Add missing index function for SQLite
- Add toCount and toExists for SQLite results
This commit is contained in:
parent
e4add06648
commit
52c00d2485
@ -29,8 +29,8 @@ module Extensions =
|
||||
WithConn.Definition.ensureTable name conn
|
||||
|
||||
/// Create an index on a document table
|
||||
member conn.ensureIndex tableName indexName fields =
|
||||
WithConn.Definition.ensureIndex tableName indexName fields conn
|
||||
member conn.ensureFieldIndex tableName indexName fields =
|
||||
WithConn.Definition.ensureFieldIndex tableName indexName fields conn
|
||||
|
||||
/// Insert a new document
|
||||
member conn.insert<'TDoc> tableName (document: 'TDoc) =
|
||||
@ -131,8 +131,8 @@ type SqliteConnectionCSharpExtensions =
|
||||
|
||||
/// Create an index on one or more fields in a document table
|
||||
[<Extension>]
|
||||
static member inline EnsureIndex(conn, tableName, indexName, fields) =
|
||||
WithConn.Definition.ensureIndex tableName indexName fields conn
|
||||
static member inline EnsureFieldIndex(conn, tableName, indexName, fields) =
|
||||
WithConn.Definition.ensureFieldIndex tableName indexName fields conn
|
||||
|
||||
/// Insert a new document
|
||||
[<Extension>]
|
||||
|
@ -103,21 +103,16 @@ module Results =
|
||||
it <- Seq.append it (Seq.singleton (mapFunc rdr))
|
||||
return List.ofSeq it
|
||||
}
|
||||
|
||||
/// Create a list of items for the results of the given command, using the specified mapping function
|
||||
let ToCustomList<'TDoc>(cmd, mapFunc: System.Func<SqliteDataReader, 'TDoc>) = backgroundTask {
|
||||
let! results = toCustomList<'TDoc> cmd mapFunc.Invoke
|
||||
return ResizeArray<'TDoc> results
|
||||
}
|
||||
|
||||
/// Create a list of items for the results of the given command
|
||||
[<CompiledName "FSharpToDocumentList">]
|
||||
let toDocumentList<'TDoc> (cmd: SqliteCommand) =
|
||||
toCustomList<'TDoc> cmd fromData
|
||||
|
||||
/// Create a list of items for the results of the given command
|
||||
let ToDocumentList<'TDoc> cmd =
|
||||
ToCustomList<'TDoc>(cmd, fromData<'TDoc>)
|
||||
|
||||
/// Extract a count from the first column
|
||||
[<CompiledName "ToCount">]
|
||||
let toCount (row: SqliteDataReader) =
|
||||
row.GetInt64 0
|
||||
|
||||
/// Extract a true/false value from a count in the first column
|
||||
[<CompiledName "ToExists">]
|
||||
let toExists row =
|
||||
toCount(row) > 0L
|
||||
|
||||
|
||||
[<AutoOpen>]
|
||||
@ -203,8 +198,8 @@ module WithConn =
|
||||
}
|
||||
|
||||
/// Create an index on a document table
|
||||
[<CompiledName "EnsureIndex">]
|
||||
let ensureIndex tableName indexName fields conn =
|
||||
[<CompiledName "EnsureFieldIndex">]
|
||||
let ensureFieldIndex tableName indexName fields conn =
|
||||
Custom.nonQuery (Query.Definition.ensureIndexOn tableName indexName fields) [] conn
|
||||
|
||||
/// Insert a new document
|
||||
@ -224,30 +219,26 @@ module WithConn =
|
||||
/// Count all documents in a table
|
||||
[<CompiledName "All">]
|
||||
let all tableName conn =
|
||||
Custom.scalar (Query.Count.all tableName) [] (_.GetInt64(0)) conn
|
||||
Custom.scalar (Query.Count.all tableName) [] toCount conn
|
||||
|
||||
/// Count matching documents using a comparison on a JSON field
|
||||
[<CompiledName "ByField">]
|
||||
let byField tableName fieldName op (value: obj) conn =
|
||||
Custom.scalar (Query.Count.byField tableName fieldName op) [ fieldParam value ] (_.GetInt64(0)) conn
|
||||
Custom.scalar (Query.Count.byField tableName fieldName op) [ fieldParam value ] toCount conn
|
||||
|
||||
/// Commands to determine if documents exist
|
||||
[<RequireQualifiedAccess>]
|
||||
module Exists =
|
||||
|
||||
/// SQLite returns a 0 for not-exists and 1 for exists
|
||||
let private exists (rdr: SqliteDataReader) =
|
||||
rdr.GetInt64(0) > 0
|
||||
|
||||
/// Determine if a document exists for the given ID
|
||||
[<CompiledName "ById">]
|
||||
let byId tableName (docId: 'TKey) conn =
|
||||
Custom.scalar (Query.Exists.byId tableName) [ idParam docId ] exists conn
|
||||
Custom.scalar (Query.Exists.byId tableName) [ idParam docId ] toExists conn
|
||||
|
||||
/// Determine if a document exists using a comparison on a JSON field
|
||||
[<CompiledName "ByField">]
|
||||
let byField tableName fieldName op (value: obj) conn =
|
||||
Custom.scalar (Query.Exists.byField tableName fieldName op) [ fieldParam value ] exists conn
|
||||
Custom.scalar (Query.Exists.byField tableName fieldName op) [ fieldParam value ] toExists conn
|
||||
|
||||
/// Commands to retrieve documents
|
||||
[<RequireQualifiedAccess>]
|
||||
@ -391,6 +382,12 @@ module Definition =
|
||||
let ensureTable name =
|
||||
use conn = Configuration.dbConn ()
|
||||
WithConn.Definition.ensureTable name conn
|
||||
|
||||
/// Create an index on a document table
|
||||
[<CompiledName "EnsureFieldIndex">]
|
||||
let ensureFieldIndex tableName indexName fields =
|
||||
use conn = Configuration.dbConn ()
|
||||
WithConn.Definition.ensureFieldIndex tableName indexName fields conn
|
||||
|
||||
/// Document insert/save functions
|
||||
[<AutoOpen>]
|
||||
|
@ -108,12 +108,9 @@ public static class SqliteCSharpExtensionTests
|
||||
await using var conn = Sqlite.Configuration.DbConn();
|
||||
|
||||
Func<string, ValueTask<bool>> itExists = async name =>
|
||||
{
|
||||
var result = await conn.CustomScalar(
|
||||
await conn.CustomScalar(
|
||||
$"SELECT EXISTS (SELECT 1 FROM {SqliteDb.Catalog} WHERE name = @name) AS it",
|
||||
new SqliteParameter[] { new("@name", name) }, rdr => rdr.GetInt64(0));
|
||||
return result > 0L;
|
||||
};
|
||||
new SqliteParameter[] { new("@name", name) }, Results.ToExists);
|
||||
|
||||
var exists = await itExists("ensured");
|
||||
var alsoExists = await itExists("idx_ensured_key");
|
||||
@ -127,6 +124,22 @@ public static class SqliteCSharpExtensionTests
|
||||
Expect.isTrue(exists, "The table should now exist");
|
||||
Expect.isTrue(alsoExists, "The key index should now exist");
|
||||
}),
|
||||
TestCase("EnsureFieldIndex succeeds", async () =>
|
||||
{
|
||||
await using var db = await SqliteDb.BuildDb();
|
||||
await using var conn = Sqlite.Configuration.DbConn();
|
||||
var indexExists = () => conn.CustomScalar(
|
||||
$"SELECT EXISTS (SELECT 1 FROM {SqliteDb.Catalog} WHERE name = 'idx_ensured_test') AS it",
|
||||
Parameters.None, Results.ToExists);
|
||||
|
||||
var exists = await indexExists();
|
||||
Expect.isFalse(exists, "The index should not exist already");
|
||||
|
||||
await conn.EnsureTable("ensured");
|
||||
await conn.EnsureFieldIndex("ensured", "test", new[] { "Id", "Category" });
|
||||
exists = await indexExists();
|
||||
Expect.isTrue(exists, "The index should now exist");
|
||||
}),
|
||||
TestList("Insert", new[]
|
||||
{
|
||||
TestCase("succeeds", async () =>
|
||||
|
@ -200,11 +200,25 @@ public static class SqliteCSharpTests
|
||||
|
||||
async ValueTask<bool> ItExists(string name)
|
||||
{
|
||||
var result = await Custom.Scalar(
|
||||
return await Custom.Scalar(
|
||||
$"SELECT EXISTS (SELECT 1 FROM {SqliteDb.Catalog} WHERE name = @name) AS it",
|
||||
new SqliteParameter[] { new("@name", name) }, rdr => rdr.GetInt64(0));
|
||||
return result > 0L;
|
||||
new SqliteParameter[] { new("@name", name) }, Results.ToExists);
|
||||
}
|
||||
}),
|
||||
TestCase("EnsureFieldIndex succeeds", async () =>
|
||||
{
|
||||
await using var db = await SqliteDb.BuildDb();
|
||||
var indexExists = () => Custom.Scalar(
|
||||
$"SELECT EXISTS (SELECT 1 FROM {SqliteDb.Catalog} WHERE name = 'idx_ensured_test') AS it",
|
||||
Parameters.None, Results.ToExists);
|
||||
|
||||
var exists = await indexExists();
|
||||
Expect.isFalse(exists, "The index should not exist already");
|
||||
|
||||
await Definition.EnsureTable("ensured");
|
||||
await Definition.EnsureFieldIndex("ensured", "test", new[] { "Id", "Category" });
|
||||
exists = await indexExists();
|
||||
Expect.isTrue(exists, "The index should now exist");
|
||||
})
|
||||
}),
|
||||
TestList("Document.Insert", new[]
|
||||
|
@ -16,14 +16,11 @@ let integrationTests =
|
||||
testTask "ensureTable succeeds" {
|
||||
use! db = SqliteDb.BuildDb()
|
||||
use conn = Configuration.dbConn ()
|
||||
let itExists (name: string) = task {
|
||||
let! result =
|
||||
conn.customScalar
|
||||
$"SELECT EXISTS (SELECT 1 FROM {SqliteDb.Catalog} WHERE name = @name) AS it"
|
||||
[ SqliteParameter("@name", name) ]
|
||||
_.GetInt64(0)
|
||||
return result > 0
|
||||
}
|
||||
let itExists (name: string) =
|
||||
conn.customScalar
|
||||
$"SELECT EXISTS (SELECT 1 FROM {SqliteDb.Catalog} WHERE name = @name) AS it"
|
||||
[ SqliteParameter("@name", name) ]
|
||||
toExists
|
||||
|
||||
let! exists = itExists "ensured"
|
||||
let! alsoExists = itExists "idx_ensured_key"
|
||||
@ -36,6 +33,23 @@ let integrationTests =
|
||||
Expect.isTrue exists' "The table should now exist"
|
||||
Expect.isTrue alsoExists' "The key index should now exist"
|
||||
}
|
||||
testTask "ensureFieldIndex succeeds" {
|
||||
use! db = SqliteDb.BuildDb()
|
||||
use conn = Configuration.dbConn ()
|
||||
let indexExists () =
|
||||
conn.customScalar
|
||||
$"SELECT EXISTS (SELECT 1 FROM {SqliteDb.Catalog} WHERE name = 'idx_ensured_test') AS it"
|
||||
[]
|
||||
toExists
|
||||
|
||||
let! exists = indexExists ()
|
||||
Expect.isFalse exists "The index should not exist already"
|
||||
|
||||
do! conn.ensureTable "ensured"
|
||||
do! conn.ensureFieldIndex "ensured" "test" [ "Name"; "Age" ]
|
||||
let! exists' = indexExists ()
|
||||
Expect.isTrue exists' "The index should now exist"
|
||||
}
|
||||
testList "insert" [
|
||||
testTask "succeeds" {
|
||||
use! db = SqliteDb.BuildDb()
|
||||
|
@ -184,14 +184,11 @@ let integrationTests =
|
||||
testList "Definition" [
|
||||
testTask "ensureTable succeeds" {
|
||||
use! db = SqliteDb.BuildDb()
|
||||
let itExists (name: string) = task {
|
||||
let! result =
|
||||
Custom.scalar
|
||||
$"SELECT EXISTS (SELECT 1 FROM {SqliteDb.Catalog} WHERE name = @name) AS it"
|
||||
[ SqliteParameter("@name", name) ]
|
||||
_.GetInt64(0)
|
||||
return result > 0
|
||||
}
|
||||
let itExists (name: string) =
|
||||
Custom.scalar
|
||||
$"SELECT EXISTS (SELECT 1 FROM {SqliteDb.Catalog} WHERE name = @name) AS it"
|
||||
[ SqliteParameter("@name", name) ]
|
||||
toExists
|
||||
|
||||
let! exists = itExists "ensured"
|
||||
let! alsoExists = itExists "idx_ensured_key"
|
||||
@ -204,6 +201,22 @@ let integrationTests =
|
||||
Expect.isTrue exists' "The table should now exist"
|
||||
Expect.isTrue alsoExists' "The key index should now exist"
|
||||
}
|
||||
testTask "ensureFieldIndex succeeds" {
|
||||
use! db = SqliteDb.BuildDb()
|
||||
let indexExists () =
|
||||
Custom.scalar
|
||||
$"SELECT EXISTS (SELECT 1 FROM {SqliteDb.Catalog} WHERE name = 'idx_ensured_test') AS it"
|
||||
[]
|
||||
toExists
|
||||
|
||||
let! exists = indexExists ()
|
||||
Expect.isFalse exists "The index should not exist already"
|
||||
|
||||
do! Definition.ensureTable "ensured"
|
||||
do! Definition.ensureFieldIndex "ensured" "test" [ "Name"; "Age" ]
|
||||
let! exists' = indexExists ()
|
||||
Expect.isTrue exists' "The index should now exist"
|
||||
}
|
||||
]
|
||||
testList "insert" [
|
||||
testTask "succeeds" {
|
||||
|
Loading…
Reference in New Issue
Block a user