aboutsummaryrefslogtreecommitdiffhomepage
path: root/sundry/spine_search_cgi/src/ext_depends_cgi/d2sqlite3/source/tests.d
diff options
context:
space:
mode:
Diffstat (limited to 'sundry/spine_search_cgi/src/ext_depends_cgi/d2sqlite3/source/tests.d')
-rw-r--r--sundry/spine_search_cgi/src/ext_depends_cgi/d2sqlite3/source/tests.d931
1 files changed, 0 insertions, 931 deletions
diff --git a/sundry/spine_search_cgi/src/ext_depends_cgi/d2sqlite3/source/tests.d b/sundry/spine_search_cgi/src/ext_depends_cgi/d2sqlite3/source/tests.d
deleted file mode 100644
index ff20af1..0000000
--- a/sundry/spine_search_cgi/src/ext_depends_cgi/d2sqlite3/source/tests.d
+++ /dev/null
@@ -1,931 +0,0 @@
-module tests.d;
-
-version (unittest):
-
-import d2sqlite3;
-import std.algorithm;
-import std.exception : assertThrown, assertNotThrown;
-import std.string : format;
-import std.typecons : Nullable;
-import std.conv : hexString;
-
-unittest // Test version of SQLite library
-{
- import std.string : startsWith;
- assert(versionString.startsWith("3."));
- assert(versionNumber >= 3_008_007);
-}
-
-unittest // COV
-{
- auto ts = threadSafe;
-}
-
-unittest // Configuration logging and db.close()
-{
- static extern (C) void loggerCallback(void* arg, int code, const(char)* msg) nothrow
- {
- ++*(cast(int*) arg);
- }
-
- int marker = 42;
-
- shutdown();
- config(SQLITE_CONFIG_MULTITHREAD);
- config(SQLITE_CONFIG_LOG, &loggerCallback, &marker);
- initialize();
-
- {
- auto db = Database(":memory:");
- try
- {
- db.run("DROP TABLE wtf");
- }
- catch (Exception e)
- {
- }
- db.close();
- }
- assert(marker == 43);
-
- shutdown();
- config(SQLITE_CONFIG_LOG, null, null);
- initialize();
-
- {
- auto db = Database(":memory:");
- try
- {
- db.run("DROP TABLE wtf");
- }
- catch (Exception e)
- {
- }
- }
- assert(marker == 43);
-}
-
-unittest // Database.tableColumnMetadata()
-{
- auto db = Database(":memory:");
- db.run("CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT,
- val FLOAT NOT NULL)");
- assert(db.tableColumnMetadata("test", "id") ==
- TableColumnMetadata("INTEGER", "BINARY", false, true, true));
- assert(db.tableColumnMetadata("test", "val") ==
- TableColumnMetadata("FLOAT", "BINARY", true, false, false));
-}
-
-unittest // Database.run()
-{
- auto db = Database(":memory:");
- int i;
- db.run(`SELECT 1; SELECT 2;`, (ResultRange r) { i = r.oneValue!int; return false; });
- assert(i == 1);
-}
-
-unittest // Database.errorCode()
-{
- auto db = Database(":memory:");
- db.run(`SELECT 1;`);
- assert(db.errorCode == SQLITE_OK);
- try
- db.run(`DROP TABLE non_existent`);
- catch (SqliteException e)
- assert(db.errorCode == SQLITE_ERROR);
-}
-
-unittest // Database.config
-{
- auto db = Database(":memory:");
- db.run(`
- CREATE TABLE test (val INTEGER);
- CREATE TRIGGER test_trig BEFORE INSERT ON test
- BEGIN
- SELECT RAISE(FAIL, 'Test failed');
- END;
- `);
- int res = 42;
- db.config(SQLITE_DBCONFIG_ENABLE_TRIGGER, 0, &res);
- assert(res == 0);
- db.execute("INSERT INTO test (val) VALUES (1)");
-}
-
-unittest // Database.createFunction(ColumnData[]...)
-{
- string myList(ColumnData[] args...)
- {
- import std.array : appender;
- import std.string : format, join;
-
- auto app = appender!(string[]);
- foreach (arg; args)
- {
- if (arg.type == SqliteType.TEXT)
- app.put(`"%s"`.format(arg));
- else
- app.put("%s".format(arg));
- }
- return app.data.join(", ");
- }
- auto db = Database(":memory:");
- db.createFunction("my_list", &myList);
- auto list = db.execute("SELECT my_list(42, 3.14, 'text', x'00FF', NULL)").oneValue!string;
- assert(list == `42, 3.14, "text", [0, 255], null`, list);
-}
-
-unittest // Database.createFunction() exceptions
-{
- import std.exception : assertThrown;
-
- int myFun(int a, int b = 1)
- {
- return a * b;
- }
-
- auto db = Database(":memory:");
- db.createFunction("myFun", &myFun);
- assertThrown!SqliteException(db.execute("SELECT myFun()"));
- assertThrown!SqliteException(db.execute("SELECT myFun(1, 2, 3)"));
- assert(db.execute("SELECT myFun(5)").oneValue!int == 5);
- assert(db.execute("SELECT myFun(5, 2)").oneValue!int == 10);
-
- db.createFunction("myFun", null);
- assertThrown!SqliteException(db.execute("SELECT myFun(5)"));
- assertThrown!SqliteException(db.execute("SELECT myFun(5, 2)"));
-}
-
-unittest // Database.setUpdateHook()
-{
- int i;
- auto db = Database(":memory:");
- db.setUpdateHook((int type, string dbName, string tableName, long rowid) {
- assert(type == SQLITE_INSERT);
- assert(dbName == "main");
- assert(tableName == "test");
- assert(rowid == 1);
- i = 42;
- });
- db.run("CREATE TABLE test (val INTEGER);
- INSERT INTO test VALUES (100)");
- assert(i == 42);
- db.setUpdateHook(null);
-}
-
-unittest // Database commit and rollback hooks
-{
- int i;
- auto db = Database(":memory:");
- db.setCommitHook({ i = 42; return SQLITE_OK; });
- db.setRollbackHook({ i = 666; });
- db.begin();
- db.execute("CREATE TABLE test (val INTEGER)");
- db.rollback();
- assert(i == 666);
- db.begin();
- db.execute("CREATE TABLE test (val INTEGER)");
- db.commit();
- assert(i == 42);
- db.setCommitHook(null);
- db.setRollbackHook(null);
-}
-
-unittest // Miscellaneous functions
-{
- auto db = Database(":memory:");
- assert(db.attachedFilePath("main") is null);
- assert(!db.isReadOnly);
- db.close();
-}
-
-unittest // Execute an SQL statement
-{
- auto db = Database(":memory:");
- db.run("");
- db.run("-- This is a comment!");
- db.run(";");
- db.run("ANALYZE; VACUUM;");
-}
-
-unittest // Unexpected multiple statements
-{
- auto db = Database(":memory:");
- db.execute("BEGIN; CREATE TABLE test (val INTEGER); ROLLBACK;");
- assertThrown(db.execute("DROP TABLE test"));
-
- db.execute("CREATE TABLE test (val INTEGER); DROP TABLE test;");
- assertNotThrown(db.execute("DROP TABLE test"));
-
- db.execute("SELECT 1; CREATE TABLE test (val INTEGER); DROP TABLE test;");
- assertThrown(db.execute("DROP TABLE test"));
-}
-
-unittest // Multiple statements with callback
-{
- import std.array : appender;
- auto db = Database(":memory:");
- auto test = appender!string;
- db.run("SELECT 1, 2, 3; SELECT 'A', 'B', 'C';", (ResultRange r) {
- foreach (col; r.front)
- test.put(col.as!string);
- return true;
- });
- assert(test.data == "123ABC");
-}
-
-unittest // Different arguments and result types with createFunction
-{
- auto db = Database(":memory:");
-
- T display(T)(T value)
- {
- return value;
- }
-
- db.createFunction("display_integer", &display!int);
- db.createFunction("display_float", &display!double);
- db.createFunction("display_text", &display!string);
- db.createFunction("display_blob", &display!Blob);
-
- assert(db.execute("SELECT display_integer(42)").oneValue!int == 42);
- assert(db.execute("SELECT display_float(3.14)").oneValue!double == 3.14);
- assert(db.execute("SELECT display_text('ABC')").oneValue!string == "ABC");
- assert(db.execute("SELECT display_blob(x'ABCD')").oneValue!Blob == cast(Blob) hexString!"ABCD");
-
- assert(db.execute("SELECT display_integer(NULL)").oneValue!int == 0);
- assert(db.execute("SELECT display_float(NULL)").oneValue!double == 0.0);
- assert(db.execute("SELECT display_text(NULL)").oneValue!string is null);
- assert(db.execute("SELECT display_blob(NULL)").oneValue!(Blob) is null);
-}
-
-unittest // Different Nullable argument types with createFunction
-{
- auto db = Database(":memory:");
-
- auto display(T : Nullable!U, U...)(T value)
- {
- if (value.isNull)
- return T.init;
- return value;
- }
-
- db.createFunction("display_integer", &display!(Nullable!int));
- db.createFunction("display_float", &display!(Nullable!double));
- db.createFunction("display_text", &display!(Nullable!string));
- db.createFunction("display_blob", &display!(Nullable!Blob));
-
- assert(db.execute("SELECT display_integer(42)").oneValue!(Nullable!int) == 42);
- assert(db.execute("SELECT display_float(3.14)").oneValue!(Nullable!double) == 3.14);
- assert(db.execute("SELECT display_text('ABC')").oneValue!(Nullable!string) == "ABC");
- assert(db.execute("SELECT display_blob(x'ABCD')").oneValue!(Nullable!Blob) == cast(Blob) hexString!"ABCD");
-
- assert(db.execute("SELECT display_integer(NULL)").oneValue!(Nullable!int).isNull);
- assert(db.execute("SELECT display_float(NULL)").oneValue!(Nullable!double).isNull);
- assert(db.execute("SELECT display_text(NULL)").oneValue!(Nullable!string).isNull);
- assert(db.execute("SELECT display_blob(NULL)").oneValue!(Nullable!Blob).isNull);
-}
-
-unittest // Callable struct with createFunction
-{
- import std.functional : toDelegate;
-
- struct Fun
- {
- int factor;
-
- this(int factor)
- {
- this.factor = factor;
- }
-
- int opCall(int value)
- {
- return value * factor;
- }
- }
-
- auto f = Fun(2);
- auto db = Database(":memory:");
- db.createFunction("my_fun", toDelegate(f));
- assert(db.execute("SELECT my_fun(4)").oneValue!int == 8);
-}
-
-unittest // Callbacks
-{
- bool wasTraced = false;
- bool wasProfiled = false;
- bool hasProgressed = false;
-
- auto db = Database(":memory:");
- db.setTraceCallback((string s) { wasTraced = true; });
- db.execute("SELECT * FROM sqlite_master;");
- assert(wasTraced);
- db.setProfileCallback((string s, ulong t) { wasProfiled = true; });
- db.execute("SELECT * FROM sqlite_master;");
- assert(wasProfiled);
-
- db.setProgressHandler(1, { hasProgressed = true; return 0; });
- db.execute("SELECT * FROM sqlite_master;");
- assert(hasProgressed);
-}
-
-unittest // Statement.oneValue()
-{
- Statement statement;
- {
- auto db = Database(":memory:");
- statement = db.prepare(" SELECT 42 ");
- }
- assert(statement.execute.oneValue!int == 42);
-}
-
-unittest // Statement.finalize()
-{
- auto db = Database(":memory:");
- auto statement = db.prepare(" SELECT 42 ");
- statement.finalize();
-}
-
-unittest // Simple parameters binding
-{
- auto db = Database(":memory:");
- db.execute("CREATE TABLE test (val INTEGER)");
-
- auto statement = db.prepare("INSERT INTO test (val) VALUES (?)");
- statement.bind(1, 36);
- statement.clearBindings();
- statement.bind(1, 42);
- statement.execute();
- statement.reset();
- statement.bind(1, 42);
- statement.execute();
-
- assert(db.lastInsertRowid == 2);
- assert(db.changes == 1);
- assert(db.totalChanges == 2);
-
- auto results = db.execute("SELECT * FROM test");
- foreach (row; results)
- assert(row.peek!int(0) == 42);
-}
-
-unittest // Multiple parameters binding
-{
- auto db = Database(":memory:");
- db.execute("CREATE TABLE test (i INTEGER, f FLOAT, t TEXT)");
- auto statement = db.prepare("INSERT INTO test (i, f, t) VALUES (:i, @f, $t)");
-
- assert(statement.parameterCount == 3);
- assert(statement.parameterName(2) == "@f");
- assert(statement.parameterIndex("$t") == 3);
- assert(statement.parameterIndex(":foo") == 0);
-
- statement.bind("$t", "TEXT");
- statement.bind(":i", 42);
- statement.bind("@f", 3.14);
- statement.execute();
- statement.reset();
- statement.bind(1, 42);
- statement.bind(2, 3.14);
- statement.bind(3, "TEXT");
- statement.execute();
-
- auto results = db.execute("SELECT * FROM test");
- foreach (row; results)
- {
- assert(row.length == 3);
- assert(row.peek!int("i") == 42);
- assert(row.peek!double("f") == 3.14);
- assert(row.peek!string("t") == "TEXT");
- }
-}
-
-// Binding/peeking structs with `toString` and `fromString`
-unittest
-{
- auto db = Database(":memory:");
- db.execute("CREATE TABLE test (val TEXT)");
-
- static struct ToStringSink {
- string value;
- void toString(scope void delegate(in char[]) sink) const
- {
- sink(this.value);
- }
- }
-
- static struct ToStringMethod {
- string value;
- string toString() const
- {
- return this.value;
- }
- }
-
- auto statement = db.prepare("INSERT INTO test (val) VALUES (?)");
- statement.bind(1, ToStringMethod("oldmethod"));
- statement.clearBindings();
- statement.bind(1, ToStringMethod("method"));
- statement.execute();
- statement.reset();
- statement.bind(1, ToStringSink("sink"));
- statement.execute();
-
- assert(db.lastInsertRowid == 2);
- assert(db.changes == 1);
- assert(db.totalChanges == 2);
-
- auto results = db.execute("SELECT * FROM test");
- results.equal!((a, b) => a.peek!string(0) == b)(["method", "sink"]);
-}
-
-unittest // Multiple parameters binding: tuples
-{
- auto db = Database(":memory:");
- db.execute("CREATE TABLE test (i INTEGER, f FLOAT, t TEXT)");
- auto statement = db.prepare("INSERT INTO test (i, f, t) VALUES (?, ?, ?)");
- statement.bindAll(42, 3.14, "TEXT");
- statement.execute();
-
- auto results = db.execute("SELECT * FROM test");
- foreach (row; results)
- {
- assert(row.length == 3);
- assert(row.peek!int(0) == 42);
- assert(row.peek!double(1) == 3.14);
- assert(row.peek!string(2) == "TEXT");
- }
-}
-
-unittest // Binding/peeking integral values
-{
- auto db = Database(":memory:");
- db.run("CREATE TABLE test (val INTEGER)");
-
- auto statement = db.prepare("INSERT INTO test (val) VALUES (?)");
- statement.inject(cast(byte) 42);
- statement.inject(42U);
- statement.inject(42UL);
- statement.inject('\x2A');
-
- auto results = db.execute("SELECT * FROM test");
- foreach (row; results)
- assert(row.peek!long(0) == 42);
-}
-
-void foobar() // Binding/peeking floating point values
-{
- auto db = Database(":memory:");
- db.run("CREATE TABLE test (val FLOAT)");
-
- auto statement = db.prepare("INSERT INTO test (val) VALUES (?)");
- statement.inject(42.0F);
- statement.inject(42.0);
- statement.inject(42.0L);
- statement.inject("42");
-
- auto results = db.execute("SELECT * FROM test");
- foreach (row; results)
- assert(row.peek!double(0) == 42.0);
-}
-
-unittest // Binding/peeking text values
-{
- auto db = Database(":memory:");
- db.run("CREATE TABLE test (val TEXT);
- INSERT INTO test (val) VALUES ('I am a text.')");
-
- auto results = db.execute("SELECT * FROM test");
- assert(results.front.peek!(string, PeekMode.slice)(0) == "I am a text.");
- assert(results.front.peek!(string, PeekMode.copy)(0) == "I am a text.");
-
- import std.exception : assertThrown;
- import std.variant : VariantException;
- assertThrown!VariantException(results.front[0].as!Blob);
-}
-
-unittest // Binding/peeking blob values
-{
- auto db = Database(":memory:");
- db.execute("CREATE TABLE test (val BLOB)");
-
- auto statement = db.prepare("INSERT INTO test (val) VALUES (?)");
- auto array = cast(Blob) [1, 2, 3];
- statement.inject(array);
- ubyte[3] sarray = [1, 2, 3];
- statement.inject(sarray);
-
- auto results = db.execute("SELECT * FROM test");
- foreach (row; results)
- {
- assert(row.peek!(Blob, PeekMode.slice)(0) == [1, 2, 3]);
- assert(row[0].as!Blob == [1, 2, 3]);
- }
-}
-
-unittest // Struct injecting
-{
- static struct Test
- {
- int i;
- double f;
- string t;
- }
-
- auto db = Database(":memory:");
- db.execute("CREATE TABLE test (i INTEGER, f FLOAT, t TEXT)");
- auto statement = db.prepare("INSERT INTO test (i, f, t) VALUES (?, ?, ?)");
- auto test = Test(42, 3.14, "TEXT");
- statement.inject(test);
- statement.inject(Test(42, 3.14, "TEXT"));
- auto itest = cast(immutable) Test(42, 3.14, "TEXT");
- statement.inject(itest);
-
- auto results = db.execute("SELECT * FROM test");
- assert(!results.empty);
- foreach (row; results)
- {
- assert(row.length == 3);
- assert(row.peek!int(0) == 42);
- assert(row.peek!double(1) == 3.14);
- assert(row.peek!string(2) == "TEXT");
- }
-}
-
-unittest // Iterable struct injecting
-{
- import std.range : iota;
-
- auto db = Database(":memory:");
- db.execute("CREATE TABLE test (a INTEGER, b INTEGER, c INTEGER)");
- auto statement = db.prepare("INSERT INTO test (a, b, c) VALUES (?, ?, ?)");
- statement.inject(iota(0, 3));
-
- auto results = db.execute("SELECT * FROM test");
- assert(!results.empty);
- foreach (row; results)
- {
- assert(row.length == 3);
- assert(row.peek!int(0) == 0);
- assert(row.peek!int(1) == 1);
- assert(row.peek!int(2) == 2);
- }
-}
-
-unittest // Injecting nullable
-{
- import std.array : array;
-
- auto db = Database(":memory:");
- db.execute("CREATE TABLE test (i INTEGER, s TEXT)");
- auto statement = db.prepare("INSERT INTO test (i, s) VALUES (?, ?)");
- statement.inject(Nullable!int(1), "one");
- statement = db.prepare("INSERT INTO test (i) VALUES (?)");
- statement.inject(Nullable!int.init);
-
- auto results = db.execute("SELECT i FROM test ORDER BY rowid");
- assert(results.equal!((a, b) => a.peek!(Nullable!int)(0) == b)(
- [ Nullable!int(1), Nullable!int.init ] ));
-}
-
-unittest // Injecting tuple
-{
- import std.typecons : tuple;
-
- auto db = Database(":memory:");
- db.execute("CREATE TABLE test (i INTEGER, f FLOAT, t TEXT)");
- auto statement = db.prepare("INSERT INTO test (i, f, t) VALUES (?, ?, ?)");
- statement.inject(tuple(42, 3.14, "TEXT"));
-
- auto results = db.execute("SELECT * FROM test");
- foreach (row; results)
- {
- assert(row.length == 3);
- assert(row.peek!int(0) == 42);
- assert(row.peek!double(1) == 3.14);
- assert(row.peek!string(2) == "TEXT");
- }
-}
-
-unittest // Injecting dict
-{
- auto db = Database(":memory:");
- db.execute("CREATE TABLE test (a TEXT, b TEXT, c TEXT)");
- auto statement = db.prepare("INSERT INTO test (c, b, a) VALUES (:c, :b, :a)");
- statement.inject([":a":"a", ":b":"b", ":c":"c"]);
-
- auto results = db.execute("SELECT * FROM test");
- foreach (row; results)
- {
- assert(row.length == 3);
- assert(row.peek!string(0) == "a");
- assert(row.peek!string(1) == "b");
- assert(row.peek!string(2) == "c");
- }
-}
-
-unittest // Binding Nullable
-{
- auto db = Database(":memory:");
- db.execute("CREATE TABLE test (a, b, c, d, e);");
-
- auto statement = db.prepare("INSERT INTO test (a,b,c,d,e) VALUES (?,?,?,?,?)");
- statement.bind(1, Nullable!int(123));
- statement.bind(2, Nullable!int());
- statement.bind(3, Nullable!(uint, 0)(42));
- statement.bind(4, Nullable!(uint, 0)());
- statement.bind(5, Nullable!bool(false));
- statement.execute();
-
- auto results = db.execute("SELECT * FROM test");
- foreach (row; results)
- {
- assert(row.length == 5);
- assert(row.peek!int(0) == 123);
- assert(row.columnType(1) == SqliteType.NULL);
- assert(row.peek!int(2) == 42);
- assert(row.columnType(3) == SqliteType.NULL);
- assert(!row.peek!bool(4));
- }
-}
-
-unittest // Peeking Nullable
-{
- auto db = Database(":memory:");
- auto results = db.execute("SELECT 1, NULL, 8.5, NULL");
- foreach (row; results)
- {
- assert(row.length == 4);
- assert(row.peek!(Nullable!double)(2).get == 8.5);
- assert(row.peek!(Nullable!double)(3).isNull);
- assert(row.peek!(Nullable!(int, 0))(0).get == 1);
- assert(row.peek!(Nullable!(int, 0))(1).isNull);
- }
-}
-
-unittest // GC anchoring test
-{
- import core.memory : GC;
-
- auto db = Database(":memory:");
- auto stmt = db.prepare("SELECT ?");
-
- auto str = ("I am test string").dup;
- stmt.bind(1, str);
- str = null;
-
- foreach (_; 0..3)
- {
- GC.collect();
- GC.minimize();
- }
-
- ResultRange results = stmt.execute();
- foreach(row; results)
- {
- assert(row.length == 1);
- assert(row.peek!string(0) == "I am test string");
- }
-}
-
-version (unittest) // ResultRange is an input range of Row
-{
- import std.range.primitives : isInputRange, ElementType;
- static assert(isInputRange!ResultRange);
- static assert(is(ElementType!ResultRange == Row));
-}
-
-unittest // Statement error
-{
- auto db = Database(":memory:");
- db.execute("CREATE TABLE test (val INTEGER NOT NULL)");
- auto stmt = db.prepare("INSERT INTO test (val) VALUES (?)");
- stmt.bind(1, null);
- import std.exception : assertThrown;
- assertThrown!SqliteException(stmt.execute());
-}
-
-version (unittest) // Row is a random access range of ColumnData
-{
- import std.range.primitives : isRandomAccessRange, ElementType;
- static assert(isRandomAccessRange!Row);
- static assert(is(ElementType!Row == ColumnData));
-}
-
-unittest // Row.init
-{
- import core.exception : AssertError;
-
- Row row;
- assert(row.empty);
- assertThrown!AssertError(row.front);
- assertThrown!AssertError(row.back);
- assertThrown!AssertError(row.popFront);
- assertThrown!AssertError(row.popBack);
- assertThrown!AssertError(row[""]);
- assertThrown!AssertError(row.peek!long(0));
-}
-
-unittest // Peek
-{
- auto db = Database(":memory:");
- db.run("CREATE TABLE test (value);
- INSERT INTO test VALUES (NULL);
- INSERT INTO test VALUES (42);
- INSERT INTO test VALUES (3.14);
- INSERT INTO test VALUES ('ABC');
- INSERT INTO test VALUES (x'DEADBEEF');");
-
- import std.math : isNaN;
- auto results = db.execute("SELECT * FROM test");
- auto row = results.front;
- assert(row.peek!long(0) == 0);
- assert(row.peek!double(0) == 0);
- assert(row.peek!string(0) is null);
- assert(row.peek!Blob(0) is null);
- results.popFront();
- row = results.front;
- assert(row.peek!long(0) == 42);
- assert(row.peek!double(0) == 42);
- assert(row.peek!string(0) == "42");
- assert(row.peek!Blob(0) == cast(Blob) "42");
- results.popFront();
- row = results.front;
- assert(row.peek!long(0) == 3);
- assert(row.peek!double(0) == 3.14);
- assert(row.peek!string(0) == "3.14");
- assert(row.peek!Blob(0) == cast(Blob) "3.14");
- results.popFront();
- row = results.front;
- assert(row.peek!long(0) == 0);
- assert(row.peek!double(0) == 0.0);
- assert(row.peek!string(0) == "ABC");
- assert(row.peek!Blob(0) == cast(Blob) "ABC");
- results.popFront();
- row = results.front;
- assert(row.peek!long(0) == 0);
- assert(row.peek!double(0) == 0.0);
- assert(row.peek!string(0) == hexString!"DEADBEEF");
- assert(row.peek!Blob(0) == cast(Blob) hexString!"DEADBEEF");
-}
-
-unittest // Peeking NULL values
-{
- auto db = Database(":memory:");
- db.run("CREATE TABLE test (val TEXT);
- INSERT INTO test (val) VALUES (NULL)");
-
- auto results = db.execute("SELECT * FROM test");
- assert(results.front.peek!bool(0) == false);
- assert(results.front.peek!long(0) == 0);
- assert(results.front.peek!double(0) == 0);
- assert(results.front.peek!string(0) is null);
- assert(results.front.peek!Blob(0) is null);
-}
-
-unittest // Row life-time
-{
- auto db = Database(":memory:");
- auto row = db.execute("SELECT 1 AS one").front;
- assert(row[0].as!long == 1);
- assert(row["one"].as!long == 1);
-}
-
-unittest // PeekMode
-{
- auto db = Database(":memory:");
- db.run("CREATE TABLE test (value);
- INSERT INTO test VALUES (x'01020304');
- INSERT INTO test VALUES (x'0A0B0C0D');");
-
- auto results = db.execute("SELECT * FROM test");
- auto row = results.front;
- auto b1 = row.peek!(Blob, PeekMode.copy)(0);
- auto b2 = row.peek!(Blob, PeekMode.slice)(0);
- results.popFront();
- row = results.front;
- auto b3 = row.peek!(Blob, PeekMode.slice)(0);
- auto b4 = row.peek!(Nullable!Blob, PeekMode.copy)(0);
- assert(b1 == cast(Blob) hexString!"01020304");
- // assert(b2 != cast(Blob) x"01020304"); // PASS if SQLite reuses internal buffer
- // assert(b2 == cast(Blob) x"0A0B0C0D"); // PASS (idem)
- assert(b3 == cast(Blob) hexString!"0A0B0C0D");
- assert(!b4.isNull && b4 == cast(Blob) hexString!"0A0B0C0D");
-}
-
-unittest // Row random-access range interface
-{
- import std.array : front, popFront;
-
- auto db = Database(":memory:");
- db.run("CREATE TABLE test (a INTEGER, b INTEGER, c INTEGER, d INTEGER);
- INSERT INTO test VALUES (1, 2, 3, 4);
- INSERT INTO test VALUES (5, 6, 7, 8);");
-
- {
- auto results = db.execute("SELECT * FROM test");
- auto values = [1, 2, 3, 4, 5, 6, 7, 8];
- foreach (row; results)
- {
- while (!row.empty)
- {
- assert(row.front.as!int == values.front);
- row.popFront();
- values.popFront();
- }
- }
- }
-
- {
- auto results = db.execute("SELECT * FROM test");
- auto values = [4, 3, 2, 1, 8, 7, 6, 5];
- foreach (row; results)
- {
- while (!row.empty)
- {
- assert(row.back.as!int == values.front);
- row.popBack();
- values.popFront();
- }
- }
- }
-
- {
- auto row = db.execute("SELECT * FROM test").front;
- row.popFront();
- auto copy = row.save();
- row.popFront();
- assert(row.front.as!int == 3);
- assert(copy.front.as!int == 2);
- }
-}
-
-unittest // ColumnData.init
-{
- import core.exception : AssertError;
- ColumnData data;
- assertThrown!AssertError(data.type);
- assertThrown!AssertError(data.as!string);
-}
-
-unittest // ColumnData-compatible types
-{
- import std.meta : AliasSeq;
-
- alias AllCases = AliasSeq!(bool, true, int, int.max, float, float.epsilon,
- real, 42.0L, string, "おはよう!", const(ubyte)[], [0x00, 0xFF],
- string, "", Nullable!byte, 42);
-
- void test(Cases...)()
- {
- auto cd = ColumnData(Cases[1]);
- assert(cd.as!(Cases[0]) == Cases[1]);
- static if (Cases.length > 2)
- test!(Cases[2..$])();
- }
-
- test!AllCases();
-}
-
-unittest // ColumnData.toString
-{
- auto db = Database(":memory:");
- auto rc = db.execute("SELECT 42, 3.14, 'foo_bar', x'00FF', NULL").cached;
- assert("%(%s%)".format(rc) == "[42, 3.14, foo_bar, [0, 255], null]");
-}
-
-unittest // CachedResults copies
-{
- auto db = Database(":memory:");
- db.run("CREATE TABLE test (msg TEXT);
- INSERT INTO test (msg) VALUES ('ABC')");
-
- static getdata(Database db)
- {
- return db.execute("SELECT * FROM test").cached;
- }
-
- auto data = getdata(db);
- assert(data.length == 1);
- assert(data[0][0].as!string == "ABC");
-}
-
-unittest // UTF-8
-{
- auto db = Database(":memory:");
- bool ran = false;
- db.run("SELECT '\u2019\u2019';", (ResultRange r) {
- assert(r.oneValue!string == "\u2019\u2019");
- ran = true;
- return true;
- });
- assert(ran);
-}
-
-unittest // loadExtension failure test
-{
- import std.exception : collectExceptionMsg;
- auto db = Database(":memory:");
- auto msg = collectExceptionMsg(db.loadExtension("foobar"));
- assert(msg.canFind("(not authorized)"));
-}