fix(localdb): Task 4 review fixes — synchronous allow-list, dictionary params, async conn setup, dispose guard
This commit is contained in:
@@ -82,6 +82,80 @@ public sealed class SqliteLocalDbTests : IDisposable
|
||||
Assert.Equal(new[] { 1L }, ids);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Transaction_DisposeWithoutCommit_RollsBack()
|
||||
{
|
||||
using var db = Create();
|
||||
await db.ExecuteAsync("CREATE TABLE t (id INTEGER PRIMARY KEY)");
|
||||
|
||||
await using (var tx = await db.BeginTransactionAsync())
|
||||
{
|
||||
await tx.ExecuteAsync("INSERT INTO t (id) VALUES (@id)", new { id = 1 });
|
||||
}
|
||||
|
||||
var count = await db.QueryAsync("SELECT COUNT(*) FROM t", r => r.GetInt64(0));
|
||||
Assert.Equal(0L, count[0]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Bind_GuidByteArrayAndNull_RoundTrip()
|
||||
{
|
||||
using var db = Create();
|
||||
await db.ExecuteAsync("CREATE TABLE t (id INTEGER PRIMARY KEY, g TEXT, blob BLOB, missing TEXT)");
|
||||
|
||||
var guid = Guid.NewGuid();
|
||||
var bytes = new byte[] { 1, 2, 3 };
|
||||
await db.ExecuteAsync(
|
||||
"INSERT INTO t (id, g, blob, missing) VALUES (@id, @g, @blob, @missing)",
|
||||
new { id = 1, g = guid, blob = bytes, missing = (string?)null });
|
||||
|
||||
var rows = await db.QueryAsync(
|
||||
"SELECT g, blob, missing FROM t WHERE id = 1",
|
||||
r => (Guid: r.GetGuid(0), Blob: (byte[])r.GetValue(1), MissingIsNull: r.IsDBNull(2)));
|
||||
|
||||
Assert.Equal(guid, rows[0].Guid);
|
||||
Assert.Equal(bytes, rows[0].Blob);
|
||||
Assert.True(rows[0].MissingIsNull);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Bind_DictionaryParameters_BindByKey()
|
||||
{
|
||||
using var db = Create();
|
||||
await db.ExecuteAsync("CREATE TABLE t (id INTEGER PRIMARY KEY, name TEXT)");
|
||||
|
||||
var parameters = new Dictionary<string, object?> { ["id"] = 7, ["name"] = null };
|
||||
await db.ExecuteAsync("INSERT INTO t (id, name) VALUES (@id, @name)", parameters);
|
||||
|
||||
var rows = await db.QueryAsync(
|
||||
"SELECT id, name FROM t",
|
||||
r => (Id: r.GetInt64(0), NameIsNull: r.IsDBNull(1)));
|
||||
|
||||
Assert.Equal(7L, rows[0].Id);
|
||||
Assert.True(rows[0].NameIsNull);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Ctor_EmptyPath_Throws()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => new SqliteLocalDb(new LocalDbOptions { Path = " " }));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Ctor_InvalidSynchronous_Throws()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() =>
|
||||
new SqliteLocalDb(new LocalDbOptions { Path = _path, Synchronous = "NORMAL; PRAGMA foreign_keys=OFF" }));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Dispose_IsIdempotent()
|
||||
{
|
||||
var db = Create();
|
||||
db.Dispose();
|
||||
db.Dispose();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HlcUdf_RegisteredOnConnection()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user