diff options
Diffstat (limited to 'ext/recover/recover1.test')
-rw-r--r-- | ext/recover/recover1.test | 320 |
1 files changed, 320 insertions, 0 deletions
diff --git a/ext/recover/recover1.test b/ext/recover/recover1.test new file mode 100644 index 0000000..dba96f5 --- /dev/null +++ b/ext/recover/recover1.test @@ -0,0 +1,320 @@ +# 2022 August 28 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +source [file join [file dirname [info script]] recover_common.tcl] +set testprefix recover1 + +proc compare_result {db1 db2 sql} { + set r1 [$db1 eval $sql] + set r2 [$db2 eval $sql] + if {$r1 != $r2} { + puts "r1: $r1" + puts "r2: $r2" + error "mismatch for $sql" + } + return "" +} + +proc compare_dbs {db1 db2} { + compare_result $db1 $db2 "SELECT sql FROM sqlite_master ORDER BY 1" + foreach tbl [$db1 eval {SELECT name FROM sqlite_master WHERE type='table'}] { + compare_result $db1 $db2 "SELECT * FROM $tbl" + } + + compare_result $db1 $db2 "PRAGMA page_size" + compare_result $db1 $db2 "PRAGMA auto_vacuum" + compare_result $db1 $db2 "PRAGMA encoding" + compare_result $db1 $db2 "PRAGMA user_version" + compare_result $db1 $db2 "PRAGMA application_id" +} + +proc do_recover_test {tn} { + forcedelete test.db2 + forcedelete rstate.db + + uplevel [list do_test $tn.1 { + set R [sqlite3_recover_init db main test.db2] + $R config testdb rstate.db + $R run + $R finish + } {}] + + sqlite3 db2 test.db2 + uplevel [list do_test $tn.2 [list compare_dbs db db2] {}] + db2 close + + forcedelete test.db2 + forcedelete rstate.db + + uplevel [list do_test $tn.3 { + set ::sqlhook [list] + set R [sqlite3_recover_init_sql db main my_sql_hook] + $R config testdb rstate.db + $R config rowids 1 + $R run + $R finish + } {}] + + sqlite3 db2 test.db2 + execsql [join $::sqlhook ";"] db2 + db2 close + sqlite3 db2 test.db2 + uplevel [list do_test $tn.4 [list compare_dbs db db2] {}] + db2 close +} + +proc my_sql_hook {sql} { + lappend ::sqlhook $sql + return 0 +} + +do_execsql_test 1.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); + CREATE TABLE t2(a INTEGER PRIMARY KEY, b) WITHOUT ROWID; + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<10 + ) + INSERT INTO t1 SELECT i*2, hex(randomblob(250)) FROM s; + INSERT INTO t2 SELECT * FROM t1; +} + +do_recover_test 1 + +do_execsql_test 2.0 { + ALTER TABLE t1 ADD COLUMN c DEFAULT 'xyz' +} +do_recover_test 2 + +do_execsql_test 3.0 { + CREATE INDEX i1 ON t1(c); +} +do_recover_test 3 + +do_execsql_test 4.0 { + CREATE VIEW v1 AS SELECT * FROM t2; +} +do_recover_test 4 + +do_execsql_test 5.0 { + CREATE UNIQUE INDEX i2 ON t1(c, b); +} +do_recover_test 5 + +#-------------------------------------------------------------------------- +# +reset_db +do_execsql_test 6.0 { + CREATE TABLE t1( + a INTEGER PRIMARY KEY, + b INT, + c TEXT, + d INT GENERATED ALWAYS AS (a*abs(b)) VIRTUAL, + e TEXT GENERATED ALWAYS AS (substr(c,b,b+1)) STORED, + f TEXT GENERATED ALWAYS AS (substr(c,b,b+1)) STORED + ); + + INSERT INTO t1 VALUES(1, 2, 'hello world'); +} +do_recover_test 6 + +do_execsql_test 7.0 { + CREATE TABLE t2(i, j GENERATED ALWAYS AS (i+1) STORED, k); + INSERT INTO t2 VALUES(10, 'ten'); +} +do_execsql_test 7.1 { + SELECT * FROM t2 +} {10 11 ten} + +do_recover_test 7.2 + +#-------------------------------------------------------------------------- +# +reset_db +do_execsql_test 8.0 { + CREATE TABLE x1(a INTEGER PRIMARY KEY AUTOINCREMENT, b, c); + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<2 + ) + INSERT INTO x1(b, c) SELECT hex(randomblob(100)), hex(randomblob(100)) FROM s; + + CREATE INDEX x1b ON x1(b); + CREATE INDEX x1cb ON x1(c, b); + DELETE FROM x1 WHERE a>50; + + ANALYZE; +} + +do_recover_test 8 + +#------------------------------------------------------------------------- +reset_db +ifcapable fts5 { + do_execsql_test 9.1 { + CREATE VIRTUAL TABLE ft5 USING fts5(a, b); + INSERT INTO ft5 VALUES('hello', 'world'); + } + do_recover_test 9 +} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 10.1 { + CREATE TABLE x1(a PRIMARY KEY, str TEXT) WITHOUT ROWID; + INSERT INTO x1 VALUES(1, ' + \nhello\012world(\n0)(\n1) + '); + INSERT INTO x1 VALUES(2, ' + \nhello + '); +} +do_execsql_test 10.2 " + INSERT INTO x1 VALUES(3, '\012hello there\015world'); + INSERT INTO x1 VALUES(4, '\015hello there\015world'); +" +do_recover_test 10 + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 11.1 { + PRAGMA page_size = 4096; + PRAGMA encoding='utf16'; + PRAGMA auto_vacuum = 2; + PRAGMA user_version = 45; + PRAGMA application_id = 22; + + CREATE TABLE u1(u, v); + INSERT INTO u1 VALUES('edvin marton', 'bond'); + INSERT INTO u1 VALUES(1, 4.0); +} +do_execsql_test 11.1a { + PRAGMA auto_vacuum; +} {2} + +do_recover_test 11 + +do_test 12.1 { + set R [sqlite3_recover_init db "" test.db2] + $R config lostandfound "" + $R config invalid xyz +} {12} +do_test 12.2 { + $R run + $R run +} {0} + +do_test 12.3 { + $R finish +} {} + + + +#------------------------------------------------------------------------- +reset_db +file_control_reservebytes db 16 +do_execsql_test 12.1 { + PRAGMA auto_vacuum = 2; + PRAGMA user_version = 45; + PRAGMA application_id = 22; + + CREATE TABLE u1(u, v); + CREATE UNIQUE INDEX i1 ON u1(u, v); + INSERT INTO u1 VALUES(1, 2), (3, 4); + + CREATE TABLE u2(u, v); + CREATE UNIQUE INDEX i2 ON u1(u, v); + INSERT INTO u2 VALUES(hex(randomblob(500)), hex(randomblob(1000))); + INSERT INTO u2 VALUES(hex(randomblob(500)), hex(randomblob(1000))); + INSERT INTO u2 VALUES(hex(randomblob(500)), hex(randomblob(1000))); + INSERT INTO u2 VALUES(hex(randomblob(50000)), hex(randomblob(20000))); +} + +do_recover_test 12 + +#------------------------------------------------------------------------- +reset_db +sqlite3 db "" +do_recover_test 13 + +do_execsql_test 14.1 { + PRAGMA auto_vacuum = 2; + PRAGMA user_version = 45; + PRAGMA application_id = 22; + + CREATE TABLE u1(u, v); + CREATE UNIQUE INDEX i1 ON u1(u, v); + INSERT INTO u1 VALUES(1, 2), (3, 4); + + CREATE TABLE u2(u, v); + CREATE UNIQUE INDEX i2 ON u1(u, v); + INSERT INTO u2 VALUES(hex(randomblob(500)), hex(randomblob(1000))); + INSERT INTO u2 VALUES(hex(randomblob(500)), hex(randomblob(1000))); + INSERT INTO u2 VALUES(hex(randomblob(500)), hex(randomblob(1000))); + INSERT INTO u2 VALUES(hex(randomblob(50000)), hex(randomblob(20000))); +} +do_recover_test 14 + +#------------------------------------------------------------------------- +reset_db +execsql { + PRAGMA journal_mode=OFF; + PRAGMA mmap_size=10; +} +do_execsql_test 15.1 { + CREATE TABLE t1(x); +} {} +do_recover_test 15 + +#------------------------------------------------------------------------- +reset_db +if {[wal_is_capable]} { + do_execsql_test 16.1 { + PRAGMA journal_mode = wal; + CREATE TABLE t1(x); + INSERT INTO t1 VALUES(1), (2), (3); + } {wal} + do_test 16.2 { + set R [sqlite3_recover_init db main test.db2] + $R run + $R finish + } {} + do_execsql_test 16.3 { + SELECT * FROM t1; + } {1 2 3} + + do_execsql_test 16.4 { + BEGIN; + SELECT * FROM t1; + } {1 2 3} + do_test 16.5 { + set R [sqlite3_recover_init db main test.db2] + $R run + list [catch { $R finish } msg] $msg + } {1 {cannot start a transaction within a transaction}} + do_execsql_test 16.6 { + SELECT * FROM t1; + } {1 2 3} + do_execsql_test 16.7 { + INSERT INTO t1 VALUES(4); + } + do_test 16.8 { + set R [sqlite3_recover_init db main test.db2] + $R run + list [catch { $R finish } msg] $msg + } {1 {cannot start a transaction within a transaction}} + do_execsql_test 16.9 { + SELECT * FROM t1; + COMMIT; + } {1 2 3 4} +} + +finish_test + |