Annotation of embedaddon/sqlite3/test/uri.test, revision 1.1.1.1
1.1 misho 1: # 2011 April 22
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:
13: set testdir [file dirname $argv0]
14: source $testdir/tester.tcl
15:
16: # Test organization:
17: #
18: # 1.*: That file names are correctly extracted from URIs.
19: # 2.*: That URI options (query parameters) are correctly extracted from URIs.
20: # 3.*: That specifying an unknown VFS causes an error.
21: # 4.*: Tests for specifying other options (other than "vfs").
22: # 5.*: Test using a different VFS with an attached database.
23: # 6.*: Test that authorities other than "" and localhost cause errors.
24: # 7.*: Test that a read-write db can be attached to a read-only connection.
25: #
26:
27: set testprefix uri
28: db close
29: sqlite3_shutdown
30: sqlite3_config_uri 1
31:
32: #-------------------------------------------------------------------------
33: # Test that file names are correctly extracted from URIs.
34: #
35: foreach {tn uri file} {
36: 1 test.db test.db
37: 2 file:test.db test.db
38: 3 file://PWD/test.db test.db
39: 4 file:PWD/test.db test.db
40: 5 file:test.db?mork=1 test.db
41: 6 file:test.db?mork=1&tonglor=2 test.db
42: 7 file:test.db?mork=1#boris test.db
43: 8 file:test.db#boris test.db
44: 9 test.db#boris test.db#boris
45: 10 file:test%2Edb test.db
46: 11 file file
47: 12 http:test.db http:test.db
48: 13 file:test.db%00extra test.db
49: 14 file:testdb%00.db%00extra testdb
50:
51: 15 test.db?mork=1#boris test.db?mork=1#boris
52: 16 file://localhostPWD/test.db%3Fhello test.db?hello
53: } {
54:
55: if {$tcl_platform(platform)=="windows"} {
56: if {$tn>14} break
57: set uri [string map [list PWD /[pwd]] $uri]
58: } else {
59: set uri [string map [list PWD [pwd]] $uri]
60: }
61:
62: if {[file isdir $file]} {error "$file is a directory"}
63: forcedelete $file
64: do_test 1.$tn.1 { file exists $file } 0
65: set DB [sqlite3_open $uri]
66: do_test 1.$tn.2 { file exists $file } 1
67: sqlite3_close $DB
68: forcedelete $file
69:
70: do_test 1.$tn.3 { file exists $file } 0
71: sqlite3 db xxx.db
72: catchsql { ATTACH $uri AS aux }
73: do_test 1.$tn.4 { file exists $file } 1
74: db close
75: }
76:
77: #-------------------------------------------------------------------------
78: # Test that URI query parameters are passed through to the VFS layer
79: # correctly.
80: #
81: testvfs tvfs2
82: testvfs tvfs -default 1
83: tvfs filter xOpen
84: tvfs script open_method
85: proc open_method {method file arglist} {
86: set ::arglist $arglist
87: }
88: foreach {tn uri kvlist} {
89: 1 file:test.db?hello=world {hello world}
90: 2 file:test.db?hello&world {hello {} world {}}
91: 3 file:test.db?hello=1&world=2&vfs=tvfs {hello 1 world 2 vfs tvfs}
92: 4 file:test.db?hello=1&world=2&vfs=tvfs2 {}
93: 5 file:test.db?%68%65%6C%6C%6F=%77%6F%72%6C%64 {hello world}
94: 6 file:testdb%00.db?hello%00extra=world%00ex {hello world}
95: 7 file:testdb%00.db?hello%00=world%00 {hello world}
96: 8 file:testdb%00.db?=world&xyz=abc {xyz abc}
97: 9 file:test.db?%00hello=world&xyz=abc {xyz abc}
98: 10 file:test.db?hello=%00world&xyz= {hello {} xyz {}}
99: 11 file:test.db?=#ravada {}
100: 12 file:test.db?&&&&&&&&hello=world&&&&&&& {hello world}
101:
102: 13 test.db?&&&&&&&&hello=world&&&&&&& {}
103: 14 http:test.db?hello&world {}
104: } {
105:
106: if {$tcl_platform(platform) == "windows" && $tn>12} {
107: continue
108: }
109:
110: set ::arglist ""
111: set DB [sqlite3_open $uri]
112: do_test 2.$tn.1 { set ::arglist } $kvlist
113: sqlite3_close $DB
114:
115: sqlite3 db xxx.db
116: set ::arglist ""
117: execsql { ATTACH $uri AS aux }
118: do_test 2.$tn.2 { set ::arglist } $kvlist
119: db close
120: }
121: tvfs delete
122: tvfs2 delete
123:
124: #-------------------------------------------------------------------------
125: # Test that specifying a non-existent VFS raises an error.
126: #
127: do_test 3.1 {
128: list [catch { sqlite3 db "file:test.db?vfs=nosuchvfs" } msg] $msg
129: } {1 {no such vfs: nosuchvfs}}
130:
131: #-------------------------------------------------------------------------
132: # Test some of the other options (other than "vfs").
133: #
134: foreach {tn mode create_ok write_ok readonly_ok} {
135: 1 ro 0 0 1
136: 2 rw 0 1 0
137: 3 rwc 1 1 0
138: } {
139: catch { db close }
140: forcedelete test.db
141:
142: set A(1) {0 {}}
143: set A(0) {1 {unable to open database file}}
144: do_test 4.1.$tn.1 {
145: list [catch {sqlite3 db "file:test.db?mode=$mode"} msg] $msg
146: } $A($create_ok)
147:
148: catch { db close }
149: forcedelete test.db
150: sqlite3 db test.db
151: db eval { CREATE TABLE t1(a, b) }
152: db close
153:
154: set A(1) {0 {}}
155: set A(0) {1 {attempt to write a readonly database}}
156: do_test 4.1.$tn.2 {
157: sqlite3 db "file:test.db?mode=$mode"
158: catchsql { INSERT INTO t1 VALUES(1, 2) }
159: } $A($write_ok)
160:
161: set A(1) {0 {}}
162: set A(0) [list 1 "access mode not allowed: $mode"]
163: do_test 4.1.$tn.3 {
164: list [catch {sqlite3 db "file:test.db?mode=$mode" -readonly 1} msg] $msg
165: } $A($readonly_ok)
166: }
167:
168: set orig [sqlite3_enable_shared_cache]
169: foreach {tn options sc_default is_shared} {
170: 1 "" 1 1
171: 2 "cache=private" 1 0
172: 3 "cache=shared" 1 1
173: 4 "" 0 0
174: 5 "cache=private" 0 0
175: 6 "cache=shared" 0 1
176: } {
177: catch { db close }
178: forcedelete test.db
179:
180: sqlite3_enable_shared_cache 1
181: sqlite3 db2 test.db
182: db2 eval {CREATE TABLE t1(a, b)}
183:
184: sqlite3_enable_shared_cache $sc_default
185: sqlite3 db "file:test.db?$options"
186: db eval {SELECT * FROM t1}
187:
188: set A(1) {1 {database table is locked: t1}}
189: set A(0) {0 {}}
190: do_test 4.2.$tn {
191: db2 eval {BEGIN; INSERT INTO t1 VALUES(1, 2);}
192: catchsql { SELECT * FROM t1 }
193: } $A($is_shared)
194:
195: db2 close
196: }
197:
198: do_test 4.3.1 {
199: list [catch {sqlite3 db "file:test.db?mode=rc"} msg] $msg
200: } {1 {no such access mode: rc}}
201: do_test 4.3.2 {
202: list [catch {sqlite3 db "file:test.db?cache=public"} msg] $msg
203: } {1 {no such cache mode: public}}
204:
205: #-------------------------------------------------------------------------
206: # Test that things work if an ATTACHed database uses a different VFS than
207: # the main database. The important point is that for all operations
208: # involving the ATTACHed database, the correct versions of the following
209: # VFS are used for all operations involving the attached database.
210: #
211: # xOpen
212: # xDelete
213: # xAccess
214: # xFullPathname
215: #
216:
217: # This block of code creates two VFS - "tvfs1" and "tvfs2". Each time one
218: # of the above methods is called using "tvfs1", global variable ::T1(X) is
219: # set, where X is the file-name the method is called on. Calls to the above
220: # methods using "tvfs2" set entries in the global T2 array.
221: #
222: ifcapable wal {
223: testvfs tvfs1
224: tvfs1 filter {xOpen xDelete xAccess xFullPathname}
225: tvfs1 script tvfs1_callback
226: proc tvfs1_callback {method filename args} {
227: set ::T1([file tail $filename]) 1
228: }
229: testvfs tvfs2
230: tvfs2 filter {xOpen xDelete xAccess xFullPathname}
231: tvfs2 script tvfs2_callback
232: proc tvfs2_callback {method filename args} {
233: set ::T2([file tail $filename]) 1
234: }
235:
236: catch {db close}
237: eval forcedelete [glob test.db*]
238: do_test 5.1.1 {
239: sqlite3 db file:test.db1?vfs=tvfs1
240: execsql {
241: ATTACH 'file:test.db2?vfs=tvfs2' AS aux;
242: PRAGMA main.journal_mode = PERSIST;
243: PRAGMA aux.journal_mode = PERSIST;
244: CREATE TABLE t1(a, b);
245: CREATE TABLE aux.t2(a, b);
246: PRAGMA main.journal_mode = WAL;
247: PRAGMA aux.journal_mode = WAL;
248: INSERT INTO t1 VALUES('x', 'y');
249: INSERT INTO t2 VALUES('x', 'y');
250: }
251: lsort [array names ::T1]
252: } {test.db1 test.db1-journal test.db1-wal}
253:
254: do_test 5.1.2 {
255: lsort [array names ::T2]
256: } {test.db2 test.db2-journal test.db2-wal}
257: db close
258:
259: tvfs1 delete
260: tvfs2 delete
261: }
262:
263: #-------------------------------------------------------------------------
264: # Check that only "" and "localhost" are acceptable as authorities.
265: #
266: catch {db close}
267: foreach {tn uri res} {
268: 1 "file://localhost/PWD/test.db" {not an error}
269: 2 "file:///PWD/test.db" {not an error}
270: 3 "file:/PWD/test.db" {not an error}
271: 4 "file://l%6Fcalhost/PWD/test.db" {invalid uri authority: l%6Fcalhost}
272: 5 "file://lbcalhost/PWD/test.db" {invalid uri authority: lbcalhost}
273: 6 "file://x/PWD/test.db" {invalid uri authority: x}
274: } {
275:
276: if {$tcl_platform(platform)=="windows"} {
277: set uri [string map [list PWD [string range [pwd] 3 end]] $uri]
278: } else {
279: set uri [string map [list PWD [string range [pwd] 1 end]] $uri]
280: }
281:
282: do_test 6.$tn {
283: set DB [sqlite3_open $uri]
284: sqlite3_errmsg $DB
285: } $res
286: catch { sqlite3_close $DB }
287: }
288:
289: forcedelete test.db test.db2
290: do_test 7.1 {
291: sqlite3 db test.db
292: execsql {
293: CREATE TABLE t1(a, b);
294: INSERT INTO t1 VALUES(1, 2);
295: ATTACH 'test.db2' AS aux;
296: CREATE TABLE aux.t2(a, b);
297: INSERT INTO t1 VALUES('a', 'b');
298: }
299: db close
300: } {}
301: do_test 7.2 {
302: sqlite3 db file:test.db?mode=ro
303: execsql { ATTACH 'file:test.db2?mode=rw' AS aux }
304: } {}
305: do_execsql_test 7.3 {
306: INSERT INTO t2 VALUES('c', 'd')
307: } {}
308: do_catchsql_test 7.4 {
309: INSERT INTO t1 VALUES(3, 4)
310: } {1 {attempt to write a readonly database}}
311:
312: finish_test
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>