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 #***********************************************************************
12 # This file implements regression tests for SQLite library. The
13 # focus of this file is testing the nolock=1 and immutable=1 query
14 # parameters and the SQLITE_IOCAP_IMMUTABLE device characteristic.
17 set testdir [file dirname $argv0]
18 source $testdir/tester.tcl
20 unset -nocomplain tvfs_calls
23 array set tvfs_calls {xLock 0 xUnlock 0 xCheckReservedLock 0 xAccess 0}
25 proc tvfs_callback {op args} {
33 tvfs script tvfs_callback
34 tvfs filter {xLock xUnlock xCheckReservedLock xAccess}
36 ############################################################################
37 # Verify that the nolock=1 query parameter for URI filenames disables all
38 # calls to xLock and xUnlock for rollback databases.
44 sqlite db test.db -vfs tvfs
45 db eval {CREATE TABLE t1(a,b,c); INSERT INTO t1 VALUES(1,2,3);}
46 list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \
47 xCheckReservedLock $::tvfs_calls(xCheckReservedLock)
48 } {xLock 7 xUnlock 5 xCheckReservedLock 0}
54 sqlite db file:test.db?nolock=0 -vfs tvfs -uri 1
55 db eval {CREATE TABLE t1(a,b,c); INSERT INTO t1 VALUES(1,2,3);}
56 list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \
57 xCheckReservedLock $::tvfs_calls(xCheckReservedLock)
58 } {xLock 7 xUnlock 5 xCheckReservedLock 0}
64 sqlite db file:test.db?nolock=1 -vfs tvfs -uri 1
65 db eval {CREATE TABLE t1(a,b,c); INSERT INTO t1 VALUES(1,2,3);}
66 list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \
67 xCheckReservedLock $::tvfs_calls(xCheckReservedLock)
68 } {xLock 0 xUnlock 0 xCheckReservedLock 0}
73 sqlite db file:test.db?nolock=0 -vfs tvfs -uri 1 -readonly 1
74 db eval {SELECT * FROM t1}
75 list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \
76 xCheckReservedLock $::tvfs_calls(xCheckReservedLock)
77 } {xLock 2 xUnlock 2 xCheckReservedLock 0}
82 sqlite db file:test.db?nolock=1 -vfs tvfs -uri 1 -readonly 1
83 db eval {SELECT * FROM t1}
84 list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \
85 xCheckReservedLock $::tvfs_calls(xCheckReservedLock)
86 } {xLock 0 xUnlock 0 xCheckReservedLock 0}
88 #############################################################################
89 # Verify that immutable=1 disables both locking and xAccess calls to the
95 # begin by creating a test database
99 INSERT INTO t1 VALUES('hello','world');
100 CREATE TABLE t2(x,y);
101 INSERT INTO t2 VALUES(12345,67890);
102 SELECT * FROM t1, t2;
104 } {hello world 12345 67890}
107 sqlite3 db2 test.db -vfs tvfs
108 db2 eval {SELECT * FROM t1, t2}
109 } {hello world 12345 67890}
111 list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \
112 xCheckReservedLock $::tvfs_calls(xCheckReservedLock) \
113 xAccess $::tvfs_calls(xAccess)
114 } {xLock 2 xUnlock 2 xCheckReservedLock 0 xAccess 4}
117 do_test nolock-2.11 {
120 sqlite3 db2 file:test.db?immutable=0 -vfs tvfs -uri 1
121 db2 eval {SELECT * FROM t1, t2}
122 } {hello world 12345 67890}
123 do_test nolock-2.12 {
124 list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \
125 xCheckReservedLock $::tvfs_calls(xCheckReservedLock) \
126 xAccess $::tvfs_calls(xAccess)
127 } {xLock 2 xUnlock 2 xCheckReservedLock 0 xAccess 4}
130 do_test nolock-2.21 {
133 sqlite3 db2 file:test.db?immutable=1 -vfs tvfs -uri 1
134 db2 eval {SELECT * FROM t1, t2}
135 } {hello world 12345 67890}
136 do_test nolock-2.22 {
137 list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \
138 xCheckReservedLock $::tvfs_calls(xCheckReservedLock) \
139 xAccess $::tvfs_calls(xAccess)
140 } {xLock 0 xUnlock 0 xCheckReservedLock 0 xAccess 0}
142 do_test nolock-2.31 {
145 sqlite3 db2 file:test.db?immutable=1 -vfs tvfs -uri 1 -readonly 1
146 db2 eval {SELECT * FROM t1, t2}
147 } {hello world 12345 67890}
148 do_test nolock-2.32 {
149 list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \
150 xCheckReservedLock $::tvfs_calls(xCheckReservedLock) \
151 xAccess $::tvfs_calls(xAccess)
152 } {xLock 0 xUnlock 0 xCheckReservedLock 0 xAccess 0}
154 ############################################################################
155 # Verify that the SQLITE_IOCAP_IMMUTABLE flag works
159 tvfs devchar immutable
161 sqlite3 db2 test.db -vfs tvfs
162 db2 eval {SELECT * FROM t1, t2}
163 } {hello world 12345 67890}
165 list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \
166 xCheckReservedLock $::tvfs_calls(xCheckReservedLock) \
167 xAccess $::tvfs_calls(xAccess)
168 } {xLock 0 xUnlock 0 xCheckReservedLock 0 xAccess 0}
170 do_test nolock-3.11 {
173 sqlite3 db2 test.db -vfs tvfs -readonly 1
174 db2 eval {SELECT * FROM t1, t2}
175 } {hello world 12345 67890}
176 do_test nolock-3.12 {
177 list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \
178 xCheckReservedLock $::tvfs_calls(xCheckReservedLock) \
179 xAccess $::tvfs_calls(xAccess)
180 } {xLock 0 xUnlock 0 xCheckReservedLock 0 xAccess 0}
186 if {[permutation]!="inmemory_journal"} {
187 # 2016-03-11: Make sure all works when transitioning to WAL mode
192 sqlite3 db file:test.db?nolock=1 -uri 1
194 PRAGMA journal_mode=WAL;
196 INSERT INTO t1 VALUES('youngling');
206 PRAGMA journal_mode=WAL;
208 INSERT INTO t1 VALUES('catbird');
214 sqlite3 db file:test.db?nolock=1 -uri 1
215 set rc [catch {db eval {SELECT * FROM t1}} msg]
217 } {1 {unable to open database file}}