3 # The author disclaims copyright to this source code. In place of
4 # a legal notice, here is a blessing:
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.
10 #***********************************************************************
11 # This file implements regression tests for SQLite library. The
12 # focus of this file is testing the operation of the library in
13 # "PRAGMA journal_mode=WAL" mode.
16 set testdir [file dirname $argv0]
18 source $testdir/tester.tcl
19 source $testdir/lock_common.tcl
20 source $testdir/wal_common.tcl
21 source $testdir/malloc_common.tcl
22 ifcapable !wal {finish_test ; return }
24 #-------------------------------------------------------------------------
25 # Changing to WAL mode in one connection forces the change in others.
30 set all_journal_modes {delete persist truncate memory off}
31 foreach jmode $all_journal_modes {
33 do_test wal6-1.0.$jmode {
35 execsql "PRAGMA journal_mode = $jmode;"
38 do_test wal6-1.1.$jmode {
40 CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
41 INSERT INTO t1 VALUES(1,2);
46 # Under Windows, you'll get an error trying to delete
47 # a file this is already opened. Close the first connection
48 # so the other tests work.
49 if {$tcl_platform(platform)=="windows"} {
50 if {$jmode=="persist" || $jmode=="truncate"} {
55 do_test wal6-1.2.$jmode {
58 PRAGMA journal_mode=WAL;
59 INSERT INTO t1 VALUES(3,4);
60 SELECT * FROM t1 ORDER BY a;
64 if {$tcl_platform(platform)=="windows"} {
65 if {$jmode=="persist" || $jmode=="truncate"} {
70 do_test wal6-1.3.$jmode {
72 SELECT * FROM t1 ORDER BY a;
82 #-------------------------------------------------------------------------
83 # Test that SQLITE_BUSY_SNAPSHOT is returned as expected.
89 PRAGMA journal_mode = WAL;
90 CREATE TABLE t1(a PRIMARY KEY, b TEXT);
91 INSERT INTO t1 VALUES(1, 'one');
92 INSERT INTO t1 VALUES(2, 'two');
100 INSERT INTO t1 VALUES(3, 'three');
104 do_catchsql_test 2.3 {
105 INSERT INTO t1 VALUES('x', 'x')
106 } {1 {database is locked}}
109 list [sqlite3_errcode db] [sqlite3_extended_errcode db]
110 } {SQLITE_BUSY SQLITE_BUSY_SNAPSHOT}
112 do_execsql_test 2.5 {
115 INSERT INTO t1 VALUES('x', 'x')
118 proc test3 {prefix} {
120 execsql { SELECT count(*) FROM t1 }
123 execsql { INSERT INTO t1 VALUES('x', 'x') } db2
126 execsql { INSERT INTO t1 VALUES('y', 'y') }
129 execsql { SELECT count(*) FROM t1 }
133 do_execsql_test 2.6.1 { DELETE FROM t1 }
137 do_execsql_test 2.6.3 { DELETE FROM t1 }
138 db eval {SELECT test3('2.6.4')}
144 #-------------------------------------------------------------------------
145 # Check that if BEGIN IMMEDIATE fails, it does not leave the user with
146 # an open read-transaction (unless one was already open before the BEGIN
147 # IMMEDIATE). Even if there are other active VMs.
150 proc test4 {prefix} {
152 catchsql { BEGIN IMMEDIATE }
153 } {1 {database is locked}}
156 execsql { COMMIT } db2
160 execsql { BEGIN IMMEDIATE }
169 do_execsql_test 3.1 {
170 PRAGMA journal_mode = WAL;
171 CREATE TABLE ab(a PRIMARY KEY, b);
177 INSERT INTO ab VALUES(1, 2);
186 INSERT INTO ab VALUES(3, 4);
190 db eval {SELECT test4('3.3.2')}
196 #-------------------------------------------------------------------------
197 # Check that if a wal file has been partially checkpointed, no frames are
198 # read from the checkpointed part.
201 do_execsql_test 4.1 {
202 PRAGMA page_size = 1024;
203 PRAGMA journal_mode = wal;
204 CREATE TABLE t1(a, b);
205 CREATE TABLE t2(a, b);
206 PRAGMA wal_checkpoint = truncate;
210 execsql { INSERT INTO t1 VALUES(1, 2) }
211 file size test.db-wal
212 } [wal_file_size 1 1024]
218 INSERT INTO t2 VALUES(3, 4);
220 execsql { PRAGMA wal_checkpoint = passive } db2
226 hexio_write test.db-wal 0 [string repeat 00 2000]
231 catchsql { SELECT * FROM t1 } db2
234 catchsql { SELECT * FROM t2 } db2
235 } {1 {database disk image is malformed}}
237 #-------------------------------------------------------------------------
238 # Confirm that it is possible to get an SQLITE_BUSY_SNAPSHOT error from
239 # "BEGIN EXCLUSIVE" if the connection already has an open read-transaction.
245 do_execsql_test 5.1 {
246 PRAGMA journal_mode = wal;
247 CREATE TABLE t1(x, y);
248 INSERT INTO t1 VALUES(1, 2);
249 INSERT INTO t1 VALUES(3, 4);
257 db2 eval { INSERT INTO t1 VALUES(5, 6) }
260 set res [catchsql {BEGIN EXCLUSIVE}]
261 lappend res [sqlite3_extended_errcode db]
265 } {1 {database is locked} SQLITE_BUSY_SNAPSHOT}