Compare commits
	
		
			No commits in common. "d382699a171d7a45e46a6f14350843ba601e2d04" and "77a6aaa583c567fa2f5c04ff10ed37c3cf5822f9" have entirely different histories.
		
	
	
		
			d382699a17
			...
			77a6aaa583
		
	
		
| @ -126,10 +126,6 @@ type FieldMatch = | ||||
|     /// All fields match (AND) | ||||
|     | All | ||||
| 
 | ||||
|     /// The SQL value implementing each matching strategy | ||||
|     override this.ToString() = | ||||
|         match this with Any -> "OR" | All -> "AND" | ||||
| 
 | ||||
| 
 | ||||
| /// Derive parameter names (each instance wraps a counter to uniquely name anonymous fields) | ||||
| type ParameterName() = | ||||
|  | ||||
| @ -46,7 +46,7 @@ module private Helpers = | ||||
|         () | ||||
|     } | ||||
|      | ||||
|     /// Create a number or string parameter, or use the given parameter derivation function if non-(numeric or string) | ||||
|     /// Create a numerically-typed parameter, or use the given parameter derivation function if non-(numeric or string) | ||||
|     let internal parameterFor<'T> (value: 'T) (catchAllFunc: 'T -> SqlValue) = | ||||
|         match box value with | ||||
|         | :? int8    as it -> Sql.int8 it | ||||
| @ -70,7 +70,7 @@ open BitBadger.Documents | ||||
| [<AutoOpen>] | ||||
| module Parameters = | ||||
|      | ||||
|     /// Create an ID parameter (name "@id") | ||||
|     /// Create an ID parameter (name "@id", key will be treated as a string) | ||||
|     [<CompiledName "Id">] | ||||
|     let idParam (key: 'TKey) = | ||||
|         "@id", parameterFor key (fun it -> Sql.string (string it)) | ||||
| @ -134,7 +134,7 @@ module Query = | ||||
|      | ||||
|     /// Create a WHERE clause fragment to implement a comparison on fields in a JSON document | ||||
|     [<CompiledName "WhereByFields">] | ||||
|     let whereByFields (howMatched: FieldMatch) fields = | ||||
|     let whereByFields howMatched fields = | ||||
|         let name = ParameterName() | ||||
|         let isNumeric (it: obj) = | ||||
|             match it with | ||||
| @ -154,7 +154,7 @@ module Query = | ||||
|                 if isNumeric value then | ||||
|                     $"({it.Path PostgreSQL})::numeric {it.Op} {param}" | ||||
|                 else $"{it.Path PostgreSQL} {it.Op} {param}") | ||||
|         |> String.concat $" {howMatched} " | ||||
|         |> String.concat (match howMatched with Any -> " OR " | All -> " AND ") | ||||
| 
 | ||||
|     /// Create a WHERE clause fragment to implement an ID-based query | ||||
|     [<CompiledName "WhereById">] | ||||
|  | ||||
| @ -33,7 +33,7 @@ module Query = | ||||
|      | ||||
|     /// Create a WHERE clause fragment to implement a comparison on fields in a JSON document | ||||
|     [<CompiledName "WhereByFields">] | ||||
|     let whereByFields (howMatched: FieldMatch) fields = | ||||
|     let whereByFields howMatched fields = | ||||
|         let name = ParameterName() | ||||
|         fields | ||||
|         |> Seq.map (fun it -> | ||||
| @ -43,7 +43,7 @@ module Query = | ||||
|                 let p = name.Derive it.ParameterName | ||||
|                 $"{it.Path SQLite} {it.Op} {p}min AND {p}max" | ||||
|             | _ -> $"{it.Path SQLite} {it.Op} {name.Derive it.ParameterName}") | ||||
|         |> String.concat $" {howMatched} " | ||||
|         |> String.concat (match howMatched with Any -> " OR " | All -> " AND ") | ||||
| 
 | ||||
|     /// Create a WHERE clause fragment to implement an ID-based query | ||||
|     [<CompiledName "WhereById">] | ||||
|  | ||||
| @ -1,7 +1,6 @@ | ||||
| using Expecto.CSharp; | ||||
| using Expecto; | ||||
| using Microsoft.FSharp.Collections; | ||||
| using Microsoft.FSharp.Core; | ||||
| 
 | ||||
| namespace BitBadger.Documents.Tests.CSharp; | ||||
| 
 | ||||
| @ -237,39 +236,6 @@ public static class CommonCSharpTests | ||||
|                 }) | ||||
|             ]) | ||||
|         ]), | ||||
|         TestList("FieldMatch.ToString", | ||||
|         [ | ||||
|             TestCase("succeeds for Any", () => | ||||
|             { | ||||
|                 Expect.equal(FieldMatch.Any.ToString(), "OR", "SQL for Any is incorrect"); | ||||
|             }), | ||||
|             TestCase("succeeds for All", () => | ||||
|             { | ||||
|                 Expect.equal(FieldMatch.All.ToString(), "AND", "SQL for All is incorrect"); | ||||
|             }) | ||||
|         ]), | ||||
|         TestList("ParameterName.Derive", | ||||
|         [ | ||||
|             TestCase("succeeds with existing name", () => | ||||
|             { | ||||
|                 ParameterName name = new(); | ||||
|                 Expect.equal(name.Derive(FSharpOption<string>.Some("@taco")), "@taco", "Name should have been @taco"); | ||||
|                 Expect.equal(name.Derive(FSharpOption<string>.None), "@field0", | ||||
|                     "Counter should not have advanced for named field"); | ||||
|             }), | ||||
|             TestCase("Derive succeeds with non-existent name", () => | ||||
|             { | ||||
|                 ParameterName name = new(); | ||||
|                 Expect.equal(name.Derive(FSharpOption<string>.None), "@field0", | ||||
|                     "Anonymous field name should have been returned"); | ||||
|                 Expect.equal(name.Derive(FSharpOption<string>.None), "@field1", | ||||
|                     "Counter should have advanced from previous call"); | ||||
|                 Expect.equal(name.Derive(FSharpOption<string>.None), "@field2", | ||||
|                     "Counter should have advanced from previous call"); | ||||
|                 Expect.equal(name.Derive(FSharpOption<string>.None), "@field3", | ||||
|                     "Counter should have advanced from previous call"); | ||||
|             }) | ||||
|         ]), | ||||
|         TestList("Query", | ||||
|         [ | ||||
|             TestCase("StatementWhere succeeds", () => | ||||
|  | ||||
| @ -156,6 +156,32 @@ public static class PostgresCSharpTests | ||||
|                     Expect.equal(value, Sql.@string("zed"), "Maximum field value not correct"); | ||||
|                 }) | ||||
|             ]), | ||||
| #pragma warning disable CS0618 | ||||
|             TestList("AddField", | ||||
|             [ | ||||
|                 TestCase("succeeds when a parameter is added", () => | ||||
|                 { | ||||
|                     var it = Parameters.AddField("@field", Field.EQ("it", "242"), []).ToList(); | ||||
|                     Expect.hasLength(it, 1, "There should have been a parameter added"); | ||||
|                     Expect.equal(it[0].Item1, "@field", "Field parameter not constructed correctly"); | ||||
|                     Expect.isTrue(it[0].Item2.IsString, "Field parameter value incorrect"); | ||||
|                 }), | ||||
|                 TestCase("succeeds when a parameter is not added", () => | ||||
|                 { | ||||
|                     var it = Parameters.AddField("@it", Field.EX("It"), []); | ||||
|                     Expect.isEmpty(it, "There should not have been any parameters added"); | ||||
|                 }), | ||||
|                 TestCase("succeeds when two parameters are added", () => | ||||
|                 { | ||||
|                     var it = Parameters.AddField("@field", Field.BT("that", "eh", "zed"), []).ToList(); | ||||
|                     Expect.hasLength(it, 2, "There should have been 2 parameters added"); | ||||
|                     Expect.equal(it[0].Item1, "@fieldmin", "Minimum field name not correct"); | ||||
|                     Expect.isTrue(it[0].Item2.IsString, "Minimum field parameter value incorrect"); | ||||
|                     Expect.equal(it[1].Item1, "@fieldmax", "Maximum field name not correct"); | ||||
|                     Expect.isTrue(it[1].Item2.IsString, "Maximum field parameter value incorrect"); | ||||
|                 }) | ||||
|             ]), | ||||
| #pragma warning restore CS0618 | ||||
|             TestList("FieldNames", | ||||
|             [ | ||||
|                 TestCase("succeeds for one name", () => | ||||
| @ -305,36 +331,6 @@ public static class PostgresCSharpTests | ||||
|             { | ||||
|                 Expect.equal(Postgres.Query.WhereJsonPathMatches("@path"), "data @? @path::jsonpath", | ||||
|                     "WHERE clause not correct"); | ||||
|             }), | ||||
|             TestCase("Patch succeeds", () => | ||||
|             { | ||||
|                 Expect.equal(Postgres.Query.Patch(PostgresDb.TableName), | ||||
|                     $"UPDATE {PostgresDb.TableName} SET data = data || @data", "Patch query not correct"); | ||||
|             }), | ||||
|             TestCase("RemoveFields succeeds", () => | ||||
|             { | ||||
|                 Expect.equal(Postgres.Query.RemoveFields(PostgresDb.TableName), | ||||
|                     $"UPDATE {PostgresDb.TableName} SET data = data - @name", "Field removal query not correct"); | ||||
|             }), | ||||
|             TestCase("ById succeeds", () => | ||||
|             { | ||||
|                 Expect.equal(Postgres.Query.ById("test", "14"), "test WHERE data->>'Id' = @id", | ||||
|                     "By-ID query not correct"); | ||||
|             }), | ||||
|             TestCase("ByFields succeeds", () => | ||||
|             { | ||||
|                 Expect.equal(Postgres.Query.ByFields("unit", FieldMatch.Any, [Field.GT("That", 14)]), | ||||
|                     "unit WHERE (data->>'That')::numeric > @field0", "By-Field query not correct"); | ||||
|             }), | ||||
|             TestCase ("ByContains succeeds", () => | ||||
|             { | ||||
|                 Expect.equal(Postgres.Query.ByContains("exam"), "exam WHERE data @> @criteria", | ||||
|                     "By-Contains query not correct"); | ||||
|             }), | ||||
|             TestCase("ByPathMach succeeds", () => | ||||
|             { | ||||
|                 Expect.equal(Postgres.Query.ByPathMatch("verify"), "verify WHERE data @? @path::jsonpath", | ||||
|                     "By-JSON Path query not correct"); | ||||
|             }) | ||||
|         ]) | ||||
|     ]); | ||||
|  | ||||
| @ -67,27 +67,6 @@ public static class SqliteCSharpTests | ||||
|             { | ||||
|                 Expect.equal(Sqlite.Query.WhereById("@id"), "data->>'Id' = @id", "WHERE clause not correct"); | ||||
|             }), | ||||
|             TestCase("Patch succeeds", () => | ||||
|             { | ||||
|                 Expect.equal(Sqlite.Query.Patch(SqliteDb.TableName), | ||||
|                     $"UPDATE {SqliteDb.TableName} SET data = json_patch(data, json(@data))", "Patch query not correct"); | ||||
|             }), | ||||
|             TestCase("RemoveFields succeeds", () => | ||||
|             { | ||||
|                 Expect.equal(Sqlite.Query.RemoveFields(SqliteDb.TableName, [new("@a", "a"), new("@b", "b")]), | ||||
|                     $"UPDATE {SqliteDb.TableName} SET data = json_remove(data, @a, @b)", | ||||
|                     "Field removal query not correct"); | ||||
|             }), | ||||
|             TestCase("ById succeeds", () => | ||||
|             { | ||||
|                 Expect.equal(Sqlite.Query.ById("test", "14"), "test WHERE data->>'Id' = @id", | ||||
|                     "By-ID query not correct"); | ||||
|             }), | ||||
|             TestCase("ByFields succeeds", () => | ||||
|             { | ||||
|                 Expect.equal(Sqlite.Query.ByFields("unit", FieldMatch.Any, [Field.GT("That", 14)]), | ||||
|                     "unit WHERE data->>'That' > @field0", "By-Field query not correct"); | ||||
|             }), | ||||
|             TestCase("Definition.EnsureTable succeeds", () => | ||||
|             { | ||||
|                 Expect.equal(Sqlite.Query.Definition.EnsureTable("tbl"), | ||||
|  | ||||
| @ -155,21 +155,13 @@ let all = | ||||
|                 } | ||||
|             ] | ||||
|         ] | ||||
|         testList "FieldMatch.ToString" [ | ||||
|             test "succeeds for Any" { | ||||
|                 Expect.equal (string Any) "OR" "SQL for Any is incorrect" | ||||
|             } | ||||
|             test "succeeds for All" { | ||||
|                 Expect.equal (string All) "AND" "SQL for All is incorrect" | ||||
|             } | ||||
|         ] | ||||
|         testList "ParameterName.Derive" [ | ||||
|             test "succeeds with existing name" { | ||||
|         testList "ParameterName" [ | ||||
|             test "Derive succeeds with existing name" { | ||||
|                 let name = ParameterName() | ||||
|                 Expect.equal (name.Derive(Some "@taco")) "@taco" "Name should have been @taco" | ||||
|                 Expect.equal (name.Derive None) "@field0" "Counter should not have advanced for named field" | ||||
|             } | ||||
|             test "succeeds with non-existent name" { | ||||
|             test "Derive succeeds with non-existent name" { | ||||
|                 let name = ParameterName() | ||||
|                 Expect.equal (name.Derive None) "@field0" "Anonymous field name should have been returned" | ||||
|                 Expect.equal (name.Derive None) "@field1" "Counter should have advanced from previous call" | ||||
|  | ||||
| @ -124,6 +124,29 @@ let unitTests = | ||||
|                     Expect.equal value (Sql.string "zed") "Maximum parameter value not correct" | ||||
|                 } | ||||
|             ] | ||||
|             testList "addFieldParam" [ | ||||
|                 test "succeeds when a parameter is added" { | ||||
|                     let paramList = addFieldParam "@field" (Field.EQ "it" "242") [] | ||||
|                     Expect.hasLength paramList 1 "There should have been a parameter added" | ||||
|                     let name, value = Seq.head paramList | ||||
|                     Expect.equal name "@field" "Field parameter name not correct" | ||||
|                     Expect.equal value (Sql.string "242") "Parameter value not correct" | ||||
|                 } | ||||
|                 test "succeeds when a parameter is not added" { | ||||
|                     let paramList = addFieldParam "@field" (Field.EX "tacos") [] | ||||
|                     Expect.isEmpty paramList "There should not have been any parameters added" | ||||
|                 } | ||||
|                 test "succeeds when two parameters are added" { | ||||
|                     let paramList = addFieldParam "@field" (Field.BT "that" "eh" "zed") [] | ||||
|                     Expect.hasLength paramList 2 "There should have been 2 parameters added" | ||||
|                     let name, value = Seq.head paramList | ||||
|                     Expect.equal name "@fieldmin" "Minimum field name not correct" | ||||
|                     Expect.equal value (Sql.string "eh") "Minimum parameter value not correct" | ||||
|                     let name, value = paramList |> Seq.skip 1 |> Seq.head | ||||
|                     Expect.equal name "@fieldmax" "Maximum field name not correct" | ||||
|                     Expect.equal value (Sql.string "zed") "Maximum parameter value not correct" | ||||
|                 } | ||||
|             ] | ||||
|             testList "fieldNameParams" [ | ||||
|                 test "succeeds for one name" { | ||||
|                     let name, value = fieldNameParams [ "bob" ] | ||||
| @ -238,34 +261,6 @@ let unitTests = | ||||
|             test "whereJsonPathMatches succeeds" { | ||||
|                 Expect.equal (Query.whereJsonPathMatches "@path") "data @? @path::jsonpath" "WHERE clause not correct" | ||||
|             } | ||||
|             test "patch succeeds" { | ||||
|                 Expect.equal | ||||
|                     (Query.patch PostgresDb.TableName) | ||||
|                     $"UPDATE {PostgresDb.TableName} SET data = data || @data" | ||||
|                     "Patch query not correct" | ||||
|             } | ||||
|             test "removeFields succeeds" { | ||||
|                 Expect.equal | ||||
|                     (Query.removeFields PostgresDb.TableName) | ||||
|                     $"UPDATE {PostgresDb.TableName} SET data = data - @name" | ||||
|                     "Field removal query not correct" | ||||
|             } | ||||
|             test "byId succeeds" { | ||||
|                 Expect.equal (Query.byId "test" "14") "test WHERE data->>'Id' = @id" "By-ID query not correct" | ||||
|             } | ||||
|             test "byFields succeeds" { | ||||
|                 Expect.equal | ||||
|                     (Query.byFields "unit" Any [ Field.GT "That" 14 ]) | ||||
|                     "unit WHERE (data->>'That')::numeric > @field0" | ||||
|                     "By-Field query not correct" | ||||
|             } | ||||
|             test "byContains succeeds" { | ||||
|                 Expect.equal (Query.byContains "exam") "exam WHERE data @> @criteria" "By-Contains query not correct" | ||||
|             } | ||||
|             test "byPathMach succeeds" { | ||||
|                 Expect.equal | ||||
|                     (Query.byPathMatch "verify") "verify WHERE data @? @path::jsonpath" "By-JSON Path query not correct" | ||||
|             } | ||||
|         ] | ||||
|     ] | ||||
| 
 | ||||
|  | ||||
| @ -55,27 +55,6 @@ let unitTests = | ||||
|             test "whereById succeeds" { | ||||
|                 Expect.equal (Query.whereById "@id") "data->>'Id' = @id" "WHERE clause not correct" | ||||
|             } | ||||
|             test "patch succeeds" { | ||||
|                 Expect.equal | ||||
|                     (Query.patch SqliteDb.TableName) | ||||
|                     $"UPDATE {SqliteDb.TableName} SET data = json_patch(data, json(@data))" | ||||
|                     "Patch query not correct" | ||||
|             } | ||||
|             test "removeFields succeeds" { | ||||
|                 Expect.equal | ||||
|                     (Query.removeFields SqliteDb.TableName [ SqliteParameter("@a", "a"); SqliteParameter("@b", "b") ]) | ||||
|                     $"UPDATE {SqliteDb.TableName} SET data = json_remove(data, @a, @b)" | ||||
|                     "Field removal query not correct" | ||||
|             } | ||||
|             test "byId succeeds" { | ||||
|                 Expect.equal (Query.byId "test" "14") "test WHERE data->>'Id' = @id" "By-ID query not correct" | ||||
|             } | ||||
|             test "byFields succeeds" { | ||||
|                 Expect.equal | ||||
|                     (Query.byFields "unit" Any [ Field.GT "That" 14 ]) | ||||
|                     "unit WHERE data->>'That' > @field0" | ||||
|                     "By-Field query not correct" | ||||
|             } | ||||
|             test "Definition.ensureTable succeeds" { | ||||
|                 Expect.equal | ||||
|                     (Query.Definition.ensureTable "tbl") | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user