github.com/jdgcs/sqlite3@v1.12.1-0.20210908114423-bc5f96e4dd51/testdata/tcl/snapshot2.test (about) 1 # 2016 November 18 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 # This file implements regression tests for SQLite library. The focus 12 # of this file is the sqlite3_snapshot_xxx() APIs. 13 # 14 15 set testdir [file dirname $argv0] 16 source $testdir/tester.tcl 17 ifcapable !snapshot {finish_test; return} 18 set testprefix snapshot2 19 20 # This test does not work with the inmemory_journal permutation. The reason 21 # is that each connection opened as part of this permutation executes 22 # "PRAGMA journal_mode=memory", which fails if the database is in wal mode 23 # and there are one or more existing connections. 24 if {[permutation]=="inmemory_journal"} { 25 finish_test 26 return 27 } 28 29 #------------------------------------------------------------------------- 30 # Check that it is not possible to obtain a snapshot immediately after 31 # a wal mode database with an empty wal file is opened. But it is after 32 # the file has been written, even by some other connection. 33 # 34 do_execsql_test 1.0 { 35 PRAGMA journal_mode = wal; 36 CREATE TABLE t1(a, b, c); 37 INSERT INTO t1 VALUES(1, 2, 3); 38 INSERT INTO t1 VALUES(4, 5, 6); 39 } {wal} 40 41 db close 42 do_test 1.1.1 { list [file exists test.db] [file exists test.db-wal] } {1 0} 43 44 sqlite3 db test.db 45 do_execsql_test 1.1.2 { SELECT * FROM t1 } {1 2 3 4 5 6} 46 47 do_test 1.1.3 { 48 execsql BEGIN 49 list [catch { sqlite3_snapshot_get_blob db main } msg] $msg 50 } {1 SQLITE_ERROR} 51 execsql COMMIT 52 53 do_test 1.1.4 { 54 execsql { INSERT INTO t1 VALUES(7, 8, 9) } 55 execsql BEGIN 56 string length [sqlite3_snapshot_get_blob db main] 57 } 48 58 execsql COMMIT 59 60 db close 61 do_test 1.2.1 { list [file exists test.db] [file exists test.db-wal] } {1 0} 62 63 sqlite3 db test.db 64 do_execsql_test 1.2.2 { SELECT * FROM t1 } {1 2 3 4 5 6 7 8 9} 65 66 do_test 1.2.3 { 67 execsql BEGIN 68 list [catch { sqlite3_snapshot_get_blob db main } msg] $msg 69 } {1 SQLITE_ERROR} 70 execsql COMMIT 71 72 do_test 1.2.4 { 73 sqlite3 db2 test.db 74 execsql { INSERT INTO t1 VALUES(10, 11, 12) } db2 75 execsql BEGIN 76 string length [sqlite3_snapshot_get_blob db main] 77 } 48 78 execsql COMMIT 79 db2 close 80 81 #------------------------------------------------------------------------- 82 # Simple tests for sqlite3_snapshot_recover(). 83 # 84 reset_db 85 do_execsql_test 2.0 { 86 CREATE TABLE t1(x); 87 PRAGMA journal_mode = wal; 88 INSERT INTO t1 VALUES(1); 89 INSERT INTO t1 VALUES(2); 90 } {wal} 91 92 do_test 2.1 { 93 db trans { set snap [sqlite3_snapshot_get_blob db main] } 94 sqlite3_db_config db NO_CKPT_ON_CLOSE 1 95 db close 96 sqlite3 db test.db 97 98 execsql {SELECT * FROM sqlite_master} 99 execsql BEGIN 100 sqlite3_snapshot_open_blob db main $snap 101 execsql COMMIT; 102 execsql { INSERT INTO t1 VALUES(3); } 103 } {} 104 105 do_test 2.2 { 106 sqlite3_db_config db NO_CKPT_ON_CLOSE 1 107 db close 108 sqlite3 db test.db 109 110 execsql {SELECT * FROM sqlite_master} 111 execsql BEGIN 112 list [catch { sqlite3_snapshot_open_blob db main $snap } msg] $msg 113 } {1 SQLITE_ERROR_SNAPSHOT} 114 115 do_test 2.3 { 116 execsql COMMIT 117 sqlite3_snapshot_recover db main 118 execsql BEGIN 119 sqlite3_snapshot_open_blob db main $snap 120 execsql { SELECT * FROM t1 } 121 } {1 2} 122 123 do_test 2.4 { 124 execsql COMMIT 125 execsql { SELECT * FROM t1 } 126 } {1 2 3} 127 128 do_test 2.5 { 129 execsql { PRAGMA wal_checkpoint } 130 sqlite3_db_config db NO_CKPT_ON_CLOSE 1 131 db close 132 sqlite3 db test.db 133 134 sqlite3_snapshot_recover db main 135 execsql BEGIN 136 list [catch { sqlite3_snapshot_open_blob db main $snap } msg] $msg 137 } {1 SQLITE_ERROR_SNAPSHOT} 138 139 #------------------------------------------------------------------------- 140 # Check that calling sqlite3_snapshot_recover() does not confuse the 141 # pager cache. 142 reset_db 143 do_execsql_test 3.0 { 144 PRAGMA journal_mode = wal; 145 CREATE TABLE t1(x, y); 146 INSERT INTO t1 VALUES('a', 'b'); 147 INSERT INTO t1 VALUES('c', 'd'); 148 } {wal} 149 do_test 3.1 { 150 sqlite3 db2 test.db 151 execsql { INSERT INTO t1 VALUES('e', 'f') } db2 152 db2 close 153 sqlite3_snapshot_recover db main 154 } {} 155 do_execsql_test 3.2 { 156 SELECT * FROM t1; 157 } {a b c d e f} 158 159 #------------------------------------------------------------------------- 160 # Check that sqlite3_snapshot_recover() returns an error if it is called 161 # with an open read-transaction. Or on a database that does not exist. Or 162 # on the temp database. Or on a db that is not in wal mode. 163 # 164 do_test 4.1 { 165 sqlite3_snapshot_recover db main 166 } {} 167 do_test 4.2 { 168 execsql { 169 BEGIN; 170 SELECT * FROM sqlite_master; 171 } 172 list [catch { sqlite3_snapshot_recover db main } msg] $msg 173 } {1 SQLITE_ERROR} 174 do_test 4.3 { 175 execsql COMMIT 176 sqlite3_snapshot_recover db main 177 } {} 178 do_test 4.4 { 179 list [catch { sqlite3_snapshot_recover db aux } msg] $msg 180 } {1 SQLITE_ERROR} 181 do_test 4.5 { 182 forcedelete test.db2 183 execsql { 184 ATTACH 'test.db2' AS aux; 185 PRAGMA aux.journal_mode = wal; 186 CREATE TABLE aux.t2(x, y); 187 } 188 list [catch { sqlite3_snapshot_recover db aux } msg] $msg 189 } {0 {}} 190 do_test 4.6 { 191 list [catch { sqlite3_snapshot_recover db temp } msg] $msg 192 } {1 SQLITE_ERROR} 193 do_test 4.7 { 194 execsql { 195 PRAGMA aux.journal_mode = delete; 196 } 197 list [catch { sqlite3_snapshot_recover db aux } msg] $msg 198 } {1 SQLITE_ERROR} 199 200 #------------------------------------------------------------------------- 201 reset_db 202 sqlite3 db2 test.db 203 do_execsql_test 5.0 { 204 CREATE TABLE t2(x); 205 PRAGMA journal_mode = wal; 206 INSERT INTO t2 VALUES('abc'); 207 INSERT INTO t2 VALUES('def'); 208 INSERT INTO t2 VALUES('ghi'); 209 } {wal} 210 211 do_test 5.1 { 212 execsql { 213 SELECT * FROM t2; 214 BEGIN; 215 } db2 216 set snap [sqlite3_snapshot_get_blob db2 main] 217 db2 eval END 218 } {} 219 220 do_test 5.2 { 221 execsql BEGIN db2 222 sqlite3_snapshot_open_blob db2 main $snap 223 db2 eval { SELECT * FROM t2 ; END } 224 } {abc def ghi} 225 226 do_test 5.3 { 227 execsql { PRAGMA wal_checkpoint = RESTART } 228 execsql BEGIN db2 229 sqlite3_snapshot_open_blob db2 main $snap 230 db2 eval { SELECT * FROM t2 ; END } 231 } {abc def ghi} 232 233 do_test 5.4 { 234 execsql { INSERT INTO t2 VALUES('jkl') } 235 execsql BEGIN db2 236 list [catch { sqlite3_snapshot_open_blob db2 main $snap } msg] $msg 237 } {1 SQLITE_ERROR_SNAPSHOT} 238 239 240 finish_test