wasCSharpSQLite – Blame information for rev 7
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | # 2011 May 06 |
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 | set testprefix e_uri |
||
16 | |||
17 | db close |
||
18 | |||
19 | proc parse_uri {uri} { |
||
20 | testvfs tvfs2 |
||
21 | testvfs tvfs |
||
22 | tvfs filter xOpen |
||
23 | tvfs script parse_uri_open_cb |
||
24 | |||
25 | set ::uri_open [list] |
||
26 | set DB [sqlite3_open_v2 $uri { |
||
27 | SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE SQLITE_OPEN_WAL |
||
28 | } tvfs] |
||
29 | sqlite3_close $DB |
||
30 | tvfs delete |
||
31 | tvfs2 delete |
||
32 | |||
33 | set ::uri_open |
||
34 | } |
||
35 | proc parse_uri_open_cb {method file arglist} { |
||
36 | set ::uri_open [list $file $arglist] |
||
37 | } |
||
38 | |||
39 | proc open_uri_error {uri} { |
||
40 | set flags {SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE SQLITE_OPEN_WAL} |
||
41 | set DB [sqlite3_open_v2 $uri $flags ""] |
||
42 | set e [sqlite3_errmsg $DB] |
||
43 | sqlite3_close $DB |
||
44 | set e |
||
45 | } |
||
46 | |||
47 | # EVIDENCE-OF: R-35840-33204 If URI filename interpretation is enabled, |
||
48 | # and the filename argument begins with "file:", then the filename is |
||
49 | # interpreted as a URI. |
||
50 | # |
||
51 | # EVIDENCE-OF: R-24124-56960 URI filename interpretation is enabled if |
||
52 | # the SQLITE_OPEN_URI flag is set in the fourth argument to |
||
53 | # sqlite3_open_v2(), or if it has been enabled globally using the |
||
54 | # SQLITE_CONFIG_URI option with the sqlite3_config() method or by the |
||
55 | # SQLITE_USE_URI compile-time option. |
||
56 | # |
||
57 | if {$tcl_platform(platform) == "unix"} { |
||
58 | set flags [list SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE] |
||
59 | |||
60 | # Tests with SQLITE_CONFIG_URI configured to false. URI intepretation is |
||
61 | # only enabled if the SQLITE_OPEN_URI flag is specified. |
||
62 | sqlite3_shutdown |
||
63 | sqlite3_config_uri 0 |
||
64 | do_test 1.1 { |
||
65 | forcedelete file:test.db test.db |
||
66 | set DB [sqlite3_open_v2 file:test.db [concat $flags SQLITE_OPEN_URI] ""] |
||
67 | list [file exists file:test.db] [file exists test.db] |
||
68 | } {0 1} |
||
69 | do_test 1.2 { |
||
70 | forcedelete file:test.db2 test.db2 |
||
71 | set STMT [sqlite3_prepare $DB "ATTACH 'file:test.db2' AS aux" -1 dummy] |
||
72 | sqlite3_step $STMT |
||
73 | sqlite3_finalize $STMT |
||
74 | list [file exists file:test.db2] [file exists test.db2] |
||
75 | } {0 1} |
||
76 | sqlite3_close $DB |
||
77 | do_test 1.3 { |
||
78 | forcedelete file:test.db test.db |
||
79 | set DB [sqlite3_open_v2 file:test.db [concat $flags] ""] |
||
80 | list [file exists file:test.db] [file exists test.db] |
||
81 | } {1 0} |
||
82 | do_test 1.4 { |
||
83 | forcedelete file:test.db2 test.db2 |
||
84 | set STMT [sqlite3_prepare $DB "ATTACH 'file:test.db2' AS aux" -1 dummy] |
||
85 | sqlite3_step $STMT |
||
86 | sqlite3_finalize $STMT |
||
87 | list [file exists file:test.db2] [file exists test.db2] |
||
88 | } {1 0} |
||
89 | sqlite3_close $DB |
||
90 | |||
91 | # Tests with SQLITE_CONFIG_URI configured to true. URI intepretation is |
||
92 | # enabled with or without SQLITE_OPEN_URI. |
||
93 | # |
||
94 | sqlite3_shutdown |
||
95 | sqlite3_config_uri 1 |
||
96 | do_test 1.5 { |
||
97 | forcedelete file:test.db test.db |
||
98 | set DB [sqlite3_open_v2 file:test.db [concat $flags SQLITE_OPEN_URI] ""] |
||
99 | list [file exists file:test.db] [file exists test.db] |
||
100 | } {0 1} |
||
101 | do_test 1.6 { |
||
102 | forcedelete file:test.db2 test.db2 |
||
103 | set STMT [sqlite3_prepare $DB "ATTACH 'file:test.db2' AS aux" -1 dummy] |
||
104 | sqlite3_step $STMT |
||
105 | sqlite3_finalize $STMT |
||
106 | list [file exists file:test.db2] [file exists test.db2] |
||
107 | } {0 1} |
||
108 | sqlite3_close $DB |
||
109 | do_test 1.7 { |
||
110 | forcedelete file:test.db test.db |
||
111 | set DB [sqlite3_open_v2 file:test.db [concat $flags] ""] |
||
112 | list [file exists file:test.db] [file exists test.db] |
||
113 | } {0 1} |
||
114 | do_test 1.8 { |
||
115 | forcedelete file:test.db2 test.db2 |
||
116 | set STMT [sqlite3_prepare $DB "ATTACH 'file:test.db2' AS aux" -1 dummy] |
||
117 | sqlite3_step $STMT |
||
118 | sqlite3_finalize $STMT |
||
119 | list [file exists file:test.db2] [file exists test.db2] |
||
120 | } {0 1} |
||
121 | sqlite3_close $DB |
||
122 | } |
||
123 | |||
124 | # ensure uri processing enabled for the rest of the tests |
||
125 | sqlite3_shutdown |
||
126 | sqlite3_config_uri 1 |
||
127 | |||
128 | # EVIDENCE-OF: R-17482-00398 If the authority is not an empty string or |
||
129 | # "localhost", an error is returned to the caller. |
||
130 | # |
||
131 | if {$tcl_platform(platform) == "unix"} { |
||
132 | set flags [list SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE SQLITE_OPEN_URI] |
||
133 | foreach {tn uri error} " |
||
134 | 1 {file://localhost[pwd]/test.db} {not an error} |
||
135 | 2 {file://[pwd]/test.db} {not an error} |
||
136 | 3 {file://x[pwd]/test.db} {invalid uri authority: x} |
||
137 | 4 {file://invalid[pwd]/test.db} {invalid uri authority: invalid} |
||
138 | " { |
||
139 | do_test 2.$tn { |
||
140 | set DB [sqlite3_open_v2 $uri $flags ""] |
||
141 | set e [sqlite3_errmsg $DB] |
||
142 | sqlite3_close $DB |
||
143 | set e |
||
144 | } $error |
||
145 | } |
||
146 | } |
||
147 | |||
148 | # EVIDENCE-OF: R-45981-25528 The fragment component of a URI, if |
||
149 | # present, is ignored. |
||
150 | # |
||
151 | # It is difficult to test that something is ignored correctly. So these tests |
||
152 | # just show that adding a fragment does not interfere with the pathname or |
||
153 | # parameters passed through to the VFS xOpen() methods. |
||
154 | # |
||
155 | foreach {tn uri parse} " |
||
156 | 1 {file:test.db#abc} {[pwd]/test.db {}} |
||
157 | 2 {file:test.db?a=b#abc} {[pwd]/test.db {a b}} |
||
158 | 3 {file:test.db?a=b#?c=d} {[pwd]/test.db {a b}} |
||
159 | " { |
||
160 | do_filepath_test 3.$tn { parse_uri $uri } $parse |
||
161 | } |
||
162 | |||
163 | # EVIDENCE-OF: R-62557-09390 SQLite uses the path component of the URI |
||
164 | # as the name of the disk file which contains the database. |
||
165 | # |
||
166 | # EVIDENCE-OF: R-28659-11035 If the path begins with a '/' character, |
||
167 | # then it is interpreted as an absolute path. |
||
168 | # |
||
169 | # EVIDENCE-OF: R-46234-61323 If the path does not begin with a '/' |
||
170 | # (meaning that the authority section is omitted from the URI) then the |
||
171 | # path is interpreted as a relative path. |
||
172 | # |
||
173 | foreach {tn uri parse} " |
||
174 | 1 {file:test.db} {[pwd]/test.db {}} |
||
175 | 2 {file:/test.db} {/test.db {}} |
||
176 | 3 {file:///test.db} {/test.db {}} |
||
177 | 4 {file://localhost/test.db} {/test.db {}} |
||
178 | 5 {file:/a/b/c/test.db} {/a/b/c/test.db {}} |
||
179 | " { |
||
180 | do_filepath_test 4.$tn { parse_uri $uri } $parse |
||
181 | } |
||
182 | |||
183 | # EVIDENCE-OF: R-01612-30877 The "vfs" parameter may be used to specify |
||
184 | # the name of a VFS object that provides the operating system interface |
||
185 | # that should be used to access the database file on disk. |
||
186 | # |
||
187 | # The above is tested by cases 1.* below. |
||
188 | # |
||
189 | # EVIDENCE-OF: R-52293-58497 If this option is set to an empty string |
||
190 | # the default VFS object is used. |
||
191 | # |
||
192 | # The above is tested by cases 2.* below. |
||
193 | # |
||
194 | # EVIDENCE-OF: R-31855-18665 If sqlite3_open_v2() is used and the vfs |
||
195 | # option is present, then the VFS specified by the option takes |
||
196 | # precedence over the value passed as the fourth parameter to |
||
197 | # sqlite3_open_v2(). |
||
198 | # |
||
199 | # The above is tested by cases 3.* below. |
||
200 | # |
||
201 | proc vfs_open_cb {name args} { |
||
202 | set ::vfs $name |
||
203 | } |
||
204 | foreach {name default} {vfs1 0 vfs2 0 vfs3 1} { |
||
205 | testvfs $name -default $default |
||
206 | $name filter xOpen |
||
207 | $name script [list vfs_open_cb $name] |
||
208 | } |
||
209 | foreach {tn uri defvfs vfs} { |
||
210 | 1.1 "file:test.db?vfs=vfs1" "" vfs1 |
||
211 | 1.2 "file:test.db?vfs=vfs2" "" vfs2 |
||
212 | |||
213 | 2.1 "file:test.db" vfs1 vfs1 |
||
214 | 2.2 "file:test.db?vfs=" vfs1 vfs3 |
||
215 | |||
216 | 3.1 "file:test.db?vfs=vfs1" vfs2 vfs1 |
||
217 | 3.2 "file:test.db?vfs=vfs2" vfs1 vfs2 |
||
218 | 3.3 "file:test.db?xvfs=vfs1" vfs2 vfs2 |
||
219 | 3.4 "file:test.db?xvfs=vfs2" vfs1 vfs1 |
||
220 | } { |
||
221 | do_test 5.$tn { |
||
222 | set flags [list SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE SQLITE_OPEN_URI] |
||
223 | sqlite3_close [ |
||
224 | sqlite3_open_v2 $uri $flags $defvfs |
||
225 | ] |
||
226 | set ::vfs |
||
227 | } $vfs |
||
228 | } |
||
229 | vfs1 delete |
||
230 | vfs2 delete |
||
231 | vfs3 delete |
||
232 | |||
233 | # EVIDENCE-OF: R-48365-36308 Specifying an unknown VFS is an error. |
||
234 | # |
||
235 | set flags [list SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE SQLITE_OPEN_URI] |
||
236 | do_test 6.1 { |
||
237 | set DB [sqlite3_open_v2 file:test.db?vfs=nosuchvfs $flags ""] |
||
238 | set errmsg [sqlite3_errmsg $DB] |
||
239 | sqlite3_close $DB |
||
240 | set errmsg |
||
241 | } {no such vfs: nosuchvfs} |
||
242 | |||
243 | |||
244 | # EVIDENCE-OF: R-60479-64270 The mode parameter may be set to either |
||
245 | # "ro", "rw" or "rwc". Attempting to set it to any other value is an |
||
246 | # error |
||
247 | # |
||
248 | sqlite3 db test.db |
||
249 | db close |
||
250 | foreach {tn uri error} " |
||
251 | 1 {file:test.db?mode=ro} {not an error} |
||
252 | 2 {file:test.db?mode=rw} {not an error} |
||
253 | 3 {file:test.db?mode=rwc} {not an error} |
||
254 | 4 {file:test.db?mode=Ro} {no such access mode: Ro} |
||
255 | 5 {file:test.db?mode=Rw} {no such access mode: Rw} |
||
256 | 6 {file:test.db?mode=Rwc} {no such access mode: Rwc} |
||
257 | " { |
||
258 | do_test 7.$tn { open_uri_error $uri } $error |
||
259 | } |
||
260 | |||
261 | |||
262 | # EVIDENCE-OF: R-09651-31805 If "ro" is specified, then the database is |
||
263 | # opened for read-only access, just as if the SQLITE_OPEN_READONLY flag |
||
264 | # had been set in the third argument to sqlite3_prepare_v2(). |
||
265 | # |
||
266 | # EVIDENCE-OF: R-40137-26050 If the mode option is set to "rw", then the |
||
267 | # database is opened for read-write (but not create) access, as if |
||
268 | # SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had been set. |
||
269 | # |
||
270 | # EVIDENCE-OF: R-26845-32976 Value "rwc" is equivalent to setting both |
||
271 | # SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. |
||
272 | # |
||
273 | foreach {tn uri read write create} { |
||
274 | 1 {file:test.db?mode=ro} 1 0 0 |
||
275 | 2 {file:test.db?mode=rw} 1 1 0 |
||
276 | 3 {file:test.db?mode=rwc} 1 1 1 |
||
277 | } { |
||
278 | set RES(c,0) {1 {unable to open database file}} |
||
279 | set RES(c,1) {0 {}} |
||
280 | set RES(w,0) {1 {attempt to write a readonly database}} |
||
281 | set RES(w,1) {0 {}} |
||
282 | set RES(r,0) {1 {this never happens}} |
||
283 | set RES(r,1) {0 {a b}} |
||
284 | |||
285 | # Test CREATE access: |
||
286 | forcedelete test.db |
||
287 | do_test 8.$tn.c { list [catch { sqlite3 db $uri } msg] $msg } $RES(c,$create) |
||
288 | catch { db close } |
||
289 | |||
290 | sqlite3 db test.db |
||
291 | db eval { CREATE TABLE t1(a, b) ; INSERT INTO t1 VALUES('a', 'b') ;} |
||
292 | db close |
||
293 | |||
294 | # Test READ access: |
||
295 | do_test 8.$tn.r { |
||
296 | sqlite3 db $uri |
||
297 | catchsql { SELECT * FROM t1 } |
||
298 | } $RES(r,$read) |
||
299 | |||
300 | # Test WRITE access: |
||
301 | do_test 8.$tn.w { |
||
302 | sqlite3 db $uri |
||
303 | catchsql { INSERT INTO t1 VALUES(1, 2) } |
||
304 | } $RES(w,$write) |
||
305 | |||
306 | catch {db close} |
||
307 | } |
||
308 | |||
309 | # EVIDENCE-OF: R-56032-32287 If sqlite3_open_v2() is used, it is an |
||
310 | # error to specify a value for the mode parameter that is less |
||
311 | # restrictive than that specified by the flags passed as the third |
||
312 | # parameter. |
||
313 | # |
||
314 | forcedelete test.db |
||
315 | sqlite3 db test.db |
||
316 | db close |
||
317 | foreach {tn uri flags error} { |
||
318 | 1 {file:test.db?mode=ro} ro {not an error} |
||
319 | 2 {file:test.db?mode=ro} rw {not an error} |
||
320 | 3 {file:test.db?mode=ro} rwc {not an error} |
||
321 | |||
322 | 4 {file:test.db?mode=rw} ro {access mode not allowed: rw} |
||
323 | 5 {file:test.db?mode=rw} rw {not an error} |
||
324 | 6 {file:test.db?mode=rw} rwc {not an error} |
||
325 | |||
326 | 7 {file:test.db?mode=rwc} ro {access mode not allowed: rwc} |
||
327 | 8 {file:test.db?mode=rwc} rw {access mode not allowed: rwc} |
||
328 | 9 {file:test.db?mode=rwc} rwc {not an error} |
||
329 | } { |
||
330 | set f(ro) [list SQLITE_OPEN_READONLY SQLITE_OPEN_URI] |
||
331 | set f(rw) [list SQLITE_OPEN_READWRITE SQLITE_OPEN_URI] |
||
332 | set f(rwc) [list SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE SQLITE_OPEN_URI] |
||
333 | |||
334 | set DB [sqlite3_open_v2 $uri $f($flags) ""] |
||
335 | set e [sqlite3_errmsg $DB] |
||
336 | sqlite3_close $DB |
||
337 | |||
338 | do_test 9.$tn { set e } $error |
||
339 | } |
||
340 | |||
341 | # EVIDENCE-OF: R-23182-54295 The cache parameter may be set to either |
||
342 | # "shared" or "private". |
||
343 | sqlite3 db test.db |
||
344 | db close |
||
345 | foreach {tn uri error} " |
||
346 | 1 {file:test.db?cache=private} {not an error} |
||
347 | 2 {file:test.db?cache=shared} {not an error} |
||
348 | 3 {file:test.db?cache=yes} {no such cache mode: yes} |
||
349 | 4 {file:test.db?cache=} {no such cache mode: } |
||
350 | " { |
||
351 | do_test 10.$tn { open_uri_error $uri } $error |
||
352 | } |
||
353 | |||
354 | # EVIDENCE-OF: R-23027-03515 Setting it to "shared" is equivalent to |
||
355 | # setting the SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed |
||
356 | # to sqlite3_open_v2(). |
||
357 | # |
||
358 | # EVIDENCE-OF: R-49793-28525 Setting the cache parameter to "private" is |
||
359 | # equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit. |
||
360 | # |
||
361 | # EVIDENCE-OF: R-19510-48080 If sqlite3_open_v2() is used and the |
||
362 | # "cache" parameter is present in a URI filename, its value overrides |
||
363 | # any behaviour requested by setting SQLITE_OPEN_PRIVATECACHE or |
||
364 | # SQLITE_OPEN_SHAREDCACHE flag. |
||
365 | # |
||
366 | set orig [sqlite3_enable_shared_cache] |
||
367 | foreach {tn uri flags shared_default isshared} { |
||
368 | 1.1 "file:test.db" "" 0 0 |
||
369 | 1.2 "file:test.db" "" 1 1 |
||
370 | 1.3 "file:test.db" private 0 0 |
||
371 | 1.4 "file:test.db" private 1 0 |
||
372 | 1.5 "file:test.db" shared 0 1 |
||
373 | 1.6 "file:test.db" shared 1 1 |
||
374 | |||
375 | 2.1 "file:test.db?cache=private" "" 0 0 |
||
376 | 2.2 "file:test.db?cache=private" "" 1 0 |
||
377 | 2.3 "file:test.db?cache=private" private 0 0 |
||
378 | 2.4 "file:test.db?cache=private" private 1 0 |
||
379 | 2.5 "file:test.db?cache=private" shared 0 0 |
||
380 | 2.6 "file:test.db?cache=private" shared 1 0 |
||
381 | |||
382 | 3.1 "file:test.db?cache=shared" "" 0 1 |
||
383 | 3.2 "file:test.db?cache=shared" "" 1 1 |
||
384 | 3.3 "file:test.db?cache=shared" private 0 1 |
||
385 | 3.4 "file:test.db?cache=shared" private 1 1 |
||
386 | 3.5 "file:test.db?cache=shared" shared 0 1 |
||
387 | 3.6 "file:test.db?cache=shared" shared 1 1 |
||
388 | } { |
||
389 | forcedelete test.db |
||
390 | sqlite3_enable_shared_cache 1 |
||
391 | sqlite3 db test.db |
||
392 | sqlite3_enable_shared_cache 0 |
||
393 | |||
394 | db eval { |
||
395 | CREATE TABLE t1(x); |
||
396 | INSERT INTO t1 VALUES('ok'); |
||
397 | } |
||
398 | |||
399 | unset -nocomplain f |
||
400 | set f() {SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE SQLITE_OPEN_URI} |
||
401 | set f(shared) [concat $f() SQLITE_OPEN_SHAREDCACHE] |
||
402 | set f(private) [concat $f() SQLITE_OPEN_PRIVATECACHE] |
||
403 | |||
404 | sqlite3_enable_shared_cache $shared_default |
||
405 | set DB [sqlite3_open_v2 $uri $f($flags) ""] |
||
406 | |||
407 | set STMT [sqlite3_prepare $DB "SELECT * FROM t1" -1 dummy] |
||
408 | |||
409 | db eval { |
||
410 | BEGIN; |
||
411 | INSERT INTO t1 VALUES('ko'); |
||
412 | } |
||
413 | |||
414 | sqlite3_step $STMT |
||
415 | sqlite3_finalize $STMT |
||
416 | |||
417 | set RES(0) {not an error} |
||
418 | set RES(1) {database table is locked: t1} |
||
419 | |||
420 | do_test 11.$tn { sqlite3_errmsg $DB } $RES($isshared) |
||
421 | |||
422 | sqlite3_close $DB |
||
423 | db close |
||
424 | } |
||
425 | sqlite3_enable_shared_cache $orig |
||
426 | |||
427 | # EVIDENCE-OF: R-63472-46769 Specifying an unknown parameter in the |
||
428 | # query component of a URI is not an error. |
||
429 | # |
||
430 | do_filepath_test 12.1 { |
||
431 | parse_uri file://localhost/test.db?an=unknown¶meter=is&ok= |
||
432 | } {/test.db {an unknown parameter is ok {}}} |
||
433 | do_filepath_test 12.2 { |
||
434 | parse_uri file://localhost/test.db?an&unknown¶meter&is&ok |
||
435 | } {/test.db {an {} unknown {} parameter {} is {} ok {}}} |
||
436 | |||
437 | # EVIDENCE-OF: R-27458-04043 URI hexadecimal escape sequences (%HH) are |
||
438 | # supported within the path and query components of a URI. |
||
439 | # |
||
440 | # EVIDENCE-OF: R-52765-50368 Before the path or query components of a |
||
441 | # URI filename are interpreted, they are encoded using UTF-8 and all |
||
442 | # hexadecimal escape sequences replaced by a single byte containing the |
||
443 | # corresponding octet. |
||
444 | # |
||
445 | # The second of the two statements above is tested by creating a |
||
446 | # multi-byte utf-8 character using a sequence of %HH escapes. |
||
447 | # |
||
448 | foreach {tn uri parse} " |
||
449 | 1 {file:/test.%64%62} {/test.db {}} |
||
450 | 2 {file:/test.db?%68%65%6c%6c%6f=%77%6f%72%6c%64} {/test.db {hello world}} |
||
451 | 3 {file:/%C3%BF.db} {/\xFF.db {}} |
||
452 | " { |
||
453 | do_filepath_test 13.$tn { parse_uri $uri } $parse |
||
454 | } |
||
455 | |||
456 | finish_test |