diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index e73f3da..4796c0a 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -6,7 +6,7 @@
4.0.0.0
4.0.0.0
4.0.0
- Change ByField to ByFields; support dot-access to document fields; add Find*Ordered functions/methods
+ Change ByField to ByFields; support dot-access to nested document fields; add Find*Ordered functions/methods; see project site for breaking changes and compatibility
danieljsummers
Bit Badger Solutions
README.md
diff --git a/src/Postgres/BitBadger.Documents.Postgres.fsproj b/src/Postgres/BitBadger.Documents.Postgres.fsproj
index 1504c4a..6773b53 100644
--- a/src/Postgres/BitBadger.Documents.Postgres.fsproj
+++ b/src/Postgres/BitBadger.Documents.Postgres.fsproj
@@ -8,6 +8,7 @@
+
diff --git a/src/Postgres/Compat.fs b/src/Postgres/Compat.fs
new file mode 100644
index 0000000..dae2bfa
--- /dev/null
+++ b/src/Postgres/Compat.fs
@@ -0,0 +1,270 @@
+namespace BitBadger.Documents.Postgres.Compat
+
+open BitBadger.Documents
+open BitBadger.Documents.Postgres
+
+[]
+module Parameters =
+
+ /// Create a JSON field parameter
+ []
+ []
+ let addFieldParam name field parameters =
+ addFieldParams [ { field with ParameterName = Some name } ] parameters
+
+ /// Append JSON field name parameters for the given field names to the given parameters
+ []
+ []
+ let fieldNameParam fieldNames =
+ fieldNameParams fieldNames
+
+
+[]
+module Query =
+
+ /// Create a WHERE clause fragment to implement a comparison on a field in a JSON document
+ []
+ []
+ let whereByField field paramName =
+ Query.whereByFields Any [ { field with ParameterName = Some paramName } ]
+
+
+module WithProps =
+
+ []
+ module Count =
+
+ /// Count matching documents using a JSON field comparison (->> =)
+ []
+ []
+ let byField tableName field sqlProps =
+ WithProps.Count.byFields tableName Any [ field ] sqlProps
+
+ []
+ module Exists =
+
+ /// Determine if a document exists using a JSON field comparison (->> =)
+ []
+ []
+ let byField tableName field sqlProps =
+ WithProps.Exists.byFields tableName Any [ field ] sqlProps
+
+ []
+ module Find =
+
+ /// Retrieve documents matching a JSON field comparison (->> =)
+ []
+ []
+ let byField<'TDoc> tableName field sqlProps =
+ WithProps.Find.byFields<'TDoc> tableName Any [ field ] sqlProps
+
+ /// Retrieve documents matching a JSON field comparison (->> =)
+ []
+ let ByField<'TDoc>(tableName, field, sqlProps) =
+ WithProps.Find.ByFields<'TDoc>(tableName, Any, Seq.singleton field, sqlProps)
+
+ /// Retrieve the first document matching a JSON field comparison (->> =); returns None if not found
+ []
+ []
+ let firstByField<'TDoc> tableName field sqlProps =
+ WithProps.Find.firstByFields<'TDoc> tableName Any [ field ] sqlProps
+
+ /// Retrieve the first document matching a JSON field comparison (->> =); returns null if not found
+ []
+ let FirstByField<'TDoc when 'TDoc: null>(tableName, field, sqlProps) =
+ WithProps.Find.FirstByFields<'TDoc>(tableName, Any, Seq.singleton field, sqlProps)
+
+ []
+ module Patch =
+
+ /// Patch documents using a JSON field comparison query in the WHERE clause (->> =)
+ []
+ []
+ let byField tableName field (patch: 'TPatch) sqlProps =
+ WithProps.Patch.byFields tableName Any [ field ] patch sqlProps
+
+ []
+ module RemoveFields =
+
+ /// Remove fields from documents via a comparison on a JSON field in the document
+ []
+ []
+ let byField tableName field fieldNames sqlProps =
+ WithProps.RemoveFields.byFields tableName Any [ field ] fieldNames sqlProps
+
+ []
+ module Delete =
+
+ /// Delete documents by matching a JSON field comparison query (->> =)
+ []
+ []
+ let byField tableName field sqlProps =
+ WithProps.Delete.byFields tableName Any [ field ] sqlProps
+
+
+[]
+module Count =
+
+ /// Count matching documents using a JSON field comparison (->> =)
+ []
+ []
+ let byField tableName field =
+ Count.byFields tableName Any [ field ]
+
+
+[]
+module Exists =
+
+ /// Determine if a document exists using a JSON field comparison (->> =)
+ []
+ []
+ let byField tableName field =
+ Exists.byFields tableName Any [ field ]
+
+
+[]
+module Find =
+
+ /// Retrieve documents matching a JSON field comparison (->> =)
+ []
+ []
+ let byField<'TDoc> tableName field =
+ Find.byFields<'TDoc> tableName Any [ field ]
+
+ /// Retrieve documents matching a JSON field comparison (->> =)
+ []
+ let ByField<'TDoc>(tableName, field) =
+ Find.ByFields<'TDoc>(tableName, Any, Seq.singleton field)
+
+ /// Retrieve the first document matching a JSON field comparison (->> =); returns None if not found
+ []
+ []
+ let firstByField<'TDoc> tableName field =
+ Find.firstByFields<'TDoc> tableName Any [ field ]
+
+ /// Retrieve the first document matching a JSON field comparison (->> =); returns null if not found
+ []
+ let FirstByField<'TDoc when 'TDoc: null>(tableName, field) =
+ Find.FirstByFields<'TDoc>(tableName, Any, Seq.singleton field)
+
+
+[]
+module Patch =
+
+ /// Patch documents using a JSON field comparison query in the WHERE clause (->> =)
+ []
+ []
+ let byField tableName field (patch: 'TPatch) =
+ Patch.byFields tableName Any [ field ] patch
+
+
+[]
+module RemoveFields =
+
+ /// Remove fields from documents via a comparison on a JSON field in the document
+ []
+ []
+ let byField tableName field fieldNames =
+ RemoveFields.byFields tableName Any [ field ] fieldNames
+
+
+[]
+module Delete =
+
+ /// Delete documents by matching a JSON field comparison query (->> =)
+ []
+ []
+ let byField tableName field =
+ Delete.byFields tableName Any [ field ]
+
+
+open Npgsql
+
+/// F# Extensions for the NpgsqlConnection type
+[]
+module Extensions =
+
+ type NpgsqlConnection with
+
+ /// Count matching documents using a JSON field comparison query (->> =)
+ []
+ member conn.countByField tableName field =
+ conn.countByFields tableName Any [ field ]
+
+ /// Determine if documents exist using a JSON field comparison query (->> =)
+ []
+ member conn.existsByField tableName field =
+ conn.existsByFields tableName Any [ field ]
+
+ /// Retrieve documents matching a JSON field comparison query (->> =)
+ []
+ member conn.findByField<'TDoc> tableName field =
+ conn.findByFields<'TDoc> tableName Any [ field ]
+
+ /// Retrieve the first document matching a JSON field comparison query (->> =); returns None if not found
+ []
+ member conn.findFirstByField<'TDoc> tableName field =
+ conn.findFirstByFields<'TDoc> tableName Any [ field ]
+
+ /// Patch documents using a JSON field comparison query in the WHERE clause (->> =)
+ []
+ member conn.patchByField tableName field (patch: 'TPatch) =
+ conn.patchByFields tableName Any [ field ] patch
+
+ /// Remove fields from documents via a comparison on a JSON field in the document
+ []
+ member conn.removeFieldsByField tableName field fieldNames =
+ conn.removeFieldsByFields tableName Any [ field ] fieldNames
+
+ /// Delete documents by matching a JSON field comparison query (->> =)
+ []
+ member conn.deleteByField tableName field =
+ conn.deleteByFields tableName Any [ field ]
+
+
+open System.Runtime.CompilerServices
+open Npgsql.FSharp
+
+type NpgsqlConnectionCSharpCompatExtensions =
+
+ /// Count matching documents using a JSON field comparison query (->> =)
+ []
+ []
+ static member inline CountByField(conn, tableName, field) =
+ WithProps.Count.byFields tableName Any [ field ] (Sql.existingConnection conn)
+
+ /// Determine if documents exist using a JSON field comparison query (->> =)
+ []
+ []
+ static member inline ExistsByField(conn, tableName, field) =
+ WithProps.Exists.byFields tableName Any [ field ] (Sql.existingConnection conn)
+
+ /// Retrieve documents matching a JSON field comparison query (->> =)
+ []
+ []
+ static member inline FindByField<'TDoc>(conn, tableName, field) =
+ WithProps.Find.ByFields<'TDoc>(tableName, Any, [ field ], Sql.existingConnection conn)
+
+ /// Retrieve the first document matching a JSON field comparison query (->> =); returns null if not found
+ []
+ []
+ static member inline FindFirstByField<'TDoc when 'TDoc: null>(conn, tableName, field) =
+ WithProps.Find.FirstByFields<'TDoc>(tableName, Any, [ field ], Sql.existingConnection conn)
+
+ /// Patch documents using a JSON field comparison query in the WHERE clause (->> =)
+ []
+ []
+ static member inline PatchByField(conn, tableName, field, patch: 'TPatch) =
+ WithProps.Patch.byFields tableName Any [ field ] patch (Sql.existingConnection conn)
+
+ /// Remove fields from documents via a comparison on a JSON field in the document
+ []
+ []
+ static member inline RemoveFieldsByField(conn, tableName, field, fieldNames) =
+ WithProps.RemoveFields.byFields tableName Any [ field ] fieldNames (Sql.existingConnection conn)
+
+ /// Delete documents by matching a JSON field comparison query (->> =)
+ []
+ []
+ static member inline DeleteByField(conn, tableName, field) =
+ WithProps.Delete.byFields tableName Any [ field ] (Sql.existingConnection conn)
diff --git a/src/Postgres/Library.fs b/src/Postgres/Library.fs
index b5abc7d..54c4d77 100644
--- a/src/Postgres/Library.fs
+++ b/src/Postgres/Library.fs
@@ -104,24 +104,12 @@ module Parameters =
|> Seq.toList
|> Seq.ofList
- /// Create a JSON field parameter
- []
- []
- let addFieldParam name field parameters =
- addFieldParams [ { field with ParameterName = Some name } ] parameters
-
/// Append JSON field name parameters for the given field names to the given parameters
[]
let fieldNameParams (fieldNames: string seq) =
if Seq.length fieldNames = 1 then "@name", Sql.string (Seq.head fieldNames)
else "@name", Sql.stringArray (Array.ofSeq fieldNames)
- /// Append JSON field name parameters for the given field names to the given parameters
- []
- []
- let fieldNameParam fieldNames =
- fieldNameParams fieldNames
-
/// An empty parameter sequence
[]
let noParams =
diff --git a/src/Sqlite/BitBadger.Documents.Sqlite.fsproj b/src/Sqlite/BitBadger.Documents.Sqlite.fsproj
index 7d46603..f51a328 100644
--- a/src/Sqlite/BitBadger.Documents.Sqlite.fsproj
+++ b/src/Sqlite/BitBadger.Documents.Sqlite.fsproj
@@ -8,6 +8,7 @@
+
diff --git a/src/Sqlite/Compat.fs b/src/Sqlite/Compat.fs
new file mode 100644
index 0000000..7288470
--- /dev/null
+++ b/src/Sqlite/Compat.fs
@@ -0,0 +1,269 @@
+namespace BitBadger.Documents.Sqlite.Compat
+
+open BitBadger.Documents
+open BitBadger.Documents.Sqlite
+
+[]
+module Parameters =
+
+ /// Create a JSON field parameter
+ []
+ []
+ let addFieldParam name field parameters =
+ addFieldParams [ { field with ParameterName = Some name } ] parameters
+
+ /// Append JSON field name parameters for the given field names to the given parameters
+ []
+ []
+ let fieldNameParam fieldNames =
+ fieldNameParams fieldNames
+
+
+[]
+module Query =
+
+ /// Create a WHERE clause fragment to implement a comparison on a field in a JSON document
+ []
+ []
+ let whereByField field paramName =
+ Query.whereByFields Any [ { field with ParameterName = Some paramName } ]
+
+
+module WithConn =
+
+ []
+ module Count =
+
+ /// Count matching documents using a JSON field comparison (->> =)
+ []
+ []
+ let byField tableName field conn =
+ WithConn.Count.byFields tableName Any [ field ] conn
+
+ []
+ module Exists =
+
+ /// Determine if a document exists using a JSON field comparison (->> =)
+ []
+ []
+ let byField tableName field conn =
+ WithConn.Exists.byFields tableName Any [ field ] conn
+
+ []
+ module Find =
+
+ /// Retrieve documents matching a JSON field comparison (->> =)
+ []
+ []
+ let byField<'TDoc> tableName field conn =
+ WithConn.Find.byFields<'TDoc> tableName Any [ field ] conn
+
+ /// Retrieve documents matching a JSON field comparison (->> =)
+ []
+ let ByField<'TDoc>(tableName, field, conn) =
+ WithConn.Find.ByFields<'TDoc>(tableName, Any, Seq.singleton field, conn)
+
+ /// Retrieve the first document matching a JSON field comparison (->> =); returns None if not found
+ []
+ []
+ let firstByField<'TDoc> tableName field conn =
+ WithConn.Find.firstByFields<'TDoc> tableName Any [ field ] conn
+
+ /// Retrieve the first document matching a JSON field comparison (->> =); returns null if not found
+ []
+ let FirstByField<'TDoc when 'TDoc: null>(tableName, field, conn) =
+ WithConn.Find.FirstByFields<'TDoc>(tableName, Any, Seq.singleton field, conn)
+
+ []
+ module Patch =
+
+ /// Patch documents using a JSON field comparison query in the WHERE clause (->> =)
+ []
+ []
+ let byField tableName field (patch: 'TPatch) conn =
+ WithConn.Patch.byFields tableName Any [ field ] patch conn
+
+ []
+ module RemoveFields =
+
+ /// Remove fields from documents via a comparison on a JSON field in the document
+ []
+ []
+ let byField tableName field fieldNames conn =
+ WithConn.RemoveFields.byFields tableName Any [ field ] fieldNames conn
+
+ []
+ module Delete =
+
+ /// Delete documents by matching a JSON field comparison query (->> =)
+ []
+ []
+ let byField tableName field conn =
+ WithConn.Delete.byFields tableName Any [ field ] conn
+
+
+[]
+module Count =
+
+ /// Count matching documents using a JSON field comparison (->> =)
+ []
+ []
+ let byField tableName field =
+ Count.byFields tableName Any [ field ]
+
+
+[]
+module Exists =
+
+ /// Determine if a document exists using a JSON field comparison (->> =)
+ []
+ []
+ let byField tableName field =
+ Exists.byFields tableName Any [ field ]
+
+
+[]
+module Find =
+
+ /// Retrieve documents matching a JSON field comparison (->> =)
+ []
+ []
+ let byField<'TDoc> tableName field =
+ Find.byFields<'TDoc> tableName Any [ field ]
+
+ /// Retrieve documents matching a JSON field comparison (->> =)
+ []
+ let ByField<'TDoc>(tableName, field) =
+ Find.ByFields<'TDoc>(tableName, Any, Seq.singleton field)
+
+ /// Retrieve the first document matching a JSON field comparison (->> =); returns None if not found
+ []
+ []
+ let firstByField<'TDoc> tableName field =
+ Find.firstByFields<'TDoc> tableName Any [ field ]
+
+ /// Retrieve the first document matching a JSON field comparison (->> =); returns null if not found
+ []
+ let FirstByField<'TDoc when 'TDoc: null>(tableName, field) =
+ Find.FirstByFields<'TDoc>(tableName, Any, Seq.singleton field)
+
+
+[]
+module Patch =
+
+ /// Patch documents using a JSON field comparison query in the WHERE clause (->> =)
+ []
+ []
+ let byField tableName field (patch: 'TPatch) =
+ Patch.byFields tableName Any [ field ] patch
+
+
+[]
+module RemoveFields =
+
+ /// Remove fields from documents via a comparison on a JSON field in the document
+ []
+ []
+ let byField tableName field fieldNames =
+ RemoveFields.byFields tableName Any [ field ] fieldNames
+
+
+[]
+module Delete =
+
+ /// Delete documents by matching a JSON field comparison query (->> =)
+ []
+ []
+ let byField tableName field =
+ Delete.byFields tableName Any [ field ]
+
+
+open Microsoft.Data.Sqlite
+
+/// F# Extensions for the NpgsqlConnection type
+[]
+module Extensions =
+
+ type SqliteConnection with
+
+ /// Count matching documents using a JSON field comparison query (->> =)
+ []
+ member conn.countByField tableName field =
+ conn.countByFields tableName Any [ field ]
+
+ /// Determine if documents exist using a JSON field comparison query (->> =)
+ []
+ member conn.existsByField tableName field =
+ conn.existsByFields tableName Any [ field ]
+
+ /// Retrieve documents matching a JSON field comparison query (->> =)
+ []
+ member conn.findByField<'TDoc> tableName field =
+ conn.findByFields<'TDoc> tableName Any [ field ]
+
+ /// Retrieve the first document matching a JSON field comparison query (->> =); returns None if not found
+ []
+ member conn.findFirstByField<'TDoc> tableName field =
+ conn.findFirstByFields<'TDoc> tableName Any [ field ]
+
+ /// Patch documents using a JSON field comparison query in the WHERE clause (->> =)
+ []
+ member conn.patchByField tableName field (patch: 'TPatch) =
+ conn.patchByFields tableName Any [ field ] patch
+
+ /// Remove fields from documents via a comparison on a JSON field in the document
+ []
+ member conn.removeFieldsByField tableName field fieldNames =
+ conn.removeFieldsByFields tableName Any [ field ] fieldNames
+
+ /// Delete documents by matching a JSON field comparison query (->> =)
+ []
+ member conn.deleteByField tableName field =
+ conn.deleteByFields tableName Any [ field ]
+
+
+open System.Runtime.CompilerServices
+
+type SqliteConnectionCSharpCompatExtensions =
+
+ /// Count matching documents using a JSON field comparison query (->> =)
+ []
+ []
+ static member inline CountByField(conn, tableName, field) =
+ WithConn.Count.byFields tableName Any [ field ] conn
+
+ /// Determine if documents exist using a JSON field comparison query (->> =)
+ []
+ []
+ static member inline ExistsByField(conn, tableName, field) =
+ WithConn.Exists.byFields tableName Any [ field ] conn
+
+ /// Retrieve documents matching a JSON field comparison query (->> =)
+ []
+ []
+ static member inline FindByField<'TDoc>(conn, tableName, field) =
+ WithConn.Find.ByFields<'TDoc>(tableName, Any, [ field ], conn)
+
+ /// Retrieve the first document matching a JSON field comparison query (->> =); returns null if not found
+ []
+ []
+ static member inline FindFirstByField<'TDoc when 'TDoc: null>(conn, tableName, field) =
+ WithConn.Find.FirstByFields<'TDoc>(tableName, Any, [ field ], conn)
+
+ /// Patch documents using a JSON field comparison query in the WHERE clause (->> =)
+ []
+ []
+ static member inline PatchByField(conn, tableName, field, patch: 'TPatch) =
+ WithConn.Patch.byFields tableName Any [ field ] patch conn
+
+ /// Remove fields from documents via a comparison on a JSON field in the document
+ []
+ []
+ static member inline RemoveFieldsByField(conn, tableName, field, fieldNames) =
+ WithConn.RemoveFields.byFields tableName Any [ field ] fieldNames conn
+
+ /// Delete documents by matching a JSON field comparison query (->> =)
+ []
+ []
+ static member inline DeleteByField(conn, tableName, field) =
+ WithConn.Delete.byFields tableName Any [ field ] conn
diff --git a/src/Tests.CSharp/PostgresCSharpTests.cs b/src/Tests.CSharp/PostgresCSharpTests.cs
index 93c3b4d..38324af 100644
--- a/src/Tests.CSharp/PostgresCSharpTests.cs
+++ b/src/Tests.CSharp/PostgresCSharpTests.cs
@@ -170,30 +170,7 @@ public static class PostgresCSharpTests
Expect.isTrue(false, "The parameter was not a StringArray type");
}
})
- ]),
-#pragma warning disable CS0618
- TestList("FieldName",
- [
- TestCase("succeeds for one name", () =>
- {
- var (name, value) = Parameters.FieldName(["bob"]);
- Expect.equal(name, "@name", "The parameter name was incorrect");
- if (!value.IsString)
- {
- Expect.isTrue(false, "The parameter was not a String type");
- }
- }),
- TestCase("succeeds for multiple names", () =>
- {
- var (name, value) = Parameters.FieldName(["bob", "tom", "mike"]);
- Expect.equal(name, "@name", "The parameter name was incorrect");
- if (!value.IsStringArray)
- {
- Expect.isTrue(false, "The parameter was not a StringArray type");
- }
- })
])
-#pragma warning restore CS0618
]);
///
diff --git a/src/Tests/PostgresTests.fs b/src/Tests/PostgresTests.fs
index 676c8ef..ee31a27 100644
--- a/src/Tests/PostgresTests.fs
+++ b/src/Tests/PostgresTests.fs
@@ -5,8 +5,6 @@ open BitBadger.Documents
open BitBadger.Documents.Postgres
open BitBadger.Documents.Tests
-#nowarn "0044"
-
(** UNIT TESTS **)
/// Unit tests for the Parameters module of the PostgreSQL library
@@ -129,18 +127,6 @@ let parametersTests = testList "Parameters" [
Expect.equal value (Sql.stringArray [| "bob"; "tom"; "mike" |]) "The parameter value was incorrect"
}
]
- testList "fieldNameParam" [
- test "succeeds for one name" {
- let name, value = fieldNameParam [ "bob" ]
- Expect.equal name "@name" "The parameter name was incorrect"
- Expect.equal value (Sql.string "bob") "The parameter value was incorrect"
- }
- test "succeeds for multiple names" {
- let name, value = fieldNameParam [ "bob"; "tom"; "mike" ]
- Expect.equal name "@name" "The parameter name was incorrect"
- Expect.equal value (Sql.stringArray [| "bob"; "tom"; "mike" |]) "The parameter value was incorrect"
- }
- ]
test "noParams succeeds" {
Expect.isEmpty noParams "The no-params sequence should be empty"
}