From e85c8474c3572c0a06326eec5869b8a4a48b9484 Mon Sep 17 00:00:00 2001 From: Don Viszneki Date: Mon, 7 Oct 2019 18:33:24 -0700 Subject: [PATCH 1/6] allow integration test configuration via environment variables --- __tests__/TestUtil.ml | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/__tests__/TestUtil.ml b/__tests__/TestUtil.ml index 0af31a9..ea9a4c5 100644 --- a/__tests__/TestUtil.ml +++ b/__tests__/TestUtil.ml @@ -1,6 +1,28 @@ +let env = Node.Process.process##env + +let host = Js.Dict.get env "MYSQL_HOST" +let _ = Js.Console.log2 "host=" host + +let host = Belt.Option.getWithDefault host "localhost" +let _ = Js.Console.log2 "host=" host + +let port = int_of_string (Belt.Option.getWithDefault (Js.Dict.get env "MYSQL_PORT") "3306") +let _ = Js.Console.log2 "port=" port + +let user = Belt.Option.getWithDefault (Js.Dict.get env "MYSQL_USER") "root" +let _ = Js.Console.log2 "user=" user + +let password = Belt.Option.getWithDefault (Js.Dict.get env "MYSQL_PASSWORD") "password" +let _ = Js.Console.log2 "password=" password + +let database = Belt.Option.getWithDefault (Js.Dict.get env "MYSQL_DATABASE") "database" +let _ = Js.Console.log2 "database=" database + let connect _ = MySql2.connect - ~host:"127.0.0.1" - ~port:3306 - ~user:"root" + ~host + ~port + ~user + ~password + ~database () From 76947f06c83d550b027449a97ec9a076356cbe25 Mon Sep 17 00:00:00 2001 From: Don Viszneki Date: Mon, 7 Oct 2019 18:37:19 -0700 Subject: [PATCH 2/6] add test for rollback batch insert on duplicate key --- __tests__/TestSqlCommonRaw.ml | 38 ++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/__tests__/TestSqlCommonRaw.ml b/__tests__/TestSqlCommonRaw.ml index 9912541..7f1699d 100644 --- a/__tests__/TestSqlCommonRaw.ml +++ b/__tests__/TestSqlCommonRaw.ml @@ -155,4 +155,40 @@ describe "Raw SQL Query Test Sequence" (fun () -> |> finish ) ); -); + + testAsync "Rollback batch insert on duplicate key" (fun finish -> + let id_0 = string_of_int (Js.Math.random_int Js.Int.min Js.Int.max) in + let code_0 = {j|unique-value-$id_0|j} in + let sql = "INSERT INTO test.simple (id, code) VALUES (?, ?)" in + let params = `Positional (Json.Encode.array Json.Encode.string [| id_0; code_0 |]) in + Sql.mutate conn ~sql ~params (fun res -> + match res with + | `Error e -> let _ = Js.log e in finish (fail "see log") + | `Mutation (_, _) -> + let id_1 = string_of_int (Js.Math.random_int Js.Int.min Js.Int.max) in + let code_1 = {j|unique-value-$id_1|j} in + let batch_size = 1 in + let table = "test.simple" in + let columns = Belt.Array.map [|"id"; "code"|] Json.Encode.string in + let rows = Belt.Array.map [| + Json.Encode.array Json.Encode.string [| id_1; code_1 |]; + Json.Encode.array Json.Encode.string [| id_0; code_0 |] + |] (fun a -> a) in + Sql.mutate_batch conn ~batch_size ~table ~columns ~rows (fun res -> + match res with + | `Mutation (rows, id) -> let _ = Js.log3 "mutation should have failed" rows id in + finish (fail "see log") + | `Error _ -> Sql.query conn ~sql:{j|SELECT * FROM test.simple WHERE code='$(code_1)'|j} (fun res -> + match res with + | `Error e -> let _ = Js.log e in finish (fail "see log") + | `Select (rows, _) -> + rows + |> Expect.expect + |> Expect.toHaveLength 0 + |> finish + ) + ) + ); + ); +) + From 83f83de57662779e03e09dbfbde314c989132349 Mon Sep 17 00:00:00 2001 From: Don Viszneki Date: Mon, 7 Oct 2019 18:55:10 -0700 Subject: [PATCH 3/6] silence TestUtil --- __tests__/TestUtil.ml | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/__tests__/TestUtil.ml b/__tests__/TestUtil.ml index ea9a4c5..27b2240 100644 --- a/__tests__/TestUtil.ml +++ b/__tests__/TestUtil.ml @@ -1,23 +1,10 @@ let env = Node.Process.process##env - -let host = Js.Dict.get env "MYSQL_HOST" -let _ = Js.Console.log2 "host=" host - -let host = Belt.Option.getWithDefault host "localhost" -let _ = Js.Console.log2 "host=" host - +let host = Belt.Option.getWithDefault (Js.Dict.get env "MYSQL_HOST") "localhost" let port = int_of_string (Belt.Option.getWithDefault (Js.Dict.get env "MYSQL_PORT") "3306") -let _ = Js.Console.log2 "port=" port - let user = Belt.Option.getWithDefault (Js.Dict.get env "MYSQL_USER") "root" -let _ = Js.Console.log2 "user=" user - let password = Belt.Option.getWithDefault (Js.Dict.get env "MYSQL_PASSWORD") "password" -let _ = Js.Console.log2 "password=" password - let database = Belt.Option.getWithDefault (Js.Dict.get env "MYSQL_DATABASE") "database" -let _ = Js.Console.log2 "database=" database let connect _ = MySql2.connect ~host From 1898eecd90730dae7cce2a01764fb9c23a119365 Mon Sep 17 00:00:00 2001 From: Don Viszneki Date: Mon, 7 Oct 2019 18:57:16 -0700 Subject: [PATCH 4/6] bugfix test Rollback batch insert on duplicate key --- __tests__/TestSqlCommonRaw.ml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/__tests__/TestSqlCommonRaw.ml b/__tests__/TestSqlCommonRaw.ml index 7f1699d..7104c72 100644 --- a/__tests__/TestSqlCommonRaw.ml +++ b/__tests__/TestSqlCommonRaw.ml @@ -157,7 +157,7 @@ describe "Raw SQL Query Test Sequence" (fun () -> ); testAsync "Rollback batch insert on duplicate key" (fun finish -> - let id_0 = string_of_int (Js.Math.random_int Js.Int.min Js.Int.max) in + let id_0 = string_of_int (Js.Math.random_int 0 (Js.Int.max - 1)) in let code_0 = {j|unique-value-$id_0|j} in let sql = "INSERT INTO test.simple (id, code) VALUES (?, ?)" in let params = `Positional (Json.Encode.array Json.Encode.string [| id_0; code_0 |]) in @@ -165,14 +165,15 @@ describe "Raw SQL Query Test Sequence" (fun () -> match res with | `Error e -> let _ = Js.log e in finish (fail "see log") | `Mutation (_, _) -> - let id_1 = string_of_int (Js.Math.random_int Js.Int.min Js.Int.max) in + let id_1 = string_of_int (Js.Math.random_int 0 (Js.Int.max - 1)) in let code_1 = {j|unique-value-$id_1|j} in let batch_size = 1 in let table = "test.simple" in let columns = Belt.Array.map [|"id"; "code"|] Json.Encode.string in + (* order is important here *) let rows = Belt.Array.map [| Json.Encode.array Json.Encode.string [| id_1; code_1 |]; - Json.Encode.array Json.Encode.string [| id_0; code_0 |] + Json.Encode.array Json.Encode.string [| id_0; code_0 |]; |] (fun a -> a) in Sql.mutate_batch conn ~batch_size ~table ~columns ~rows (fun res -> match res with From 734c7dcb433bc3d57d61464a487e1516162dd126 Mon Sep 17 00:00:00 2001 From: Don Viszneki Date: Mon, 7 Oct 2019 18:59:42 -0700 Subject: [PATCH 5/6] always rollback transaction if any stage of batch insert fails --- src/SqlCommonBatchInsert.ml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/SqlCommonBatchInsert.ml b/src/SqlCommonBatchInsert.ml index fe27006..8ec57fd 100644 --- a/src/SqlCommonBatchInsert.ml +++ b/src/SqlCommonBatchInsert.ml @@ -67,7 +67,12 @@ let insert execute ?batch_size ~table ~columns ~rows user_cb = | None -> 1000 | Some(s) -> s in - let fail = (fun e -> user_cb (`Error e)) in + let fail = (fun err -> rollback ~execute + ~fail:(fun err -> user_cb (`Error err)) + ~ok:(fun _ _ -> user_cb (`Error err)) + () + ) + in let complete = (fun count id -> let ok = (fun _ _ -> user_cb (`Mutation (count, id))) in From 29887c0d03f36f2681a4ff9f0f8f21ecde9e9a28 Mon Sep 17 00:00:00 2001 From: Nathan A Sculli Date: Mon, 7 Oct 2019 21:46:02 -0700 Subject: [PATCH 6/6] Change default database to test so that it the TravisCI tests will work. --- __tests__/TestUtil.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__tests__/TestUtil.ml b/__tests__/TestUtil.ml index 27b2240..f10f1f8 100644 --- a/__tests__/TestUtil.ml +++ b/__tests__/TestUtil.ml @@ -4,7 +4,7 @@ let host = Belt.Option.getWithDefault (Js.Dict.get env "MYSQL_HOST") "localhost" let port = int_of_string (Belt.Option.getWithDefault (Js.Dict.get env "MYSQL_PORT") "3306") let user = Belt.Option.getWithDefault (Js.Dict.get env "MYSQL_USER") "root" let password = Belt.Option.getWithDefault (Js.Dict.get env "MYSQL_PASSWORD") "password" -let database = Belt.Option.getWithDefault (Js.Dict.get env "MYSQL_DATABASE") "database" +let database = Belt.Option.getWithDefault (Js.Dict.get env "MYSQL_DATABASE") "test" let connect _ = MySql2.connect ~host