1# 2019 April 23 2# 3# The author disclaims copyright to this source code. In place of 4# a legal notice, here is a blessing: 5# 6# May you do good and not evil. 7# May you find forgiveness for yourself and forgive others. 8# May you share freely, never taking more than you give. 9# 10#*********************************************************************** 11# 12# Test the shell tool ".ar" command. 13# 14 15set testdir [file dirname $argv0] 16source $testdir/tester.tcl 17set testprefix recover 18 19ifcapable !vtab { 20 finish_test; return 21} 22set CLI [test_find_cli] 23 24proc compare_result {db1 db2 sql} { 25 set r1 [$db1 eval $sql] 26 set r2 [$db2 eval $sql] 27 if {$r1 != $r2} { 28 puts "r1: $r1" 29 puts "r2: $r2" 30 error "mismatch for $sql" 31 } 32 return "" 33} 34 35proc compare_dbs {db1 db2} { 36 compare_result $db1 $db2 "SELECT sql FROM sqlite_master ORDER BY 1" 37 foreach tbl [$db1 eval {SELECT name FROM sqlite_master WHERE type='table'}] { 38 compare_result $db1 $db2 "SELECT * FROM $tbl" 39 } 40} 41 42proc recover_with_opts {opts} { 43 set cmd ".recover $opts" 44 set fd [open [list |$::CLI test.db $cmd]] 45 fconfigure $fd -encoding binary 46 fconfigure $fd -translation binary 47 set sql [read $fd] 48 close $fd 49 50 forcedelete test.db2 51 sqlite3 db2 test.db2 52 execsql $sql db2 53 db2 close 54} 55 56proc do_recover_test {tn {tsql {}} {res {}}} { 57 recover_with_opts "" 58 59 sqlite3 db2 test.db2 60 if {$tsql==""} { 61 uplevel [list do_test $tn [list compare_dbs db db2] {}] 62 } else { 63 uplevel [list do_execsql_test -db db2 $tn $tsql $res] 64 } 65 db2 close 66} 67 68set doc { 69 hello 70 world 71} 72do_execsql_test 1.1.1 { 73 CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); 74 INSERT INTO t1 VALUES(1, 4, X'1234567800'); 75 INSERT INTO t1 VALUES(2, 'test', 8.1); 76 INSERT INTO t1 VALUES(3, $doc, 8.4); 77} 78do_recover_test 1.1.2 79 80do_execsql_test 1.2.1 " 81 DELETE FROM t1; 82 INSERT INTO t1 VALUES(13, 'hello\r\nworld', 13); 83" 84do_recover_test 1.2.2 85 86do_execsql_test 1.3.1 " 87 CREATE TABLE t2(i INTEGER PRIMARY KEY AUTOINCREMENT, b, c); 88 INSERT INTO t2 VALUES(NULL, 1, 2); 89 INSERT INTO t2 VALUES(NULL, 3, 4); 90 INSERT INTO t2 VALUES(NULL, 5, 6); 91 CREATE TABLE t3(i INTEGER PRIMARY KEY AUTOINCREMENT, b, c); 92 INSERT INTO t3 VALUES(NULL, 1, 2); 93 INSERT INTO t3 VALUES(NULL, 3, 4); 94 INSERT INTO t3 VALUES(NULL, 5, 6); 95 DELETE FROM t2; 96" 97do_recover_test 1.3.2 98 99#------------------------------------------------------------------------- 100reset_db 101do_execsql_test 2.1.0 { 102 PRAGMA auto_vacuum = 0; 103 CREATE TABLE t1(a, b, c, PRIMARY KEY(b, c)) WITHOUT ROWID; 104 INSERT INTO t1 VALUES(1, 2, 3); 105 INSERT INTO t1 VALUES(4, 5, 6); 106 INSERT INTO t1 VALUES(7, 8, 9); 107} 108 109do_recover_test 2.1.1 110 111do_execsql_test 2.2.0 { 112 PRAGMA writable_schema = 1; 113 DELETE FROM sqlite_master WHERE name='t1'; 114} 115do_recover_test 2.2.1 { 116 SELECT name FROM sqlite_master 117} {lost_and_found} 118 119do_execsql_test 2.3.0 { 120 CREATE TABLE lost_and_found(a, b, c); 121} 122do_recover_test 2.3.1 { 123 SELECT name FROM sqlite_master 124} {lost_and_found lost_and_found_0} 125 126do_execsql_test 2.4.0 { 127 CREATE TABLE lost_and_found_0(a, b, c); 128} 129do_recover_test 2.4.1 { 130 SELECT name FROM sqlite_master; 131 SELECT * FROM lost_and_found_1; 132} {lost_and_found lost_and_found_0 lost_and_found_1 133 2 2 3 {} 2 3 1 134 2 2 3 {} 5 6 4 135 2 2 3 {} 8 9 7 136} 137 138#------------------------------------------------------------------------- 139reset_db 140do_recover_test 3.0 141 142#------------------------------------------------------------------------- 143reset_db 144execsql { PRAGMA secure_delete = 0 } 145execsql { PRAGMA auto_vacuum = 0 } 146do_execsql_test 4.0 { 147 CREATE TABLE t1(a, b, c); 148 CREATE TABLE t2(d, e, f); 149 CREATE TABLE t3(g, h, i); 150 151 INSERT INTO t2 VALUES(1, 2, 3); 152 INSERT INTO t2 VALUES('a', 'b', 'c'); 153 154 INSERT INTO t3 VALUES('one', 'two', 'three'); 155 DROP TABLE t1; 156 DROP TABLE t2; 157} 158 159recover_with_opts "" 160sqlite3 db2 test.db2 161do_execsql_test -db db2 4.1.1 { 162 SELECT name FROM sqlite_schema 163} {t3 lost_and_found} 164do_execsql_test -db db2 4.1.2 { 165 SELECT id, c0, c1, c2 FROM lost_and_found 166} {1 1 2 3 2 a b c} 167db2 close 168 169recover_with_opts -ignore-freelist 170sqlite3 db2 test.db2 171do_execsql_test -db db2 4.2.1 { 172 SELECT name FROM sqlite_schema 173} {t3} 174do_execsql_test -db db2 4.2.2 { 175 SELECT * FROM t3 176} {one two three} 177db2 close 178 179finish_test 180