summaryrefslogtreecommitdiffstats
path: root/ext/recover/recover1.test
diff options
context:
space:
mode:
Diffstat (limited to 'ext/recover/recover1.test')
-rw-r--r--ext/recover/recover1.test320
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
+