Skip to content

Commit

Permalink
Merge pull request #10 from scull7/scull7/fix-big-int-id-and-rewrite
Browse files Browse the repository at this point in the history
All the Things
  • Loading branch information
scull7 committed Jul 9, 2018
2 parents 29e894b + 8854853 commit f6dd72c
Show file tree
Hide file tree
Showing 22 changed files with 747 additions and 255 deletions.
2 changes: 0 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,3 @@ before_install:
- sudo apt-get -qq update
- sudo apt-get install -y jq
- mysql -e 'CREATE DATABASE IF NOT EXISTS test;'
before_script:
- yarn install:peers
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@ and [Named Placeholders](#named-placeholders).
#### Standard Query Method
```reason
let conn
= MySql2.connect(~host=127.0.0.1, ~port=3306, ~user="root", ());
= MySql2.Connection.connect(~host=127.0.0.1, ~port=3306, ~user="root", ());
MySql2.execute(conn, "SHOW DATABASES", None, res => {
switch res {
| `Error(e) => Js.log2("ERROR: ", e)
| `Select(rows, meta) => Js.log3("SELECT: ", rows, meta)
| `Mutation(count, id) => Js.log3("MUTATION: ", count, id)
| `Select(select) => Js.log2("SELECT: ", select)
| `Mutation(mutation) => Js.log2("MUTATION: ", mutation)
}
MySql2.close(conn);
});
Expand All @@ -72,9 +72,9 @@ MySql2.execute(conn, "SHOW DATABASES", None, res => {
##### Named Placeholders
```reason
let conn
= MySql2.connect(~host=127.0.0.1, ~port=3306, ~user="root", ());
= MySql2.Connect.connect(~host=127.0.0.1, ~port=3306, ~user="root", ());
let named = `Named(
let named = MySql2.Params.named(
Json.Encode.object_([
("x", Json.Encode.int(1)),
("y", Json.Encode.int(2)),
Expand All @@ -84,8 +84,8 @@ let named = `Named(
MySql2.execute(conn, "SELECT :x + :y AS result", Some(named), res => {
switch res {
| `Error(e) => Js.log2("ERROR: ", e)
| `Select(rows, meta) => Js.log3("SELECT: ", rows, meta)
| `Mutation(count, id) => Js.log3("MUTATION: ", count, id)
| `Select(select) => Js.log2("SELECT: ", select)
| `Mutation(mutation) => Js.log2("MUTATION: ", mutation)
}
}
MySql2.close(conn);
Expand All @@ -95,17 +95,17 @@ MySql2.execute(conn, "SELECT :x + :y AS result", Some(named), res => {
##### Unnamed Placeholders
```reason
let conn
= MySql2.connect(~host=127.0.0.1, ~port=3306, ~user="root", ());
= MySql2.Connection.connect(~host=127.0.0.1, ~port=3306, ~user="root", ());
let positional = `Positional(
let positional = MySql2.Params.positional(
Belt_Array.map([|5, 6|], Json.Encode.int) |> Json.Encode.jsonArray
);
MySql2.execute(conn, "SELECT 1 + ? + ? AS result", Some(positional), res => {
switch res {
| `Error(e) => Js.log2("ERROR: ", e)
| `Select(rows, meta) => Js.log3("SELECT: ", rows, meta)
| `Mutation(count, id) => Js.log3("MUTATION: ", count, id)
| `Select(rows, meta) => Js.log2("SELECT: ", rows, meta)
| `Mutation(count, id) => Js.log2("MUTATION: ", count, id)
}
}
MySql2.close(conn);
Expand Down
226 changes: 226 additions & 0 deletions __tests__/Test_mysql2.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
open Jest;

let connect = () =>
MySql2.Connection.connect(
~host="127.0.0.1",
~port=3306,
~user="root",
~password="",
~database="test",
(),
);

let table_sql = {|
CREATE TABLE IF NOT EXISTS `test`.`mysql2` (
`id` bigint(20) NOT NULL AUTO_INCREMENT
, `code` varchar(32) NOT NULL
, `display` varchar(140) DEFAULT NULL
, PRIMARY KEY(`id`)
)
|};

let seed_sql = {|
INSERT IGNORE INTO `test`.`mysql2`
(`id`, `code`, `display`)
VALUES
(1, "batman", "I am, Bat-man"),
(2, "superman", "Truth, Justice and the American Way"),
(3, "wonder_woman", "Suffering Sappho!")
|};

let mutationPromise = (db, sql, params) =>
Js.Promise.make((~resolve, ~reject) =>
MySql2.execute(
db,
sql,
params,
fun
| `Error(e) => reject(. e)
| `Select(_) => reject(. "unexpected_select_result" |. Failure)
| `Mutation(m) => resolve(. m),
)
|. ignore
);

let selectPromise = (db, sql, params) =>
Js.Promise.make((~resolve, ~reject) =>
MySql2.execute(
db,
sql,
params,
fun
| `Error(e) => reject(. e)
| `Mutation(_) => reject(. "unexpected_mutation_result" |. Failure)
| `Select(select) => resolve(. select),
)
|. ignore
);

describe("MySql2", () => {
let db = ref(None);

let getDb = () => db^ |. Belt.Option.getExn;

beforeAllPromise(() => {
db := connect() |. Some;

mutationPromise(getDb(), "DROP TABLE IF EXISTS `test`.`mysql2`", None)
|> Js.Promise.then_(_ => mutationPromise(getDb(), table_sql, None))
|> Js.Promise.then_(_ => mutationPromise(getDb(), seed_sql, None));
});

afterAll(() => getDb() |. MySql2.Connection.close);

describe("Mutation", () => {
let result = ref(None);

let getResult = () => result^ |. Belt.Option.getExn;

beforeAllPromise(() => {
let sql = {|
INSERT INTO `test`.`mysql2`
(`id`, `code`, `display`)
VALUES
(4, "flash", "I am the fastest man alive")
|};

mutationPromise(getDb(), sql, None)
|> Js.Promise.then_(mutation => {
result := Some(mutation);
Js.Promise.resolve(mutation);
});
});

let makeTest = (label, fn, expected) =>
test(label, () =>
getResult() |. fn |. Expect.expect |> Expect.toBe(expected)
);

describe("fieldCount", () =>
makeTest("should return zero", MySql2.Mutation.fieldCount, 0)
);

describe("info", () =>
makeTest("should return empty string", MySql2.Mutation.info, "")
);

describe("serverStatus", () =>
makeTest("should return 2", MySql2.Mutation.serverStatus, 2)
);

describe("warningStatus", () =>
makeTest("should return 0", MySql2.Mutation.warningStatus, 0)
);
});

describe("Select", () => {
let result = ref(None);

let getResult = () => result^ |. Belt.Option.getExn;

beforeAllPromise(() =>
selectPromise(getDb(), "SELECT * FROM `test`.`mysql2`", None)
|> Js.Promise.then_(select => {
result := Some(select);
Js.Promise.resolve(select);
})
);

let makeMetaTest = (label, fn, expected) =>
test(label, () =>
getResult()
|. MySql2.Select.meta
|. Belt.Array.map(fn)
|. Expect.expect
|> Expect.toEqual(expected)
);

describe("catalog", () =>
makeMetaTest(
"should return the string 'def'",
MySql2.Select.Meta.catalog,
[|"def", "def", "def"|],
)
);

describe("schema", () =>
makeMetaTest(
"should return the string 'test'",
MySql2.Select.Meta.schema,
[|"test", "test", "test"|],
)
);

describe("name", () =>
makeMetaTest(
"should return the column name string",
MySql2.Select.Meta.name,
[|"id", "code", "display"|],
)
);

describe("orgName", () =>
makeMetaTest(
"should return the schema defined column name string",
MySql2.Select.Meta.orgName,
[|"id", "code", "display"|],
)
);

describe("table", () =>
makeMetaTest(
"should return the table name string",
MySql2.Select.Meta.table,
[|"mysql2", "mysql2", "mysql2"|],
)
);

describe("orgTable", () =>
makeMetaTest(
"should return the schema defined table name string",
MySql2.Select.Meta.orgTable,
[|"mysql2", "mysql2", "mysql2"|],
)
);

describe("characterSet", () =>
makeMetaTest(
"should return the column character sets",
MySql2.Select.Meta.characterSet,
[|63, 224, 224|],
)
);

describe("columnLength", () =>
makeMetaTest(
"should return the length of each column",
MySql2.Select.Meta.columnLength,
[|20, 128, 560|],
)
);

describe("columnType", () =>
makeMetaTest(
"should return the internal type code of each column",
MySql2.Select.Meta.columnType,
[|8, 253, 253|],
)
);

describe("flags", () =>
makeMetaTest(
"should return the flag set for each column",
MySql2.Select.Meta.flags,
[|16899, 4097, 0|],
)
);

describe("decimals", () =>
makeMetaTest(
"should return the decimal count of each column",
MySql2.Select.Meta.decimals,
[|0, 0, 0|],
)
);
});
});
54 changes: 30 additions & 24 deletions __tests__/Test_mysql2_error.re
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
open Jest;

let connect = () =>
MySql2.connect(~host="127.0.0.1", ~port=3306, ~user="root", ());
MySql2.Connection.connect(~host="127.0.0.1", ~port=3306, ~user="root", ());

describe("MySql2 Error Handling", () => {
let conn = connect();

afterAll(() => MySql2.close(conn));
afterAll(() => MySql2.Connection.close(conn));

let accessDeniedTest = "Should respond with an access denied error";
testAsync(
accessDeniedTest,
finish => {
let c = MySql2.connect(~password="s0m3 g@rb@g3 pw", ());
let c = MySql2.Connection.connect(~password="s0m3 g@rb@g3 pw", ());
let sql = "SELECT 1+1 AS result";
MySql2.execute(c, sql, None, res =>
switch (res) {
| `Select(_, _) => fail("unexpected_select_result") |> finish
| `Mutation(_, _) => fail("unexpected_mutation_result") |> finish
| `Select(_) => fail("unexpected_select_result") |> finish
| `Mutation(_) => fail("unexpected_mutation_result") |> finish
| `Error(e) =>
Expect.expect(() =>
raise(e)
Expand All @@ -36,8 +36,8 @@ describe("MySql2 Error Handling", () => {
let sql = "SELECT invalid, AS result";
MySql2.execute(conn, sql, None, res =>
switch (res) {
| `Select(_, _) => fail("unexpected_select_result") |> finish
| `Mutation(_, _) => fail("unexpected_mutation_result") |> finish
| `Select(_) => fail("unexpected_select_result") |> finish
| `Mutation(_) => fail("unexpected_mutation_result") |> finish
| `Error(e) =>
Expect.expect(() =>
raise(e)
Expand All @@ -51,41 +51,47 @@ describe("MySql2 Error Handling", () => {

test("Should parse out an empty error with defaults", () => {
/* Use raw JS here toe retrieve a garbage object */
let e = [%raw {| (function () { return { message: "IDKWTM" } })() |} ];
let e = [%raw {| (function () { return { message: "IDKWTM" } })() |}];
let actual = MySql2_error.fromJs(e);

Expect.expect(() => raise(actual))
Expect.expect(() =>
raise(actual)
)
|> Expect.toThrowMessage("Failure,-2,UNKNOWN - 99999 (99999) - IDKWTM");
});

test("Should return a defaulted error", () => {
/* Use raw JS here toe retrieve a garbage object */
let e = [%raw {| (function () { return {} })()|} ];
let e = [%raw {| (function () { return {} })()|}];
let actual = MySql2_error.fromJs(e);

Expect.expect(() => raise(actual))
Expect.expect(() =>
raise(actual)
)
|> Expect.toThrowMessage("UNKNOWN - 99999 (99999) - EMPTY_MESSAGE");
});

test("should give appropriate message when only a sqlState is given", () =>{
test("should give appropriate message when only a sqlState is given", () => {
/* Use raw JS here toe retrieve a garbage object */
let e = [%raw {| (function () { return { sqlState: "test" } })()|} ];
let e = [%raw {| (function () { return { sqlState: "test" } })()|}];
let actual = MySql2_error.fromJs(e);

Expect.expect(() => raise(actual))

Expect.expect(() =>
raise(actual)
)
|> Expect.toThrowMessage(
"UNKNOWN - 99999 (99999) - EMPTY_MESSAGE - (test)"
);
"UNKNOWN - 99999 (99999) - EMPTY_MESSAGE - (test)",
);
});

test("should give appropriate message when only a sqlMessage is given", () =>{
test("should give appropriate message when only a sqlMessage is given", () => {
/* Use raw JS here toe retrieve a garbage object */
let e = [%raw {| (function () { return { sqlMessage: "test" } })()|} ];
let e = [%raw {| (function () { return { sqlMessage: "test" } })()|}];
let actual = MySql2_error.fromJs(e);
Expect.expect(() => raise(actual))
|> Expect.toThrowMessage(
"UNKNOWN - 99999 (99999) - EMPTY_MESSAGE - test"
);

Expect.expect(() =>
raise(actual)
)
|> Expect.toThrowMessage("UNKNOWN - 99999 (99999) - EMPTY_MESSAGE - test");
});
});
Loading

0 comments on commit f6dd72c

Please sign in to comment.