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