v3 RC1 #1
|
@ -18,11 +18,13 @@ module Configuration =
|
||||||
let mutable private dataSourceValue : NpgsqlDataSource option = None
|
let mutable private dataSourceValue : NpgsqlDataSource option = None
|
||||||
|
|
||||||
/// Register a data source to use for query execution (disposes the current one if it exists)
|
/// Register a data source to use for query execution (disposes the current one if it exists)
|
||||||
|
[<CompiledName "UseDataSource">]
|
||||||
let useDataSource source =
|
let useDataSource source =
|
||||||
if Option.isSome dataSourceValue then dataSourceValue.Value.Dispose()
|
if Option.isSome dataSourceValue then dataSourceValue.Value.Dispose()
|
||||||
dataSourceValue <- Some source
|
dataSourceValue <- Some source
|
||||||
|
|
||||||
/// Retrieve the currently configured data source
|
/// Retrieve the currently configured data source
|
||||||
|
[<CompiledName "DataSource">]
|
||||||
let dataSource () =
|
let dataSource () =
|
||||||
match dataSourceValue with
|
match dataSourceValue with
|
||||||
| Some source -> source
|
| Some source -> source
|
||||||
|
@ -85,8 +87,8 @@ module Query =
|
||||||
Query.Definition.ensureTableFor name "JSONB"
|
Query.Definition.ensureTableFor name "JSONB"
|
||||||
|
|
||||||
/// SQL statement to create an index on JSON documents in the specified table
|
/// SQL statement to create an index on JSON documents in the specified table
|
||||||
[<CompiledName "EnsureJsonIndex">]
|
[<CompiledName "EnsureDocumentIndex">]
|
||||||
let ensureJsonIndex (name: string) idxType =
|
let ensureDocumentIndex (name: string) idxType =
|
||||||
let extraOps = match idxType with Full -> "" | Optimized -> " jsonb_path_ops"
|
let extraOps = match idxType with Full -> "" | Optimized -> " jsonb_path_ops"
|
||||||
let tableName = name.Split '.' |> Array.last
|
let tableName = name.Split '.' |> Array.last
|
||||||
$"CREATE INDEX IF NOT EXISTS idx_{tableName}_document ON {name} USING GIN (data{extraOps})"
|
$"CREATE INDEX IF NOT EXISTS idx_{tableName}_document ON {name} USING GIN (data{extraOps})"
|
||||||
|
@ -266,9 +268,9 @@ module WithProps =
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create an index on documents in the specified table
|
/// Create an index on documents in the specified table
|
||||||
[<CompiledName "EnsureJsonIndex">]
|
[<CompiledName "EnsureDocumentIndex">]
|
||||||
let ensureJsonIndex name idxType sqlProps =
|
let ensureDocumentIndex name idxType sqlProps =
|
||||||
Custom.nonQuery (Query.Definition.ensureJsonIndex name idxType) [] sqlProps
|
Custom.nonQuery (Query.Definition.ensureDocumentIndex name idxType) [] sqlProps
|
||||||
|
|
||||||
/// Create an index on field(s) within documents in the specified table
|
/// Create an index on field(s) within documents in the specified table
|
||||||
[<CompiledName "EnsureFieldIndex">]
|
[<CompiledName "EnsureFieldIndex">]
|
||||||
|
@ -549,9 +551,9 @@ module Definition =
|
||||||
WithProps.Definition.ensureTable name (fromDataSource ())
|
WithProps.Definition.ensureTable name (fromDataSource ())
|
||||||
|
|
||||||
/// Create an index on documents in the specified table
|
/// Create an index on documents in the specified table
|
||||||
[<CompiledName "EnsureJsonIndex">]
|
[<CompiledName "EnsureDocumentIndex">]
|
||||||
let ensureJsonIndex name idxType =
|
let ensureDocumentIndex name idxType =
|
||||||
WithProps.Definition.ensureJsonIndex name idxType (fromDataSource ())
|
WithProps.Definition.ensureDocumentIndex name idxType (fromDataSource ())
|
||||||
|
|
||||||
/// Create an index on field(s) within documents in the specified table
|
/// Create an index on field(s) within documents in the specified table
|
||||||
[<CompiledName "EnsureFieldIndex">]
|
[<CompiledName "EnsureFieldIndex">]
|
||||||
|
|
|
@ -23,218 +23,216 @@ public static class CommonCSharpTests
|
||||||
/// Unit tests
|
/// Unit tests
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Tests]
|
[Tests]
|
||||||
public static Test Unit =
|
public static readonly Test Unit = TestList("Common.C# Unit", new[]
|
||||||
TestList("Common.C# Unit", new[]
|
{
|
||||||
{
|
TestSequenced(
|
||||||
TestSequenced(
|
TestList("Configuration", new[]
|
||||||
TestList("Configuration", new[]
|
|
||||||
{
|
|
||||||
TestCase("UseSerializer succeeds", () =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Configuration.UseSerializer(new TestSerializer());
|
|
||||||
|
|
||||||
var serialized = Configuration.Serializer().Serialize(new SubDocument
|
|
||||||
{
|
|
||||||
Foo = "howdy",
|
|
||||||
Bar = "bye"
|
|
||||||
});
|
|
||||||
Expect.equal(serialized, "{\"Overridden\":true}", "Specified serializer was not used");
|
|
||||||
|
|
||||||
var deserialized = Configuration.Serializer()
|
|
||||||
.Deserialize<object>("{\"Something\":\"here\"}");
|
|
||||||
Expect.isNull(deserialized, "Specified serializer should have returned null");
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
Configuration.UseSerializer(DocumentSerializer.Default);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
TestCase("Serializer returns configured serializer", () =>
|
|
||||||
{
|
|
||||||
Expect.isTrue(ReferenceEquals(DocumentSerializer.Default, Configuration.Serializer()),
|
|
||||||
"Serializer should have been the same");
|
|
||||||
}),
|
|
||||||
TestCase("UseIdField / IdField succeeds", () =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Expect.equal(Configuration.IdField(), "Id",
|
|
||||||
"The default configured ID field was incorrect");
|
|
||||||
Configuration.UseIdField("id");
|
|
||||||
Expect.equal(Configuration.IdField(), "id", "UseIdField did not set the ID field");
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
Configuration.UseIdField("Id");
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})),
|
|
||||||
TestList("Op", new[]
|
|
||||||
{
|
{
|
||||||
TestCase("EQ succeeds", () =>
|
TestCase("UseSerializer succeeds", () =>
|
||||||
{
|
{
|
||||||
Expect.equal(Op.EQ.ToString(), "=", "The equals operator was not correct");
|
try
|
||||||
|
{
|
||||||
|
Configuration.UseSerializer(new TestSerializer());
|
||||||
|
|
||||||
|
var serialized = Configuration.Serializer().Serialize(new SubDocument
|
||||||
|
{
|
||||||
|
Foo = "howdy",
|
||||||
|
Bar = "bye"
|
||||||
|
});
|
||||||
|
Expect.equal(serialized, "{\"Overridden\":true}", "Specified serializer was not used");
|
||||||
|
|
||||||
|
var deserialized = Configuration.Serializer()
|
||||||
|
.Deserialize<object>("{\"Something\":\"here\"}");
|
||||||
|
Expect.isNull(deserialized, "Specified serializer should have returned null");
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Configuration.UseSerializer(DocumentSerializer.Default);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
TestCase("GT succeeds", () =>
|
TestCase("Serializer returns configured serializer", () =>
|
||||||
{
|
{
|
||||||
Expect.equal(Op.GT.ToString(), ">", "The greater than operator was not correct");
|
Expect.isTrue(ReferenceEquals(DocumentSerializer.Default, Configuration.Serializer()),
|
||||||
|
"Serializer should have been the same");
|
||||||
}),
|
}),
|
||||||
TestCase("GE succeeds", () =>
|
TestCase("UseIdField / IdField succeeds", () =>
|
||||||
{
|
{
|
||||||
Expect.equal(Op.GE.ToString(), ">=", "The greater than or equal to operator was not correct");
|
try
|
||||||
|
{
|
||||||
|
Expect.equal(Configuration.IdField(), "Id",
|
||||||
|
"The default configured ID field was incorrect");
|
||||||
|
Configuration.UseIdField("id");
|
||||||
|
Expect.equal(Configuration.IdField(), "id", "UseIdField did not set the ID field");
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Configuration.UseIdField("Id");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})),
|
||||||
|
TestList("Op", new[]
|
||||||
|
{
|
||||||
|
TestCase("EQ succeeds", () =>
|
||||||
|
{
|
||||||
|
Expect.equal(Op.EQ.ToString(), "=", "The equals operator was not correct");
|
||||||
|
}),
|
||||||
|
TestCase("GT succeeds", () =>
|
||||||
|
{
|
||||||
|
Expect.equal(Op.GT.ToString(), ">", "The greater than operator was not correct");
|
||||||
|
}),
|
||||||
|
TestCase("GE succeeds", () =>
|
||||||
|
{
|
||||||
|
Expect.equal(Op.GE.ToString(), ">=", "The greater than or equal to operator was not correct");
|
||||||
|
}),
|
||||||
|
TestCase("LT succeeds", () =>
|
||||||
|
{
|
||||||
|
Expect.equal(Op.LT.ToString(), "<", "The less than operator was not correct");
|
||||||
|
}),
|
||||||
|
TestCase("LE succeeds", () =>
|
||||||
|
{
|
||||||
|
Expect.equal(Op.LE.ToString(), "<=", "The less than or equal to operator was not correct");
|
||||||
|
}),
|
||||||
|
TestCase("NE succeeds", () =>
|
||||||
|
{
|
||||||
|
Expect.equal(Op.NE.ToString(), "<>", "The not equal to operator was not correct");
|
||||||
|
}),
|
||||||
|
TestCase("EX succeeds", () =>
|
||||||
|
{
|
||||||
|
Expect.equal(Op.EX.ToString(), "IS NOT NULL", "The \"exists\" operator was not correct");
|
||||||
|
}),
|
||||||
|
TestCase("NEX succeeds", () =>
|
||||||
|
{
|
||||||
|
Expect.equal(Op.NEX.ToString(), "IS NULL", "The \"not exists\" operator was not correct");
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
TestList("Query", new[]
|
||||||
|
{
|
||||||
|
TestCase("SelectFromTable succeeds", () =>
|
||||||
|
{
|
||||||
|
Expect.equal(Query.SelectFromTable("test.table"), "SELECT data FROM test.table",
|
||||||
|
"SELECT statement not correct");
|
||||||
|
}),
|
||||||
|
TestCase("WhereById succeeds", () =>
|
||||||
|
{
|
||||||
|
Expect.equal(Query.WhereById("@id"), "data ->> 'Id' = @id", "WHERE clause not correct");
|
||||||
|
}),
|
||||||
|
TestList("WhereByField", new[]
|
||||||
|
{
|
||||||
|
TestCase("succeeds when a logical operator is passed", () =>
|
||||||
|
{
|
||||||
|
Expect.equal(Query.WhereByField("theField", Op.GT, "@test"), "data ->> 'theField' > @test",
|
||||||
|
"WHERE clause not correct");
|
||||||
}),
|
}),
|
||||||
TestCase("LT succeeds", () =>
|
TestCase("succeeds when an existence operator is passed", () =>
|
||||||
{
|
{
|
||||||
Expect.equal(Op.LT.ToString(), "<", "The less than operator was not correct");
|
Expect.equal(Query.WhereByField("thatField", Op.NEX, ""), "data ->> 'thatField' IS NULL",
|
||||||
}),
|
"WHERE clause not correct");
|
||||||
TestCase("LE succeeds", () =>
|
|
||||||
{
|
|
||||||
Expect.equal(Op.LE.ToString(), "<=", "The less than or equal to operator was not correct");
|
|
||||||
}),
|
|
||||||
TestCase("NE succeeds", () =>
|
|
||||||
{
|
|
||||||
Expect.equal(Op.NE.ToString(), "<>", "The not equal to operator was not correct");
|
|
||||||
}),
|
|
||||||
TestCase("EX succeeds", () =>
|
|
||||||
{
|
|
||||||
Expect.equal(Op.EX.ToString(), "IS NOT NULL", "The \"exists\" operator was not correct");
|
|
||||||
}),
|
|
||||||
TestCase("NEX succeeds", () =>
|
|
||||||
{
|
|
||||||
Expect.equal(Op.NEX.ToString(), "IS NULL", "The \"not exists\" operator was not correct");
|
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
TestList("Query", new[]
|
TestList("Definition", new[]
|
||||||
{
|
{
|
||||||
TestCase("SelectFromTable succeeds", () =>
|
TestCase("EnsureTableFor succeeds", () =>
|
||||||
{
|
{
|
||||||
Expect.equal(Query.SelectFromTable("test.table"), "SELECT data FROM test.table",
|
Expect.equal(Query.Definition.EnsureTableFor("my.table", "JSONB"),
|
||||||
"SELECT statement not correct");
|
"CREATE TABLE IF NOT EXISTS my.table (data JSONB NOT NULL)",
|
||||||
|
"CREATE TABLE statement not constructed correctly");
|
||||||
}),
|
}),
|
||||||
TestCase("WhereById succeeds", () =>
|
TestList("EnsureKey", new[]
|
||||||
{
|
{
|
||||||
Expect.equal(Query.WhereById("@id"), "data ->> 'Id' = @id", "WHERE clause not correct");
|
TestCase("succeeds when a schema is present", () =>
|
||||||
}),
|
|
||||||
TestList("WhereByField", new[]
|
|
||||||
{
|
|
||||||
TestCase("succeeds when a logical operator is passed", () =>
|
|
||||||
{
|
{
|
||||||
Expect.equal(Query.WhereByField("theField", Op.GT, "@test"), "data ->> 'theField' > @test",
|
Expect.equal(Query.Definition.EnsureKey("test.table"),
|
||||||
"WHERE clause not correct");
|
"CREATE UNIQUE INDEX IF NOT EXISTS idx_table_key ON test.table ((data ->> 'Id'))",
|
||||||
|
"CREATE INDEX for key statement with schema not constructed correctly");
|
||||||
}),
|
}),
|
||||||
TestCase("succeeds when an existence operator is passed", () =>
|
TestCase("succeeds when a schema is not present", () =>
|
||||||
{
|
{
|
||||||
Expect.equal(Query.WhereByField("thatField", Op.NEX, ""), "data ->> 'thatField' IS NULL",
|
Expect.equal(Query.Definition.EnsureKey("table"),
|
||||||
"WHERE clause not correct");
|
"CREATE UNIQUE INDEX IF NOT EXISTS idx_table_key ON table ((data ->> 'Id'))",
|
||||||
|
"CREATE INDEX for key statement without schema not constructed correctly");
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
TestList("Definition", new[]
|
TestCase("EnsureIndexOn succeeds for multiple fields and directions", () =>
|
||||||
{
|
{
|
||||||
TestCase("EnsureTableFor succeeds", () =>
|
Expect.equal(
|
||||||
{
|
Query.Definition.EnsureIndexOn("test.table", "gibberish",
|
||||||
Expect.equal(Query.Definition.EnsureTableFor("my.table", "JSONB"),
|
new[] { "taco", "guac DESC", "salsa ASC" }),
|
||||||
"CREATE TABLE IF NOT EXISTS my.table (data JSONB NOT NULL)",
|
"CREATE INDEX IF NOT EXISTS idx_table_gibberish ON test.table "
|
||||||
"CREATE TABLE statement not constructed correctly");
|
+ "((data ->> 'taco'), (data ->> 'guac') DESC, (data ->> 'salsa') ASC)",
|
||||||
}),
|
"CREATE INDEX for multiple field statement incorrect");
|
||||||
TestList("EnsureKey", new[]
|
})
|
||||||
{
|
}),
|
||||||
TestCase("succeeds when a schema is present", () =>
|
TestCase("Insert succeeds", () =>
|
||||||
{
|
{
|
||||||
Expect.equal(Query.Definition.EnsureKey("test.table"),
|
Expect.equal(Query.Insert("tbl"), "INSERT INTO tbl VALUES (@data)", "INSERT statement not correct");
|
||||||
"CREATE UNIQUE INDEX IF NOT EXISTS idx_table_key ON test.table ((data ->> 'Id'))",
|
}),
|
||||||
"CREATE INDEX for key statement with schema not constructed correctly");
|
TestCase("Save succeeds", () =>
|
||||||
}),
|
{
|
||||||
TestCase("succeeds when a schema is not present", () =>
|
Expect.equal(Query.Save("tbl"),
|
||||||
{
|
$"INSERT INTO tbl VALUES (@data) ON CONFLICT ((data ->> 'Id')) DO UPDATE SET data = EXCLUDED.data",
|
||||||
Expect.equal(Query.Definition.EnsureKey("table"),
|
"INSERT ON CONFLICT UPDATE statement not correct");
|
||||||
"CREATE UNIQUE INDEX IF NOT EXISTS idx_table_key ON table ((data ->> 'Id'))",
|
}),
|
||||||
"CREATE INDEX for key statement without schema not constructed correctly");
|
TestList("Count", new[]
|
||||||
})
|
{
|
||||||
}),
|
TestCase("All succeeds", () =>
|
||||||
TestCase("EnsureIndexOn succeeds for multiple fields and directions", () =>
|
{
|
||||||
{
|
Expect.equal(Query.Count.All("tbl"), "SELECT COUNT(*) AS it FROM tbl", "Count query not correct");
|
||||||
Expect.equal(
|
|
||||||
Query.Definition.EnsureIndexOn("test.table", "gibberish",
|
|
||||||
new[] { "taco", "guac DESC", "salsa ASC" }),
|
|
||||||
"CREATE INDEX IF NOT EXISTS idx_table_gibberish ON test.table "
|
|
||||||
+ "((data ->> 'taco'), (data ->> 'guac') DESC, (data ->> 'salsa') ASC)",
|
|
||||||
"CREATE INDEX for multiple field statement incorrect");
|
|
||||||
})
|
|
||||||
}),
|
}),
|
||||||
TestCase("Insert succeeds", () =>
|
TestCase("ByField succeeds", () =>
|
||||||
{
|
{
|
||||||
Expect.equal(Query.Insert("tbl"), "INSERT INTO tbl VALUES (@data)", "INSERT statement not correct");
|
Expect.equal(Query.Count.ByField("tbl", "thatField", Op.EQ),
|
||||||
|
"SELECT COUNT(*) AS it FROM tbl WHERE data ->> 'thatField' = @field",
|
||||||
|
"JSON field text comparison count query not correct");
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
TestList("Exists", new[]
|
||||||
|
{
|
||||||
|
TestCase("ById succeeds", () =>
|
||||||
|
{
|
||||||
|
Expect.equal(Query.Exists.ById("tbl"),
|
||||||
|
"SELECT EXISTS (SELECT 1 FROM tbl WHERE data ->> 'Id' = @id) AS it",
|
||||||
|
"ID existence query not correct");
|
||||||
}),
|
}),
|
||||||
TestCase("Save succeeds", () =>
|
TestCase("ByField succeeds", () =>
|
||||||
{
|
{
|
||||||
Expect.equal(Query.Save("tbl"),
|
Expect.equal(Query.Exists.ByField("tbl", "Test", Op.LT),
|
||||||
$"INSERT INTO tbl VALUES (@data) ON CONFLICT ((data ->> 'Id')) DO UPDATE SET data = EXCLUDED.data",
|
"SELECT EXISTS (SELECT 1 FROM tbl WHERE data ->> 'Test' < @field) AS it",
|
||||||
"INSERT ON CONFLICT UPDATE statement not correct");
|
"JSON field text comparison exists query not correct");
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
TestList("Find", new[]
|
||||||
|
{
|
||||||
|
TestCase("ById succeeds", () =>
|
||||||
|
{
|
||||||
|
Expect.equal(Query.Find.ById("tbl"), "SELECT data FROM tbl WHERE data ->> 'Id' = @id",
|
||||||
|
"SELECT by ID query not correct");
|
||||||
}),
|
}),
|
||||||
TestList("Count", new[]
|
TestCase("ByField succeeds", () =>
|
||||||
{
|
{
|
||||||
TestCase("All succeeds", () =>
|
Expect.equal(Query.Find.ByField("tbl", "Golf", Op.GE),
|
||||||
{
|
"SELECT data FROM tbl WHERE data ->> 'Golf' >= @field",
|
||||||
Expect.equal(Query.Count.All("tbl"), "SELECT COUNT(*) AS it FROM tbl",
|
"SELECT by JSON comparison query not correct");
|
||||||
"Count query not correct");
|
})
|
||||||
}),
|
}),
|
||||||
TestCase("ByField succeeds", () =>
|
TestCase("Update.Full succeeds", () =>
|
||||||
{
|
{
|
||||||
Expect.equal(Query.Count.ByField("tbl", "thatField", Op.EQ),
|
Expect.equal(Query.Update.Full("tbl"), "UPDATE tbl SET data = @data WHERE data ->> 'Id' = @id",
|
||||||
"SELECT COUNT(*) AS it FROM tbl WHERE data ->> 'thatField' = @field",
|
"UPDATE full statement not correct");
|
||||||
"JSON field text comparison count query not correct");
|
}),
|
||||||
})
|
TestList("Delete", new[]
|
||||||
|
{
|
||||||
|
TestCase("ById succeeds", () =>
|
||||||
|
{
|
||||||
|
Expect.equal(Query.Delete.ById("tbl"), "DELETE FROM tbl WHERE data ->> 'Id' = @id",
|
||||||
|
"DELETE by ID query not correct");
|
||||||
}),
|
}),
|
||||||
TestList("Exists", new[]
|
TestCase("ByField succeeds", () =>
|
||||||
{
|
{
|
||||||
TestCase("ById succeeds", () =>
|
Expect.equal(Query.Delete.ByField("tbl", "gone", Op.NEX),
|
||||||
{
|
"DELETE FROM tbl WHERE data ->> 'gone' IS NULL",
|
||||||
Expect.equal(Query.Exists.ById("tbl"),
|
"DELETE by JSON comparison query not correct");
|
||||||
"SELECT EXISTS (SELECT 1 FROM tbl WHERE data ->> 'Id' = @id) AS it",
|
|
||||||
"ID existence query not correct");
|
|
||||||
}),
|
|
||||||
TestCase("ByField succeeds", () =>
|
|
||||||
{
|
|
||||||
Expect.equal(Query.Exists.ByField("tbl", "Test", Op.LT),
|
|
||||||
"SELECT EXISTS (SELECT 1 FROM tbl WHERE data ->> 'Test' < @field) AS it",
|
|
||||||
"JSON field text comparison exists query not correct");
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
TestList("Find", new[]
|
|
||||||
{
|
|
||||||
TestCase("ById succeeds", () =>
|
|
||||||
{
|
|
||||||
Expect.equal(Query.Find.ById("tbl"), "SELECT data FROM tbl WHERE data ->> 'Id' = @id",
|
|
||||||
"SELECT by ID query not correct");
|
|
||||||
}),
|
|
||||||
TestCase("ByField succeeds", () =>
|
|
||||||
{
|
|
||||||
Expect.equal(Query.Find.ByField("tbl", "Golf", Op.GE),
|
|
||||||
"SELECT data FROM tbl WHERE data ->> 'Golf' >= @field",
|
|
||||||
"SELECT by JSON comparison query not correct");
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
TestCase("Update.Full succeeds", () =>
|
|
||||||
{
|
|
||||||
Expect.equal(Query.Update.Full("tbl"), "UPDATE tbl SET data = @data WHERE data ->> 'Id' = @id",
|
|
||||||
"UPDATE full statement not correct");
|
|
||||||
}),
|
|
||||||
TestList("Delete", new[]
|
|
||||||
{
|
|
||||||
TestCase("ById succeeds", () =>
|
|
||||||
{
|
|
||||||
Expect.equal(Query.Delete.ById("tbl"), "DELETE FROM tbl WHERE data ->> 'Id' = @id",
|
|
||||||
"DELETE by ID query not correct");
|
|
||||||
}),
|
|
||||||
TestCase("ByField succeeds", () =>
|
|
||||||
{
|
|
||||||
Expect.equal(Query.Delete.ByField("tbl", "gone", Op.NEX),
|
|
||||||
"DELETE FROM tbl WHERE data ->> 'gone' IS NULL",
|
|
||||||
"DELETE by JSON comparison query not correct");
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
});
|
})
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -137,7 +137,7 @@ public static class PostgresDb
|
||||||
Sql.executeNonQuery(Sql.query(Postgres.Query.Definition.EnsureTable(TableName), sqlProps));
|
Sql.executeNonQuery(Sql.query(Postgres.Query.Definition.EnsureTable(TableName), sqlProps));
|
||||||
Sql.executeNonQuery(Sql.query(Query.Definition.EnsureKey(TableName), sqlProps));
|
Sql.executeNonQuery(Sql.query(Query.Definition.EnsureKey(TableName), sqlProps));
|
||||||
|
|
||||||
Postgres.Configuration.useDataSource(MkDataSource(database.ConnectionString));
|
Postgres.Configuration.UseDataSource(MkDataSource(database.ConnectionString));
|
||||||
|
|
||||||
return new ThrowawayPostgresDb(database);
|
return new ThrowawayPostgresDb(database);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,498 +14,492 @@ public static class SqliteCSharpExtensionTests
|
||||||
{
|
{
|
||||||
private static Task LoadDocs() => SqliteCSharpTests.LoadDocs();
|
private static Task LoadDocs() => SqliteCSharpTests.LoadDocs();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Integration tests for the SQLite extension methods
|
||||||
|
/// </summary>
|
||||||
[Tests]
|
[Tests]
|
||||||
public static Test Integration =
|
public static readonly Test Integration = TestList("Extensions", new[]
|
||||||
TestList("Extensions", new[]
|
{
|
||||||
|
TestList("CustomSingle", new[]
|
||||||
{
|
{
|
||||||
TestList("CustomSingle", new[]
|
TestCase("succeeds when a row is found", async () =>
|
||||||
{
|
|
||||||
TestCase("succeeds when a row is found", async () =>
|
|
||||||
{
|
|
||||||
await using var db = await SqliteDb.BuildDb();
|
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
|
||||||
await LoadDocs();
|
|
||||||
|
|
||||||
var doc = await conn.CustomSingle(
|
|
||||||
$"SELECT data FROM {SqliteDb.TableName} WHERE data ->> 'Id' = @id",
|
|
||||||
new[] { Parameters.Id("one") }, Results.FromData<JsonDocument>);
|
|
||||||
Expect.isNotNull(doc, "There should have been a document returned");
|
|
||||||
Expect.equal(doc!.Id, "one", "The incorrect document was returned");
|
|
||||||
}),
|
|
||||||
TestCase("succeeds when a row is not found", async () =>
|
|
||||||
{
|
|
||||||
await using var db = await SqliteDb.BuildDb();
|
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
|
||||||
await LoadDocs();
|
|
||||||
|
|
||||||
var doc = await conn.CustomSingle(
|
|
||||||
$"SELECT data FROM {SqliteDb.TableName} WHERE data ->> 'Id' = @id",
|
|
||||||
new[] { Parameters.Id("eighty") }, Results.FromData<JsonDocument>);
|
|
||||||
Expect.isNull(doc, "There should not have been a document returned");
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
TestList("CustomList", new[]
|
|
||||||
{
|
|
||||||
TestCase("succeeds when data is found", async () =>
|
|
||||||
{
|
|
||||||
await using var db = await SqliteDb.BuildDb();
|
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
|
||||||
await LoadDocs();
|
|
||||||
|
|
||||||
var docs = await conn.CustomList(Query.SelectFromTable(SqliteDb.TableName), Parameters.None,
|
|
||||||
Results.FromData<JsonDocument>);
|
|
||||||
Expect.equal(docs.Count, 5, "There should have been 5 documents returned");
|
|
||||||
}),
|
|
||||||
TestCase("succeeds when data is not found", async () =>
|
|
||||||
{
|
|
||||||
await using var db = await SqliteDb.BuildDb();
|
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
|
||||||
await LoadDocs();
|
|
||||||
|
|
||||||
var docs = await conn.CustomList(
|
|
||||||
$"SELECT data FROM {SqliteDb.TableName} WHERE data ->> 'NumValue' > @value",
|
|
||||||
new[] { new SqliteParameter("@value", 100) }, Results.FromData<JsonDocument>);
|
|
||||||
Expect.isEmpty(docs, "There should have been no documents returned");
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
TestList("CustomNonQuery", new[]
|
|
||||||
{
|
|
||||||
TestCase("succeeds when operating on data", async () =>
|
|
||||||
{
|
|
||||||
await using var db = await SqliteDb.BuildDb();
|
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
|
||||||
await LoadDocs();
|
|
||||||
|
|
||||||
await conn.CustomNonQuery($"DELETE FROM {SqliteDb.TableName}", Parameters.None);
|
|
||||||
|
|
||||||
var remaining = await conn.CountAll(SqliteDb.TableName);
|
|
||||||
Expect.equal(remaining, 0L, "There should be no documents remaining in the table");
|
|
||||||
}),
|
|
||||||
TestCase("succeeds when no data matches where clause", async () =>
|
|
||||||
{
|
|
||||||
await using var db = await SqliteDb.BuildDb();
|
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
|
||||||
await LoadDocs();
|
|
||||||
|
|
||||||
await conn.CustomNonQuery(
|
|
||||||
$"DELETE FROM {SqliteDb.TableName} WHERE data ->> 'NumValue' > @value",
|
|
||||||
new[] { new SqliteParameter("@value", 100) });
|
|
||||||
|
|
||||||
var remaining = await conn.CountAll(SqliteDb.TableName);
|
|
||||||
Expect.equal(remaining, 5L, "There should be 5 documents remaining in the table");
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
TestCase("CustomScalar succeeds", async () =>
|
|
||||||
{
|
|
||||||
await using var db = await SqliteDb.BuildDb();
|
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
|
||||||
|
|
||||||
var nbr = await conn.CustomScalar("SELECT 5 AS test_value", Parameters.None, rdr => rdr.GetInt32(0));
|
|
||||||
Expect.equal(nbr, 5, "The query should have returned the number 5");
|
|
||||||
}),
|
|
||||||
TestCase("EnsureTable succeeds", async () =>
|
|
||||||
{
|
|
||||||
await using var db = await SqliteDb.BuildDb();
|
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
|
||||||
|
|
||||||
Func<string, ValueTask<bool>> itExists = async name =>
|
|
||||||
{
|
|
||||||
var result = 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;
|
|
||||||
};
|
|
||||||
|
|
||||||
var exists = await itExists("ensured");
|
|
||||||
var alsoExists = await itExists("idx_ensured_key");
|
|
||||||
Expect.isFalse(exists, "The table should not exist already");
|
|
||||||
Expect.isFalse(alsoExists, "The key index should not exist already");
|
|
||||||
|
|
||||||
await conn.EnsureTable("ensured");
|
|
||||||
|
|
||||||
exists = await itExists("ensured");
|
|
||||||
alsoExists = await itExists("idx_ensured_key");
|
|
||||||
Expect.isTrue(exists, "The table should now exist");
|
|
||||||
Expect.isTrue(alsoExists, "The key index should now exist");
|
|
||||||
}),
|
|
||||||
TestList("Insert", new[]
|
|
||||||
{
|
|
||||||
TestCase("succeeds", async () =>
|
|
||||||
{
|
|
||||||
await using var db = await SqliteDb.BuildDb();
|
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
|
||||||
var before = await conn.FindAll<SubDocument>(SqliteDb.TableName);
|
|
||||||
Expect.isEmpty(before, "There should be no documents in the table");
|
|
||||||
await conn.Insert(SqliteDb.TableName,
|
|
||||||
new JsonDocument { Id = "turkey", Sub = new() { Foo = "gobble", Bar = "gobble" } });
|
|
||||||
var after = await conn.FindAll<JsonDocument>(SqliteDb.TableName);
|
|
||||||
Expect.equal(after.Count, 1, "There should have been one document inserted");
|
|
||||||
}),
|
|
||||||
TestCase("fails for duplicate key", async () =>
|
|
||||||
{
|
|
||||||
await using var db = await SqliteDb.BuildDb();
|
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
|
||||||
await conn.Insert(SqliteDb.TableName, new JsonDocument { Id = "test" });
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await Document.Insert(SqliteDb.TableName, new JsonDocument { Id = "test" });
|
|
||||||
Expect.isTrue(false, "An exception should have been raised for duplicate document ID insert");
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
// This is what is supposed to happen
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
TestList("Save", new[]
|
|
||||||
{
|
|
||||||
TestCase("succeeds when a document is inserted", async () =>
|
|
||||||
{
|
|
||||||
await using var db = await SqliteDb.BuildDb();
|
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
|
||||||
var before = await conn.FindAll<JsonDocument>(SqliteDb.TableName);
|
|
||||||
Expect.isEmpty(before, "There should be no documents in the table");
|
|
||||||
|
|
||||||
await conn.Save(SqliteDb.TableName,
|
|
||||||
new JsonDocument { Id = "test", Sub = new() { Foo = "a", Bar = "b" } });
|
|
||||||
var after = await conn.FindAll<JsonDocument>(SqliteDb.TableName);
|
|
||||||
Expect.equal(after.Count, 1, "There should have been one document inserted");
|
|
||||||
}),
|
|
||||||
TestCase("succeeds when a document is updated", async () =>
|
|
||||||
{
|
|
||||||
await using var db = await SqliteDb.BuildDb();
|
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
|
||||||
await conn.Insert(SqliteDb.TableName,
|
|
||||||
new JsonDocument { Id = "test", Sub = new() { Foo = "a", Bar = "b" } });
|
|
||||||
|
|
||||||
var before = await conn.FindById<string, JsonDocument>(SqliteDb.TableName, "test");
|
|
||||||
Expect.isNotNull(before, "There should have been a document returned");
|
|
||||||
Expect.equal(before!.Id, "test", "The document is not correct");
|
|
||||||
Expect.isNotNull(before.Sub, "There should have been a sub-document");
|
|
||||||
Expect.equal(before.Sub!.Foo, "a", "The document is not correct");
|
|
||||||
Expect.equal(before.Sub.Bar, "b", "The document is not correct");
|
|
||||||
|
|
||||||
await conn.Save(SqliteDb.TableName, new JsonDocument { Id = "test" });
|
|
||||||
var after = await conn.FindById<string, JsonDocument>(SqliteDb.TableName, "test");
|
|
||||||
Expect.isNotNull(after, "There should have been a document returned post-update");
|
|
||||||
Expect.equal(after!.Id, "test", "The updated document is not correct");
|
|
||||||
Expect.isNull(after.Sub, "There should not have been a sub-document in the updated document");
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
TestCase("CountAll succeeds", async () =>
|
|
||||||
{
|
{
|
||||||
await using var db = await SqliteDb.BuildDb();
|
await using var db = await SqliteDb.BuildDb();
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
await LoadDocs();
|
await LoadDocs();
|
||||||
|
|
||||||
var theCount = await conn.CountAll(SqliteDb.TableName);
|
var doc = await conn.CustomSingle($"SELECT data FROM {SqliteDb.TableName} WHERE data ->> 'Id' = @id",
|
||||||
Expect.equal(theCount, 5L, "There should have been 5 matching documents");
|
new[] { Parameters.Id("one") }, Results.FromData<JsonDocument>);
|
||||||
|
Expect.isNotNull(doc, "There should have been a document returned");
|
||||||
|
Expect.equal(doc!.Id, "one", "The incorrect document was returned");
|
||||||
}),
|
}),
|
||||||
TestCase("CountByField succeeds", async () =>
|
TestCase("succeeds when a row is not found", async () =>
|
||||||
{
|
{
|
||||||
await using var db = await SqliteDb.BuildDb();
|
await using var db = await SqliteDb.BuildDb();
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
await LoadDocs();
|
await LoadDocs();
|
||||||
|
|
||||||
var theCount = await conn.CountByField(SqliteDb.TableName, "Value", Op.EQ, "purple");
|
var doc = await conn.CustomSingle($"SELECT data FROM {SqliteDb.TableName} WHERE data ->> 'Id' = @id",
|
||||||
Expect.equal(theCount, 2L, "There should have been 2 matching documents");
|
new[] { Parameters.Id("eighty") }, Results.FromData<JsonDocument>);
|
||||||
}),
|
Expect.isNull(doc, "There should not have been a document returned");
|
||||||
TestList("ExistsById", new[]
|
})
|
||||||
|
}),
|
||||||
|
TestList("CustomList", new[]
|
||||||
|
{
|
||||||
|
TestCase("succeeds when data is found", async () =>
|
||||||
{
|
{
|
||||||
TestCase("succeeds when a document exists", async () =>
|
await using var db = await SqliteDb.BuildDb();
|
||||||
{
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
await using var db = await SqliteDb.BuildDb();
|
await LoadDocs();
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
|
||||||
await LoadDocs();
|
|
||||||
|
|
||||||
var exists = await conn.ExistsById(SqliteDb.TableName, "three");
|
var docs = await conn.CustomList(Query.SelectFromTable(SqliteDb.TableName), Parameters.None,
|
||||||
Expect.isTrue(exists, "There should have been an existing document");
|
Results.FromData<JsonDocument>);
|
||||||
}),
|
Expect.equal(docs.Count, 5, "There should have been 5 documents returned");
|
||||||
TestCase("succeeds when a document does not exist", async () =>
|
|
||||||
{
|
|
||||||
await using var db = await SqliteDb.BuildDb();
|
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
|
||||||
await LoadDocs();
|
|
||||||
|
|
||||||
var exists = await conn.ExistsById(SqliteDb.TableName, "seven");
|
|
||||||
Expect.isFalse(exists, "There should not have been an existing document");
|
|
||||||
})
|
|
||||||
}),
|
}),
|
||||||
TestList("ExistsByField", new[]
|
TestCase("succeeds when data is not found", async () =>
|
||||||
{
|
{
|
||||||
TestCase("succeeds when documents exist", async () =>
|
await using var db = await SqliteDb.BuildDb();
|
||||||
{
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
await using var db = await SqliteDb.BuildDb();
|
await LoadDocs();
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
|
||||||
await LoadDocs();
|
|
||||||
|
|
||||||
var exists = await conn.ExistsByField(SqliteDb.TableName, "NumValue", Op.GE, 10);
|
var docs = await conn.CustomList(
|
||||||
Expect.isTrue(exists, "There should have been existing documents");
|
$"SELECT data FROM {SqliteDb.TableName} WHERE data ->> 'NumValue' > @value",
|
||||||
}),
|
new[] { new SqliteParameter("@value", 100) }, Results.FromData<JsonDocument>);
|
||||||
TestCase("succeeds when no matching documents exist", async () =>
|
Expect.isEmpty(docs, "There should have been no documents returned");
|
||||||
{
|
})
|
||||||
await using var db = await SqliteDb.BuildDb();
|
}),
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
TestList("CustomNonQuery", new[]
|
||||||
await LoadDocs();
|
{
|
||||||
|
TestCase("succeeds when operating on data", async () =>
|
||||||
var exists = await conn.ExistsByField(SqliteDb.TableName, "Nothing", Op.EQ, "none");
|
|
||||||
Expect.isFalse(exists, "There should not have been any existing documents");
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
TestList("FindAll", new[]
|
|
||||||
{
|
{
|
||||||
TestCase("succeeds when there is data", async () =>
|
await using var db = await SqliteDb.BuildDb();
|
||||||
{
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
await using var db = await SqliteDb.BuildDb();
|
await LoadDocs();
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
|
||||||
|
|
||||||
await conn.Insert(SqliteDb.TableName, new JsonDocument { Id = "one", Value = "two" });
|
await conn.CustomNonQuery($"DELETE FROM {SqliteDb.TableName}", Parameters.None);
|
||||||
await conn.Insert(SqliteDb.TableName, new JsonDocument { Id = "three", Value = "four" });
|
|
||||||
await conn.Insert(SqliteDb.TableName, new JsonDocument { Id = "five", Value = "six" });
|
|
||||||
|
|
||||||
var results = await conn.FindAll<JsonDocument>(SqliteDb.TableName);
|
var remaining = await conn.CountAll(SqliteDb.TableName);
|
||||||
Expect.equal(results.Count, 3, "There should have been 3 documents returned");
|
Expect.equal(remaining, 0L, "There should be no documents remaining in the table");
|
||||||
}),
|
|
||||||
TestCase("succeeds when there is no data", async () =>
|
|
||||||
{
|
|
||||||
await using var db = await SqliteDb.BuildDb();
|
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
|
||||||
var results = await conn.FindAll<JsonDocument>(SqliteDb.TableName);
|
|
||||||
Expect.isEmpty(results, "There should have been no documents returned");
|
|
||||||
})
|
|
||||||
}),
|
}),
|
||||||
TestList("FindById", new[]
|
TestCase("succeeds when no data matches where clause", async () =>
|
||||||
{
|
{
|
||||||
TestCase("succeeds when a document is found", async () =>
|
await using var db = await SqliteDb.BuildDb();
|
||||||
{
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
await using var db = await SqliteDb.BuildDb();
|
await LoadDocs();
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
|
||||||
await LoadDocs();
|
|
||||||
|
|
||||||
var doc = await conn.FindById<string, JsonDocument>(SqliteDb.TableName, "two");
|
await conn.CustomNonQuery($"DELETE FROM {SqliteDb.TableName} WHERE data ->> 'NumValue' > @value",
|
||||||
Expect.isNotNull(doc, "There should have been a document returned");
|
new[] { new SqliteParameter("@value", 100) });
|
||||||
Expect.equal(doc!.Id, "two", "The incorrect document was returned");
|
|
||||||
}),
|
|
||||||
TestCase("succeeds when a document is not found", async () =>
|
|
||||||
{
|
|
||||||
await using var db = await SqliteDb.BuildDb();
|
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
|
||||||
await LoadDocs();
|
|
||||||
|
|
||||||
var doc = await conn.FindById<string, JsonDocument>(SqliteDb.TableName, "eighty-seven");
|
var remaining = await conn.CountAll(SqliteDb.TableName);
|
||||||
Expect.isNull(doc, "There should not have been a document returned");
|
Expect.equal(remaining, 5L, "There should be 5 documents remaining in the table");
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
TestList("FindByField", new[]
|
TestCase("CustomScalar succeeds", async () =>
|
||||||
|
{
|
||||||
|
await using var db = await SqliteDb.BuildDb();
|
||||||
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
|
|
||||||
|
var nbr = await conn.CustomScalar("SELECT 5 AS test_value", Parameters.None, rdr => rdr.GetInt32(0));
|
||||||
|
Expect.equal(nbr, 5, "The query should have returned the number 5");
|
||||||
|
}),
|
||||||
|
TestCase("EnsureTable succeeds", async () =>
|
||||||
|
{
|
||||||
|
await using var db = await SqliteDb.BuildDb();
|
||||||
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
|
|
||||||
|
Func<string, ValueTask<bool>> itExists = async name =>
|
||||||
{
|
{
|
||||||
TestCase("succeeds when documents are found", async () =>
|
var result = await conn.CustomScalar(
|
||||||
{
|
$"SELECT EXISTS (SELECT 1 FROM {SqliteDb.Catalog} WHERE name = @name) AS it",
|
||||||
await using var db = await SqliteDb.BuildDb();
|
new SqliteParameter[] { new("@name", name) }, rdr => rdr.GetInt64(0));
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
return result > 0L;
|
||||||
await LoadDocs();
|
};
|
||||||
|
|
||||||
var docs = await conn.FindByField<JsonDocument>(SqliteDb.TableName, "NumValue", Op.GT, 15);
|
var exists = await itExists("ensured");
|
||||||
Expect.equal(docs.Count, 2, "There should have been two documents returned");
|
var alsoExists = await itExists("idx_ensured_key");
|
||||||
}),
|
Expect.isFalse(exists, "The table should not exist already");
|
||||||
TestCase("succeeds when documents are not found", async () =>
|
Expect.isFalse(alsoExists, "The key index should not exist already");
|
||||||
{
|
|
||||||
await using var db = await SqliteDb.BuildDb();
|
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
|
||||||
await LoadDocs();
|
|
||||||
|
|
||||||
var docs = await conn.FindByField<JsonDocument>(SqliteDb.TableName, "Value", Op.EQ, "mauve");
|
await conn.EnsureTable("ensured");
|
||||||
Expect.isEmpty(docs, "There should have been no documents returned");
|
|
||||||
})
|
exists = await itExists("ensured");
|
||||||
}),
|
alsoExists = await itExists("idx_ensured_key");
|
||||||
TestList("FindFirstByField", new[]
|
Expect.isTrue(exists, "The table should now exist");
|
||||||
|
Expect.isTrue(alsoExists, "The key index should now exist");
|
||||||
|
}),
|
||||||
|
TestList("Insert", new[]
|
||||||
|
{
|
||||||
|
TestCase("succeeds", async () =>
|
||||||
{
|
{
|
||||||
TestCase("succeeds when a document is found", async () =>
|
await using var db = await SqliteDb.BuildDb();
|
||||||
{
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
await using var db = await SqliteDb.BuildDb();
|
var before = await conn.FindAll<SubDocument>(SqliteDb.TableName);
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
Expect.isEmpty(before, "There should be no documents in the table");
|
||||||
await LoadDocs();
|
await conn.Insert(SqliteDb.TableName,
|
||||||
|
new JsonDocument { Id = "turkey", Sub = new() { Foo = "gobble", Bar = "gobble" } });
|
||||||
var doc = await conn.FindFirstByField<JsonDocument>(SqliteDb.TableName, "Value", Op.EQ,
|
var after = await conn.FindAll<JsonDocument>(SqliteDb.TableName);
|
||||||
"another");
|
Expect.equal(after.Count, 1, "There should have been one document inserted");
|
||||||
Expect.isNotNull(doc, "There should have been a document returned");
|
|
||||||
Expect.equal(doc!.Id, "two", "The incorrect document was returned");
|
|
||||||
}),
|
|
||||||
TestCase("succeeds when multiple documents are found", async () =>
|
|
||||||
{
|
|
||||||
await using var db = await SqliteDb.BuildDb();
|
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
|
||||||
await LoadDocs();
|
|
||||||
|
|
||||||
var doc = await conn.FindFirstByField<JsonDocument>(SqliteDb.TableName, "Sub.Foo", Op.EQ,
|
|
||||||
"green");
|
|
||||||
Expect.isNotNull(doc, "There should have been a document returned");
|
|
||||||
Expect.contains(new[] { "two", "four" }, doc!.Id, "An incorrect document was returned");
|
|
||||||
}),
|
|
||||||
TestCase("succeeds when a document is not found", async () =>
|
|
||||||
{
|
|
||||||
await using var db = await SqliteDb.BuildDb();
|
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
|
||||||
await LoadDocs();
|
|
||||||
|
|
||||||
var doc = await conn.FindFirstByField<JsonDocument>(SqliteDb.TableName, "Value", Op.EQ,
|
|
||||||
"absent");
|
|
||||||
Expect.isNull(doc, "There should not have been a document returned");
|
|
||||||
})
|
|
||||||
}),
|
}),
|
||||||
TestList("UpdateFull", new[]
|
TestCase("fails for duplicate key", async () =>
|
||||||
{
|
{
|
||||||
TestCase("succeeds when a document is updated", async () =>
|
await using var db = await SqliteDb.BuildDb();
|
||||||
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
|
await conn.Insert(SqliteDb.TableName, new JsonDocument { Id = "test" });
|
||||||
|
try
|
||||||
{
|
{
|
||||||
await using var db = await SqliteDb.BuildDb();
|
await Document.Insert(SqliteDb.TableName, new JsonDocument { Id = "test" });
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
Expect.isTrue(false, "An exception should have been raised for duplicate document ID insert");
|
||||||
await LoadDocs();
|
}
|
||||||
|
catch (Exception)
|
||||||
var testDoc = new JsonDocument { Id = "one", Sub = new() { Foo = "blue", Bar = "red" } };
|
|
||||||
await conn.UpdateFull(SqliteDb.TableName, "one", testDoc);
|
|
||||||
var after = await conn.FindById<string, JsonDocument>(SqliteDb.TableName, "one");
|
|
||||||
Expect.isNotNull(after, "There should have been a document returned post-update");
|
|
||||||
Expect.equal(after.Id, "one", "The updated document is not correct");
|
|
||||||
Expect.isNotNull(after.Sub, "The updated document should have had a sub-document");
|
|
||||||
Expect.equal(after.Sub!.Foo, "blue", "The updated sub-document is not correct");
|
|
||||||
Expect.equal(after.Sub.Bar, "red", "The updated sub-document is not correct");
|
|
||||||
}),
|
|
||||||
TestCase("succeeds when no document is updated", async () =>
|
|
||||||
{
|
{
|
||||||
await using var db = await SqliteDb.BuildDb();
|
// This is what is supposed to happen
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
}
|
||||||
var before = await conn.FindAll<JsonDocument>(SqliteDb.TableName);
|
})
|
||||||
Expect.isEmpty(before, "There should have been no documents returned");
|
}),
|
||||||
|
TestList("Save", new[]
|
||||||
// This not raising an exception is the test
|
{
|
||||||
await conn.UpdateFull(SqliteDb.TableName, "test",
|
TestCase("succeeds when a document is inserted", async () =>
|
||||||
new JsonDocument { Id = "x", Sub = new() { Foo = "blue", Bar = "red" } });
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
TestList("UpdateFullFunc", new[]
|
|
||||||
{
|
{
|
||||||
TestCase("succeeds when a document is updated", async () =>
|
await using var db = await SqliteDb.BuildDb();
|
||||||
{
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
await using var db = await SqliteDb.BuildDb();
|
var before = await conn.FindAll<JsonDocument>(SqliteDb.TableName);
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
Expect.isEmpty(before, "There should be no documents in the table");
|
||||||
await LoadDocs();
|
|
||||||
|
|
||||||
await conn.UpdateFullFunc(SqliteDb.TableName, doc => doc.Id,
|
await conn.Save(SqliteDb.TableName,
|
||||||
new JsonDocument { Id = "one", Value = "le un", NumValue = 1 });
|
new JsonDocument { Id = "test", Sub = new() { Foo = "a", Bar = "b" } });
|
||||||
var after = await conn.FindById<string, JsonDocument>(SqliteDb.TableName, "one");
|
var after = await conn.FindAll<JsonDocument>(SqliteDb.TableName);
|
||||||
Expect.isNotNull(after, "There should have been a document returned post-update");
|
Expect.equal(after.Count, 1, "There should have been one document inserted");
|
||||||
Expect.equal(after.Id, "one", "The updated document is incorrect");
|
|
||||||
Expect.equal(after.Value, "le un", "The updated document is incorrect");
|
|
||||||
Expect.equal(after.NumValue, 1, "The updated document is incorrect");
|
|
||||||
Expect.isNull(after.Sub, "The updated document should not have a sub-document");
|
|
||||||
}),
|
|
||||||
TestCase("succeeds when no document is updated", async () =>
|
|
||||||
{
|
|
||||||
await using var db = await SqliteDb.BuildDb();
|
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
|
||||||
var before = await conn.FindAll<JsonDocument>(SqliteDb.TableName);
|
|
||||||
Expect.isEmpty(before, "There should have been no documents returned");
|
|
||||||
|
|
||||||
// This not raising an exception is the test
|
|
||||||
await conn.UpdateFullFunc(SqliteDb.TableName, doc => doc.Id,
|
|
||||||
new JsonDocument { Id = "one", Value = "le un", NumValue = 1 });
|
|
||||||
})
|
|
||||||
}),
|
}),
|
||||||
TestList("UpdatePartialById", new[]
|
TestCase("succeeds when a document is updated", async () =>
|
||||||
{
|
{
|
||||||
TestCase("succeeds when a document is updated", async () =>
|
await using var db = await SqliteDb.BuildDb();
|
||||||
{
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
await using var db = await SqliteDb.BuildDb();
|
await conn.Insert(SqliteDb.TableName,
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
new JsonDocument { Id = "test", Sub = new() { Foo = "a", Bar = "b" } });
|
||||||
await LoadDocs();
|
|
||||||
|
|
||||||
await conn.UpdatePartialById(SqliteDb.TableName, "one", new { NumValue = 44 });
|
var before = await conn.FindById<string, JsonDocument>(SqliteDb.TableName, "test");
|
||||||
var after = await conn.FindById<string, JsonDocument>(SqliteDb.TableName, "one");
|
Expect.isNotNull(before, "There should have been a document returned");
|
||||||
Expect.isNotNull(after, "There should have been a document returned post-update");
|
Expect.equal(before!.Id, "test", "The document is not correct");
|
||||||
Expect.equal(after.Id, "one", "The updated document is not correct");
|
Expect.isNotNull(before.Sub, "There should have been a sub-document");
|
||||||
Expect.equal(after.NumValue, 44, "The updated document is not correct");
|
Expect.equal(before.Sub!.Foo, "a", "The document is not correct");
|
||||||
}),
|
Expect.equal(before.Sub.Bar, "b", "The document is not correct");
|
||||||
TestCase("succeeds when no document is updated", async () =>
|
|
||||||
{
|
|
||||||
await using var db = await SqliteDb.BuildDb();
|
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
|
||||||
var before = await conn.FindAll<JsonDocument>(SqliteDb.TableName);
|
|
||||||
Expect.isEmpty(before, "There should have been no documents returned");
|
|
||||||
|
|
||||||
// This not raising an exception is the test
|
await conn.Save(SqliteDb.TableName, new JsonDocument { Id = "test" });
|
||||||
await conn.UpdatePartialById(SqliteDb.TableName, "test", new { Foo = "green" });
|
var after = await conn.FindById<string, JsonDocument>(SqliteDb.TableName, "test");
|
||||||
})
|
Expect.isNotNull(after, "There should have been a document returned post-update");
|
||||||
}),
|
Expect.equal(after!.Id, "test", "The updated document is not correct");
|
||||||
TestList("UpdatePartialByField", new[]
|
Expect.isNull(after.Sub, "There should not have been a sub-document in the updated document");
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
TestCase("CountAll succeeds", async () =>
|
||||||
|
{
|
||||||
|
await using var db = await SqliteDb.BuildDb();
|
||||||
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
|
await LoadDocs();
|
||||||
|
|
||||||
|
var theCount = await conn.CountAll(SqliteDb.TableName);
|
||||||
|
Expect.equal(theCount, 5L, "There should have been 5 matching documents");
|
||||||
|
}),
|
||||||
|
TestCase("CountByField succeeds", async () =>
|
||||||
|
{
|
||||||
|
await using var db = await SqliteDb.BuildDb();
|
||||||
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
|
await LoadDocs();
|
||||||
|
|
||||||
|
var theCount = await conn.CountByField(SqliteDb.TableName, "Value", Op.EQ, "purple");
|
||||||
|
Expect.equal(theCount, 2L, "There should have been 2 matching documents");
|
||||||
|
}),
|
||||||
|
TestList("ExistsById", new[]
|
||||||
|
{
|
||||||
|
TestCase("succeeds when a document exists", async () =>
|
||||||
{
|
{
|
||||||
TestCase("succeeds when a document is updated", async () =>
|
await using var db = await SqliteDb.BuildDb();
|
||||||
{
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
await using var db = await SqliteDb.BuildDb();
|
await LoadDocs();
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
|
||||||
await LoadDocs();
|
|
||||||
|
|
||||||
await conn.UpdatePartialByField(SqliteDb.TableName, "Value", Op.EQ, "purple",
|
var exists = await conn.ExistsById(SqliteDb.TableName, "three");
|
||||||
new { NumValue = 77 });
|
Expect.isTrue(exists, "There should have been an existing document");
|
||||||
var after = await conn.CountByField(SqliteDb.TableName, "NumValue", Op.EQ, 77);
|
|
||||||
Expect.equal(after, 2L, "There should have been 2 documents returned");
|
|
||||||
}),
|
|
||||||
TestCase("succeeds when no document is updated", async () =>
|
|
||||||
{
|
|
||||||
await using var db = await SqliteDb.BuildDb();
|
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
|
||||||
var before = await conn.FindAll<JsonDocument>(SqliteDb.TableName);
|
|
||||||
Expect.isEmpty(before, "There should have been no documents returned");
|
|
||||||
|
|
||||||
// This not raising an exception is the test
|
|
||||||
await conn.UpdatePartialByField(SqliteDb.TableName, "Value", Op.EQ, "burgundy",
|
|
||||||
new { Foo = "green" });
|
|
||||||
})
|
|
||||||
}),
|
}),
|
||||||
TestList("DeleteById", new[]
|
TestCase("succeeds when a document does not exist", async () =>
|
||||||
{
|
{
|
||||||
TestCase("succeeds when a document is deleted", async () =>
|
await using var db = await SqliteDb.BuildDb();
|
||||||
{
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
await using var db = await SqliteDb.BuildDb();
|
await LoadDocs();
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
|
||||||
await LoadDocs();
|
|
||||||
|
|
||||||
await conn.DeleteById(SqliteDb.TableName, "four");
|
var exists = await conn.ExistsById(SqliteDb.TableName, "seven");
|
||||||
var remaining = await conn.CountAll(SqliteDb.TableName);
|
Expect.isFalse(exists, "There should not have been an existing document");
|
||||||
Expect.equal(remaining, 4L, "There should have been 4 documents remaining");
|
})
|
||||||
}),
|
}),
|
||||||
TestCase("succeeds when a document is not deleted", async () =>
|
TestList("ExistsByField", new[]
|
||||||
{
|
{
|
||||||
await using var db = await SqliteDb.BuildDb();
|
TestCase("succeeds when documents exist", async () =>
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
|
||||||
await LoadDocs();
|
|
||||||
|
|
||||||
await conn.DeleteById(SqliteDb.TableName, "thirty");
|
|
||||||
var remaining = await conn.CountAll(SqliteDb.TableName);
|
|
||||||
Expect.equal(remaining, 5L, "There should have been 5 documents remaining");
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
TestList("DeleteByField", new[]
|
|
||||||
{
|
{
|
||||||
TestCase("succeeds when documents are deleted", async () =>
|
await using var db = await SqliteDb.BuildDb();
|
||||||
{
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
await using var db = await SqliteDb.BuildDb();
|
await LoadDocs();
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
|
||||||
await LoadDocs();
|
|
||||||
|
|
||||||
await conn.DeleteByField(SqliteDb.TableName, "Value", Op.NE, "purple");
|
var exists = await conn.ExistsByField(SqliteDb.TableName, "NumValue", Op.GE, 10);
|
||||||
var remaining = await conn.CountAll(SqliteDb.TableName);
|
Expect.isTrue(exists, "There should have been existing documents");
|
||||||
Expect.equal(remaining, 2L, "There should have been 2 documents remaining");
|
|
||||||
}),
|
|
||||||
TestCase("succeeds when documents are not deleted", async () =>
|
|
||||||
{
|
|
||||||
await using var db = await SqliteDb.BuildDb();
|
|
||||||
await using var conn = Sqlite.Configuration.DbConn();
|
|
||||||
await LoadDocs();
|
|
||||||
|
|
||||||
await conn.DeleteByField(SqliteDb.TableName, "Value", Op.EQ, "crimson");
|
|
||||||
var remaining = await conn.CountAll(SqliteDb.TableName);
|
|
||||||
Expect.equal(remaining, 5L, "There should have been 5 documents remaining");
|
|
||||||
})
|
|
||||||
}),
|
}),
|
||||||
TestCase("Clean up database", () => Sqlite.Configuration.UseConnectionString("data source=:memory:"))
|
TestCase("succeeds when no matching documents exist", async () =>
|
||||||
});
|
{
|
||||||
|
await using var db = await SqliteDb.BuildDb();
|
||||||
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
|
await LoadDocs();
|
||||||
|
|
||||||
|
var exists = await conn.ExistsByField(SqliteDb.TableName, "Nothing", Op.EQ, "none");
|
||||||
|
Expect.isFalse(exists, "There should not have been any existing documents");
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
TestList("FindAll", new[]
|
||||||
|
{
|
||||||
|
TestCase("succeeds when there is data", async () =>
|
||||||
|
{
|
||||||
|
await using var db = await SqliteDb.BuildDb();
|
||||||
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
|
|
||||||
|
await conn.Insert(SqliteDb.TableName, new JsonDocument { Id = "one", Value = "two" });
|
||||||
|
await conn.Insert(SqliteDb.TableName, new JsonDocument { Id = "three", Value = "four" });
|
||||||
|
await conn.Insert(SqliteDb.TableName, new JsonDocument { Id = "five", Value = "six" });
|
||||||
|
|
||||||
|
var results = await conn.FindAll<JsonDocument>(SqliteDb.TableName);
|
||||||
|
Expect.equal(results.Count, 3, "There should have been 3 documents returned");
|
||||||
|
}),
|
||||||
|
TestCase("succeeds when there is no data", async () =>
|
||||||
|
{
|
||||||
|
await using var db = await SqliteDb.BuildDb();
|
||||||
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
|
var results = await conn.FindAll<JsonDocument>(SqliteDb.TableName);
|
||||||
|
Expect.isEmpty(results, "There should have been no documents returned");
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
TestList("FindById", new[]
|
||||||
|
{
|
||||||
|
TestCase("succeeds when a document is found", async () =>
|
||||||
|
{
|
||||||
|
await using var db = await SqliteDb.BuildDb();
|
||||||
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
|
await LoadDocs();
|
||||||
|
|
||||||
|
var doc = await conn.FindById<string, JsonDocument>(SqliteDb.TableName, "two");
|
||||||
|
Expect.isNotNull(doc, "There should have been a document returned");
|
||||||
|
Expect.equal(doc!.Id, "two", "The incorrect document was returned");
|
||||||
|
}),
|
||||||
|
TestCase("succeeds when a document is not found", async () =>
|
||||||
|
{
|
||||||
|
await using var db = await SqliteDb.BuildDb();
|
||||||
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
|
await LoadDocs();
|
||||||
|
|
||||||
|
var doc = await conn.FindById<string, JsonDocument>(SqliteDb.TableName, "eighty-seven");
|
||||||
|
Expect.isNull(doc, "There should not have been a document returned");
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
TestList("FindByField", new[]
|
||||||
|
{
|
||||||
|
TestCase("succeeds when documents are found", async () =>
|
||||||
|
{
|
||||||
|
await using var db = await SqliteDb.BuildDb();
|
||||||
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
|
await LoadDocs();
|
||||||
|
|
||||||
|
var docs = await conn.FindByField<JsonDocument>(SqliteDb.TableName, "NumValue", Op.GT, 15);
|
||||||
|
Expect.equal(docs.Count, 2, "There should have been two documents returned");
|
||||||
|
}),
|
||||||
|
TestCase("succeeds when documents are not found", async () =>
|
||||||
|
{
|
||||||
|
await using var db = await SqliteDb.BuildDb();
|
||||||
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
|
await LoadDocs();
|
||||||
|
|
||||||
|
var docs = await conn.FindByField<JsonDocument>(SqliteDb.TableName, "Value", Op.EQ, "mauve");
|
||||||
|
Expect.isEmpty(docs, "There should have been no documents returned");
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
TestList("FindFirstByField", new[]
|
||||||
|
{
|
||||||
|
TestCase("succeeds when a document is found", async () =>
|
||||||
|
{
|
||||||
|
await using var db = await SqliteDb.BuildDb();
|
||||||
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
|
await LoadDocs();
|
||||||
|
|
||||||
|
var doc = await conn.FindFirstByField<JsonDocument>(SqliteDb.TableName, "Value", Op.EQ, "another");
|
||||||
|
Expect.isNotNull(doc, "There should have been a document returned");
|
||||||
|
Expect.equal(doc!.Id, "two", "The incorrect document was returned");
|
||||||
|
}),
|
||||||
|
TestCase("succeeds when multiple documents are found", async () =>
|
||||||
|
{
|
||||||
|
await using var db = await SqliteDb.BuildDb();
|
||||||
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
|
await LoadDocs();
|
||||||
|
|
||||||
|
var doc = await conn.FindFirstByField<JsonDocument>(SqliteDb.TableName, "Sub.Foo", Op.EQ, "green");
|
||||||
|
Expect.isNotNull(doc, "There should have been a document returned");
|
||||||
|
Expect.contains(new[] { "two", "four" }, doc!.Id, "An incorrect document was returned");
|
||||||
|
}),
|
||||||
|
TestCase("succeeds when a document is not found", async () =>
|
||||||
|
{
|
||||||
|
await using var db = await SqliteDb.BuildDb();
|
||||||
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
|
await LoadDocs();
|
||||||
|
|
||||||
|
var doc = await conn.FindFirstByField<JsonDocument>(SqliteDb.TableName, "Value", Op.EQ, "absent");
|
||||||
|
Expect.isNull(doc, "There should not have been a document returned");
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
TestList("UpdateFull", new[]
|
||||||
|
{
|
||||||
|
TestCase("succeeds when a document is updated", async () =>
|
||||||
|
{
|
||||||
|
await using var db = await SqliteDb.BuildDb();
|
||||||
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
|
await LoadDocs();
|
||||||
|
|
||||||
|
var testDoc = new JsonDocument { Id = "one", Sub = new() { Foo = "blue", Bar = "red" } };
|
||||||
|
await conn.UpdateFull(SqliteDb.TableName, "one", testDoc);
|
||||||
|
var after = await conn.FindById<string, JsonDocument>(SqliteDb.TableName, "one");
|
||||||
|
Expect.isNotNull(after, "There should have been a document returned post-update");
|
||||||
|
Expect.equal(after.Id, "one", "The updated document is not correct");
|
||||||
|
Expect.isNotNull(after.Sub, "The updated document should have had a sub-document");
|
||||||
|
Expect.equal(after.Sub!.Foo, "blue", "The updated sub-document is not correct");
|
||||||
|
Expect.equal(after.Sub.Bar, "red", "The updated sub-document is not correct");
|
||||||
|
}),
|
||||||
|
TestCase("succeeds when no document is updated", async () =>
|
||||||
|
{
|
||||||
|
await using var db = await SqliteDb.BuildDb();
|
||||||
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
|
var before = await conn.FindAll<JsonDocument>(SqliteDb.TableName);
|
||||||
|
Expect.isEmpty(before, "There should have been no documents returned");
|
||||||
|
|
||||||
|
// This not raising an exception is the test
|
||||||
|
await conn.UpdateFull(SqliteDb.TableName, "test",
|
||||||
|
new JsonDocument { Id = "x", Sub = new() { Foo = "blue", Bar = "red" } });
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
TestList("UpdateFullFunc", new[]
|
||||||
|
{
|
||||||
|
TestCase("succeeds when a document is updated", async () =>
|
||||||
|
{
|
||||||
|
await using var db = await SqliteDb.BuildDb();
|
||||||
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
|
await LoadDocs();
|
||||||
|
|
||||||
|
await conn.UpdateFullFunc(SqliteDb.TableName, doc => doc.Id,
|
||||||
|
new JsonDocument { Id = "one", Value = "le un", NumValue = 1 });
|
||||||
|
var after = await conn.FindById<string, JsonDocument>(SqliteDb.TableName, "one");
|
||||||
|
Expect.isNotNull(after, "There should have been a document returned post-update");
|
||||||
|
Expect.equal(after.Id, "one", "The updated document is incorrect");
|
||||||
|
Expect.equal(after.Value, "le un", "The updated document is incorrect");
|
||||||
|
Expect.equal(after.NumValue, 1, "The updated document is incorrect");
|
||||||
|
Expect.isNull(after.Sub, "The updated document should not have a sub-document");
|
||||||
|
}),
|
||||||
|
TestCase("succeeds when no document is updated", async () =>
|
||||||
|
{
|
||||||
|
await using var db = await SqliteDb.BuildDb();
|
||||||
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
|
var before = await conn.FindAll<JsonDocument>(SqliteDb.TableName);
|
||||||
|
Expect.isEmpty(before, "There should have been no documents returned");
|
||||||
|
|
||||||
|
// This not raising an exception is the test
|
||||||
|
await conn.UpdateFullFunc(SqliteDb.TableName, doc => doc.Id,
|
||||||
|
new JsonDocument { Id = "one", Value = "le un", NumValue = 1 });
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
TestList("UpdatePartialById", new[]
|
||||||
|
{
|
||||||
|
TestCase("succeeds when a document is updated", async () =>
|
||||||
|
{
|
||||||
|
await using var db = await SqliteDb.BuildDb();
|
||||||
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
|
await LoadDocs();
|
||||||
|
|
||||||
|
await conn.UpdatePartialById(SqliteDb.TableName, "one", new { NumValue = 44 });
|
||||||
|
var after = await conn.FindById<string, JsonDocument>(SqliteDb.TableName, "one");
|
||||||
|
Expect.isNotNull(after, "There should have been a document returned post-update");
|
||||||
|
Expect.equal(after.Id, "one", "The updated document is not correct");
|
||||||
|
Expect.equal(after.NumValue, 44, "The updated document is not correct");
|
||||||
|
}),
|
||||||
|
TestCase("succeeds when no document is updated", async () =>
|
||||||
|
{
|
||||||
|
await using var db = await SqliteDb.BuildDb();
|
||||||
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
|
var before = await conn.FindAll<JsonDocument>(SqliteDb.TableName);
|
||||||
|
Expect.isEmpty(before, "There should have been no documents returned");
|
||||||
|
|
||||||
|
// This not raising an exception is the test
|
||||||
|
await conn.UpdatePartialById(SqliteDb.TableName, "test", new { Foo = "green" });
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
TestList("UpdatePartialByField", new[]
|
||||||
|
{
|
||||||
|
TestCase("succeeds when a document is updated", async () =>
|
||||||
|
{
|
||||||
|
await using var db = await SqliteDb.BuildDb();
|
||||||
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
|
await LoadDocs();
|
||||||
|
|
||||||
|
await conn.UpdatePartialByField(SqliteDb.TableName, "Value", Op.EQ, "purple", new { NumValue = 77 });
|
||||||
|
var after = await conn.CountByField(SqliteDb.TableName, "NumValue", Op.EQ, 77);
|
||||||
|
Expect.equal(after, 2L, "There should have been 2 documents returned");
|
||||||
|
}),
|
||||||
|
TestCase("succeeds when no document is updated", async () =>
|
||||||
|
{
|
||||||
|
await using var db = await SqliteDb.BuildDb();
|
||||||
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
|
var before = await conn.FindAll<JsonDocument>(SqliteDb.TableName);
|
||||||
|
Expect.isEmpty(before, "There should have been no documents returned");
|
||||||
|
|
||||||
|
// This not raising an exception is the test
|
||||||
|
await conn.UpdatePartialByField(SqliteDb.TableName, "Value", Op.EQ, "burgundy", new { Foo = "green" });
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
TestList("DeleteById", new[]
|
||||||
|
{
|
||||||
|
TestCase("succeeds when a document is deleted", async () =>
|
||||||
|
{
|
||||||
|
await using var db = await SqliteDb.BuildDb();
|
||||||
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
|
await LoadDocs();
|
||||||
|
|
||||||
|
await conn.DeleteById(SqliteDb.TableName, "four");
|
||||||
|
var remaining = await conn.CountAll(SqliteDb.TableName);
|
||||||
|
Expect.equal(remaining, 4L, "There should have been 4 documents remaining");
|
||||||
|
}),
|
||||||
|
TestCase("succeeds when a document is not deleted", async () =>
|
||||||
|
{
|
||||||
|
await using var db = await SqliteDb.BuildDb();
|
||||||
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
|
await LoadDocs();
|
||||||
|
|
||||||
|
await conn.DeleteById(SqliteDb.TableName, "thirty");
|
||||||
|
var remaining = await conn.CountAll(SqliteDb.TableName);
|
||||||
|
Expect.equal(remaining, 5L, "There should have been 5 documents remaining");
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
TestList("DeleteByField", new[]
|
||||||
|
{
|
||||||
|
TestCase("succeeds when documents are deleted", async () =>
|
||||||
|
{
|
||||||
|
await using var db = await SqliteDb.BuildDb();
|
||||||
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
|
await LoadDocs();
|
||||||
|
|
||||||
|
await conn.DeleteByField(SqliteDb.TableName, "Value", Op.NE, "purple");
|
||||||
|
var remaining = await conn.CountAll(SqliteDb.TableName);
|
||||||
|
Expect.equal(remaining, 2L, "There should have been 2 documents remaining");
|
||||||
|
}),
|
||||||
|
TestCase("succeeds when documents are not deleted", async () =>
|
||||||
|
{
|
||||||
|
await using var db = await SqliteDb.BuildDb();
|
||||||
|
await using var conn = Sqlite.Configuration.DbConn();
|
||||||
|
await LoadDocs();
|
||||||
|
|
||||||
|
await conn.DeleteByField(SqliteDb.TableName, "Value", Op.EQ, "crimson");
|
||||||
|
var remaining = await conn.CountAll(SqliteDb.TableName);
|
||||||
|
Expect.equal(remaining, 5L, "There should have been 5 documents remaining");
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
TestCase("Clean up database", () => Sqlite.Configuration.UseConnectionString("data source=:memory:"))
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -39,15 +39,15 @@ let unitTests =
|
||||||
$"CREATE TABLE IF NOT EXISTS {PostgresDb.TableName} (data JSONB NOT NULL)"
|
$"CREATE TABLE IF NOT EXISTS {PostgresDb.TableName} (data JSONB NOT NULL)"
|
||||||
"CREATE TABLE statement not constructed correctly"
|
"CREATE TABLE statement not constructed correctly"
|
||||||
}
|
}
|
||||||
test "ensureJsonIndex succeeds for full index" {
|
test "ensureDocumentIndex succeeds for full index" {
|
||||||
Expect.equal
|
Expect.equal
|
||||||
(Query.Definition.ensureJsonIndex "schema.tbl" Full)
|
(Query.Definition.ensureDocumentIndex "schema.tbl" Full)
|
||||||
"CREATE INDEX IF NOT EXISTS idx_tbl_document ON schema.tbl USING GIN (data)"
|
"CREATE INDEX IF NOT EXISTS idx_tbl_document ON schema.tbl USING GIN (data)"
|
||||||
"CREATE INDEX statement not constructed correctly"
|
"CREATE INDEX statement not constructed correctly"
|
||||||
}
|
}
|
||||||
test "ensureJsonIndex succeeds for JSONB Path Ops index" {
|
test "ensureDocumentIndex succeeds for JSONB Path Ops index" {
|
||||||
Expect.equal
|
Expect.equal
|
||||||
(Query.Definition.ensureJsonIndex PostgresDb.TableName Optimized)
|
(Query.Definition.ensureDocumentIndex PostgresDb.TableName Optimized)
|
||||||
(sprintf "CREATE INDEX IF NOT EXISTS idx_%s_document ON %s USING GIN (data jsonb_path_ops)"
|
(sprintf "CREATE INDEX IF NOT EXISTS idx_%s_document ON %s USING GIN (data jsonb_path_ops)"
|
||||||
PostgresDb.TableName PostgresDb.TableName)
|
PostgresDb.TableName PostgresDb.TableName)
|
||||||
"CREATE INDEX statement not constructed correctly"
|
"CREATE INDEX statement not constructed correctly"
|
||||||
|
@ -266,7 +266,7 @@ 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 "ensureJsonIndex succeeds" {
|
testTask "ensureDocumentIndex succeeds" {
|
||||||
use db = PostgresDb.BuildDb()
|
use db = PostgresDb.BuildDb()
|
||||||
let indexExists () =
|
let indexExists () =
|
||||||
Custom.scalar
|
Custom.scalar
|
||||||
|
@ -277,8 +277,8 @@ let integrationTests =
|
||||||
let! exists = indexExists ()
|
let! exists = indexExists ()
|
||||||
Expect.isFalse exists "The index should not exist already"
|
Expect.isFalse exists "The index should not exist already"
|
||||||
|
|
||||||
do! Definition.ensureTable "ensured"
|
do! Definition.ensureTable "ensured"
|
||||||
do! Definition.ensureJsonIndex "ensured" Optimized
|
do! Definition.ensureDocumentIndex "ensured" Optimized
|
||||||
let! exists' = indexExists ()
|
let! exists' = indexExists ()
|
||||||
Expect.isTrue exists' "The index should now exist"
|
Expect.isTrue exists' "The index should now exist"
|
||||||
}
|
}
|
||||||
|
@ -730,7 +730,7 @@ let integrationTests =
|
||||||
Expect.equal before 0 "There should have been no documents returned"
|
Expect.equal before 0 "There should have been no documents returned"
|
||||||
|
|
||||||
// This not raising an exception is the test
|
// This not raising an exception is the test
|
||||||
do! Update.partialByContains PostgresDb.TableName {| Value = "burgundy" |} {| Foo = "green" |}
|
do! Update.partialByJsonPath PostgresDb.TableName "$.NumValue ? (@ < 0)" {| Foo = "green" |}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user