diff options
author | dan miller | 2007-10-20 02:49:29 +0000 |
---|---|---|
committer | dan miller | 2007-10-20 02:49:29 +0000 |
commit | e36d23a85ebff914d74bb541558c2b6082b78edb (patch) | |
tree | 54b58fdf162e78af64055282a6035c8d2443389d /libraries/sqlite/unix/sqlite-3.5.1/test/incrblob.test | |
parent | * Fixed an issue whereby avatar chat distances were being calculated against ... (diff) | |
download | opensim-SC-e36d23a85ebff914d74bb541558c2b6082b78edb.zip opensim-SC-e36d23a85ebff914d74bb541558c2b6082b78edb.tar.gz opensim-SC-e36d23a85ebff914d74bb541558c2b6082b78edb.tar.bz2 opensim-SC-e36d23a85ebff914d74bb541558c2b6082b78edb.tar.xz |
sqlite source (unix build) added to libraries
Diffstat (limited to 'libraries/sqlite/unix/sqlite-3.5.1/test/incrblob.test')
-rw-r--r-- | libraries/sqlite/unix/sqlite-3.5.1/test/incrblob.test | 597 |
1 files changed, 597 insertions, 0 deletions
diff --git a/libraries/sqlite/unix/sqlite-3.5.1/test/incrblob.test b/libraries/sqlite/unix/sqlite-3.5.1/test/incrblob.test new file mode 100644 index 0000000..28d7132 --- /dev/null +++ b/libraries/sqlite/unix/sqlite-3.5.1/test/incrblob.test | |||
@@ -0,0 +1,597 @@ | |||
1 | # 2007 May 1 | ||
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 | # $Id: incrblob.test,v 1.16 2007/09/03 16:45:36 drh Exp $ | ||
13 | # | ||
14 | |||
15 | set testdir [file dirname $argv0] | ||
16 | source $testdir/tester.tcl | ||
17 | |||
18 | ifcapable {!autovacuum || !pragma || !incrblob} { | ||
19 | finish_test | ||
20 | return | ||
21 | } | ||
22 | |||
23 | do_test incrblob-1.1 { | ||
24 | execsql { | ||
25 | CREATE TABLE blobs(k PRIMARY KEY, v BLOB); | ||
26 | INSERT INTO blobs VALUES('one', X'0102030405060708090A'); | ||
27 | INSERT INTO blobs VALUES('two', X'0A090807060504030201'); | ||
28 | } | ||
29 | } {} | ||
30 | |||
31 | do_test incrblob-1.2.1 { | ||
32 | set ::blob [db incrblob blobs v 1] | ||
33 | string match incrblob_* $::blob | ||
34 | } {1} | ||
35 | do_test incrblob-1.2.2 { | ||
36 | binary scan [read $::blob] c* data | ||
37 | set data | ||
38 | } {1 2 3 4 5 6 7 8 9 10} | ||
39 | do_test incrblob-1.2.3 { | ||
40 | seek $::blob 0 | ||
41 | puts -nonewline $::blob "1234567890" | ||
42 | flush $::blob | ||
43 | } {} | ||
44 | do_test incrblob-1.2.4 { | ||
45 | seek $::blob 0 | ||
46 | binary scan [read $::blob] c* data | ||
47 | set data | ||
48 | } {49 50 51 52 53 54 55 56 57 48} | ||
49 | do_test incrblob-1.2.5 { | ||
50 | close $::blob | ||
51 | } {} | ||
52 | do_test incrblob-1.2.6 { | ||
53 | execsql { | ||
54 | SELECT v FROM blobs WHERE rowid = 1; | ||
55 | } | ||
56 | } {1234567890} | ||
57 | |||
58 | #-------------------------------------------------------------------- | ||
59 | # Test cases incrblob-1.3.X check that it is possible to read and write | ||
60 | # regions of a blob that lie on overflow pages. | ||
61 | # | ||
62 | do_test incrblob-1.3.1 { | ||
63 | set ::str "[string repeat . 10000]" | ||
64 | execsql { | ||
65 | INSERT INTO blobs(rowid, k, v) VALUES(3, 'three', $::str); | ||
66 | } | ||
67 | } {} | ||
68 | |||
69 | do_test incrblob-1.3.2 { | ||
70 | set ::blob [db incrblob blobs v 3] | ||
71 | seek $::blob 8500 | ||
72 | read $::blob 10 | ||
73 | } {..........} | ||
74 | do_test incrblob-1.3.3 { | ||
75 | seek $::blob 8500 | ||
76 | puts -nonewline $::blob 1234567890 | ||
77 | } {} | ||
78 | do_test incrblob-1.3.4 { | ||
79 | seek $::blob 8496 | ||
80 | read $::blob 10 | ||
81 | } {....123456} | ||
82 | do_test incrblob-1.3.10 { | ||
83 | close $::blob | ||
84 | } {} | ||
85 | |||
86 | |||
87 | #------------------------------------------------------------------------ | ||
88 | # incrblob-2.*: | ||
89 | # | ||
90 | # Test that the following operations use ptrmap pages to reduce | ||
91 | # unnecessary reads: | ||
92 | # | ||
93 | # * Reading near the end of a blob, | ||
94 | # * Writing near the end of a blob, and | ||
95 | # * SELECT a column value that is located on an overflow page. | ||
96 | # | ||
97 | proc nRead {db} { | ||
98 | set bt [btree_from_db $db] | ||
99 | db_enter $db | ||
100 | array set stats [btree_pager_stats $bt] | ||
101 | db_leave $db | ||
102 | return $stats(read) | ||
103 | } | ||
104 | proc nWrite {db} { | ||
105 | set bt [btree_from_db $db] | ||
106 | db_enter $db | ||
107 | array set stats [btree_pager_stats $bt] | ||
108 | db_leave $db | ||
109 | return $stats(write) | ||
110 | } | ||
111 | |||
112 | sqlite3_soft_heap_limit 0 | ||
113 | |||
114 | foreach AutoVacuumMode [list 0 1] { | ||
115 | |||
116 | if {$AutoVacuumMode>0} { | ||
117 | ifcapable !autovacuum { | ||
118 | break | ||
119 | } | ||
120 | } | ||
121 | |||
122 | db close | ||
123 | file delete -force test.db test.db-journal | ||
124 | |||
125 | sqlite3 db test.db | ||
126 | execsql "PRAGMA auto_vacuum = $AutoVacuumMode" | ||
127 | |||
128 | do_test incrblob-2.$AutoVacuumMode.1 { | ||
129 | set ::str [string repeat abcdefghij 2900] | ||
130 | execsql { | ||
131 | BEGIN; | ||
132 | CREATE TABLE blobs(k PRIMARY KEY, v BLOB, i INTEGER); | ||
133 | DELETE FROM blobs; | ||
134 | INSERT INTO blobs VALUES('one', $::str || randstr(500,500), 45); | ||
135 | COMMIT; | ||
136 | } | ||
137 | expr [file size test.db]/1024 | ||
138 | } [expr 31 + $AutoVacuumMode] | ||
139 | |||
140 | ifcapable autovacuum { | ||
141 | do_test incrblob-2.$AutoVacuumMode.2 { | ||
142 | execsql { | ||
143 | PRAGMA auto_vacuum; | ||
144 | } | ||
145 | } $AutoVacuumMode | ||
146 | } | ||
147 | |||
148 | do_test incrblob-2.$AutoVacuumMode.3 { | ||
149 | # Open and close the db to make sure the page cache is empty. | ||
150 | db close | ||
151 | sqlite3 db test.db | ||
152 | |||
153 | # Read the last 20 bytes of the blob via a blob handle. | ||
154 | set ::blob [db incrblob blobs v 1] | ||
155 | seek $::blob -20 end | ||
156 | set ::fragment [read $::blob] | ||
157 | close $::blob | ||
158 | |||
159 | # If the database is not in auto-vacuum mode, the whole of | ||
160 | # the overflow-chain must be scanned. In auto-vacuum mode, | ||
161 | # sqlite uses the ptrmap pages to avoid reading the other pages. | ||
162 | # | ||
163 | nRead db | ||
164 | } [expr $AutoVacuumMode ? 4 : 30] | ||
165 | |||
166 | do_test incrblob-2.$AutoVacuumMode.4 { | ||
167 | string range [db one {SELECT v FROM blobs}] end-19 end | ||
168 | } $::fragment | ||
169 | |||
170 | do_test incrblob-2.$AutoVacuumMode.5 { | ||
171 | # Open and close the db to make sure the page cache is empty. | ||
172 | db close | ||
173 | sqlite3 db test.db | ||
174 | |||
175 | # Write the second-to-last 20 bytes of the blob via a blob handle. | ||
176 | # | ||
177 | set ::blob [db incrblob blobs v 1] | ||
178 | seek $::blob -40 end | ||
179 | puts -nonewline $::blob "1234567890abcdefghij" | ||
180 | flush $::blob | ||
181 | |||
182 | # If the database is not in auto-vacuum mode, the whole of | ||
183 | # the overflow-chain must be scanned. In auto-vacuum mode, | ||
184 | # sqlite uses the ptrmap pages to avoid reading the other pages. | ||
185 | # | ||
186 | nRead db | ||
187 | } [expr $AutoVacuumMode ? 4 : 30] | ||
188 | |||
189 | # Pages 1 (the write-counter) and 32 (the blob data) were written. | ||
190 | do_test incrblob-2.$AutoVacuumMode.6 { | ||
191 | close $::blob | ||
192 | nWrite db | ||
193 | } 2 | ||
194 | |||
195 | do_test incrblob-2.$AutoVacuumMode.7 { | ||
196 | string range [db one {SELECT v FROM blobs}] end-39 end-20 | ||
197 | } "1234567890abcdefghij" | ||
198 | |||
199 | do_test incrblob-2.$AutoVacuumMode.8 { | ||
200 | # Open and close the db to make sure the page cache is empty. | ||
201 | db close | ||
202 | sqlite3 db test.db | ||
203 | |||
204 | execsql { SELECT i FROM blobs } | ||
205 | } {45} | ||
206 | |||
207 | do_test incrblob-2.$AutoVacuumMode.9 { | ||
208 | nRead db | ||
209 | } [expr $AutoVacuumMode ? 4 : 30] | ||
210 | } | ||
211 | sqlite3_soft_heap_limit $soft_limit | ||
212 | |||
213 | #------------------------------------------------------------------------ | ||
214 | # incrblob-3.*: | ||
215 | # | ||
216 | # Test the outcome of trying to write to a read-only blob handle. | ||
217 | # | ||
218 | do_test incrblob-3.1 { | ||
219 | set ::blob [db incrblob -readonly blobs v 1] | ||
220 | seek $::blob -40 end | ||
221 | read $::blob 20 | ||
222 | } "1234567890abcdefghij" | ||
223 | do_test incrblob-3.2 { | ||
224 | seek $::blob 0 | ||
225 | set rc [catch { | ||
226 | puts -nonewline $::blob "helloworld" | ||
227 | } msg] | ||
228 | close $::blob | ||
229 | list $rc $msg | ||
230 | } "1 {channel \"$::blob\" wasn't opened for writing}" | ||
231 | |||
232 | do_test incrblob-3.3 { | ||
233 | set ::blob [db incrblob -readonly blobs v 1] | ||
234 | seek $::blob -40 end | ||
235 | read $::blob 20 | ||
236 | } "1234567890abcdefghij" | ||
237 | do_test incrblob-3.4 { | ||
238 | set rc [catch { | ||
239 | sqlite3_blob_write $::blob 20 "qwertyuioplkjhgfds" | ||
240 | } msg] | ||
241 | list $rc $msg | ||
242 | } {1 SQLITE_READONLY} | ||
243 | catch {close $::blob} | ||
244 | |||
245 | #------------------------------------------------------------------------ | ||
246 | # incrblob-4.*: | ||
247 | # | ||
248 | # Try a couple of error conditions: | ||
249 | # | ||
250 | # 4.1 - Attempt to open a row that does not exist. | ||
251 | # 4.2 - Attempt to open a column that does not exist. | ||
252 | # 4.3 - Attempt to open a table that does not exist. | ||
253 | # 4.4 - Attempt to open a database that does not exist. | ||
254 | # | ||
255 | # 4.5 - Attempt to open an integer | ||
256 | # 4.6 - Attempt to open a real value | ||
257 | # 4.7 - Attempt to open an SQL null | ||
258 | # | ||
259 | # 4.8 - Attempt to open an indexed column for writing | ||
260 | # 4.9 - Attempt to open an indexed column for reading (this works) | ||
261 | # | ||
262 | do_test incrblob-4.1 { | ||
263 | set rc [catch { | ||
264 | set ::blob [db incrblob blobs v 2] | ||
265 | } msg ] | ||
266 | list $rc $msg | ||
267 | } {1 {no such rowid: 2}} | ||
268 | do_test incrblob-4.2 { | ||
269 | set rc [catch { | ||
270 | set ::blob [db incrblob blobs blue 1] | ||
271 | } msg ] | ||
272 | list $rc $msg | ||
273 | } {1 {no such column: "blue"}} | ||
274 | do_test incrblob-4.3 { | ||
275 | set rc [catch { | ||
276 | set ::blob [db incrblob nosuchtable blue 1] | ||
277 | } msg ] | ||
278 | list $rc $msg | ||
279 | } {1 {no such table: main.nosuchtable}} | ||
280 | do_test incrblob-4.4 { | ||
281 | set rc [catch { | ||
282 | set ::blob [db incrblob nosuchdb blobs v 1] | ||
283 | } msg ] | ||
284 | list $rc $msg | ||
285 | } {1 {no such table: nosuchdb.blobs}} | ||
286 | |||
287 | do_test incrblob-4.5 { | ||
288 | set rc [catch { | ||
289 | set ::blob [db incrblob blobs i 1] | ||
290 | } msg ] | ||
291 | list $rc $msg | ||
292 | } {1 {cannot open value of type integer}} | ||
293 | do_test incrblob-4.6 { | ||
294 | execsql { | ||
295 | INSERT INTO blobs(k, v, i) VALUES(123, 567.765, NULL); | ||
296 | } | ||
297 | set rc [catch { | ||
298 | set ::blob [db incrblob blobs v 2] | ||
299 | } msg ] | ||
300 | list $rc $msg | ||
301 | } {1 {cannot open value of type real}} | ||
302 | do_test incrblob-4.7 { | ||
303 | set rc [catch { | ||
304 | set ::blob [db incrblob blobs i 2] | ||
305 | } msg ] | ||
306 | list $rc $msg | ||
307 | } {1 {cannot open value of type null}} | ||
308 | |||
309 | do_test incrblob-4.8 { | ||
310 | execsql { | ||
311 | INSERT INTO blobs(k, v, i) VALUES(X'010203040506070809', 'hello', 'world'); | ||
312 | } | ||
313 | set rc [catch { | ||
314 | set ::blob [db incrblob blobs k 3] | ||
315 | } msg ] | ||
316 | list $rc $msg | ||
317 | } {1 {cannot open indexed column for writing}} | ||
318 | |||
319 | do_test incrblob-4.9.1 { | ||
320 | set rc [catch { | ||
321 | set ::blob [db incrblob -readonly blobs k 3] | ||
322 | } msg] | ||
323 | } {0} | ||
324 | do_test incrblob-4.9.2 { | ||
325 | binary scan [read $::blob] c* c | ||
326 | close $::blob | ||
327 | set c | ||
328 | } {1 2 3 4 5 6 7 8 9} | ||
329 | |||
330 | do_test incrblob-4.10 { | ||
331 | set ::blob [db incrblob -readonly blobs k 3] | ||
332 | set rc [catch { sqlite3_blob_read $::blob 10 100 } msg] | ||
333 | list $rc $msg | ||
334 | } {1 SQLITE_ERROR} | ||
335 | do_test incrblob-4.11 { | ||
336 | close $::blob | ||
337 | } {} | ||
338 | |||
339 | #------------------------------------------------------------------------ | ||
340 | # incrblob-5.*: | ||
341 | # | ||
342 | # Test that opening a blob in an attached database works. | ||
343 | # | ||
344 | do_test incrblob-5.1 { | ||
345 | file delete -force test2.db test2.db-journal | ||
346 | set ::size [expr [file size [info script]]] | ||
347 | execsql { | ||
348 | ATTACH 'test2.db' AS aux; | ||
349 | CREATE TABLE aux.files(name, text); | ||
350 | INSERT INTO aux.files VALUES('this one', zeroblob($::size)); | ||
351 | } | ||
352 | set fd [db incrblob aux files text 1] | ||
353 | fconfigure $fd -translation binary | ||
354 | set fd2 [open [info script]] | ||
355 | fconfigure $fd2 -translation binary | ||
356 | puts -nonewline $fd [read $fd2] | ||
357 | close $fd | ||
358 | close $fd2 | ||
359 | set ::text [db one {select text from aux.files}] | ||
360 | string length $::text | ||
361 | } [file size [info script]] | ||
362 | do_test incrblob-5.2 { | ||
363 | set fd2 [open [info script]] | ||
364 | fconfigure $fd2 -translation binary | ||
365 | set ::data [read $fd2] | ||
366 | close $fd2 | ||
367 | set ::data | ||
368 | } $::text | ||
369 | |||
370 | # free memory | ||
371 | unset ::data | ||
372 | unset ::text | ||
373 | |||
374 | #------------------------------------------------------------------------ | ||
375 | # incrblob-6.*: | ||
376 | # | ||
377 | # Test that opening a blob for write-access is impossible if | ||
378 | # another connection has the database RESERVED lock. | ||
379 | # | ||
380 | # Then test that blob writes that take place inside of a | ||
381 | # transaction are not visible to external connections until | ||
382 | # after the transaction is commited and the blob channel | ||
383 | # closed. | ||
384 | # | ||
385 | sqlite3_soft_heap_limit 0 | ||
386 | do_test incrblob-6.1 { | ||
387 | sqlite3 db2 test.db | ||
388 | execsql { | ||
389 | BEGIN; | ||
390 | INSERT INTO blobs(k, v, i) VALUES('a', 'different', 'connection'); | ||
391 | } db2 | ||
392 | } {} | ||
393 | do_test incrblob-6.2 { | ||
394 | execsql { | ||
395 | SELECT rowid FROM blobs | ||
396 | } | ||
397 | } {1 2 3} | ||
398 | do_test incrblob-6.3 { | ||
399 | set rc [catch { | ||
400 | db incrblob blobs v 1 | ||
401 | } msg] | ||
402 | list $rc $msg | ||
403 | } {1 {database is locked}} | ||
404 | do_test incrblob-6.4 { | ||
405 | set rc [catch { | ||
406 | db incrblob blobs v 3 | ||
407 | } msg] | ||
408 | list $rc $msg | ||
409 | } {1 {database is locked}} | ||
410 | do_test incrblob-6.5 { | ||
411 | set ::blob [db incrblob -readonly blobs v 3] | ||
412 | read $::blob | ||
413 | } {hello} | ||
414 | do_test incrblob-6.6 { | ||
415 | close $::blob | ||
416 | } {} | ||
417 | |||
418 | do_test incrblob-6.7 { | ||
419 | set ::blob [db2 incrblob blobs i 4] | ||
420 | gets $::blob | ||
421 | } {connection} | ||
422 | do_test incrblob-6.8 { | ||
423 | tell $::blob | ||
424 | } {10} | ||
425 | do_test incrblob-6.9 { | ||
426 | seek $::blob 0 | ||
427 | puts -nonewline $::blob "invocation" | ||
428 | flush $::blob | ||
429 | } {} | ||
430 | |||
431 | # At this point rollback or commit should be illegal (because | ||
432 | # there is an open blob channel). | ||
433 | do_test incrblob-6.10 { | ||
434 | catchsql { | ||
435 | ROLLBACK; | ||
436 | } db2 | ||
437 | } {1 {cannot rollback transaction - SQL statements in progress}} | ||
438 | do_test incrblob-6.11 { | ||
439 | catchsql { | ||
440 | COMMIT; | ||
441 | } db2 | ||
442 | } {1 {cannot commit transaction - SQL statements in progress}} | ||
443 | |||
444 | do_test incrblob-6.12 { | ||
445 | execsql { | ||
446 | SELECT * FROM blobs WHERE rowid = 4; | ||
447 | } | ||
448 | } {} | ||
449 | do_test incrblob-6.13 { | ||
450 | close $::blob | ||
451 | execsql { | ||
452 | COMMIT; | ||
453 | } db2 | ||
454 | } {} | ||
455 | do_test incrblob-6.14 { | ||
456 | execsql { | ||
457 | SELECT * FROM blobs WHERE rowid = 4; | ||
458 | } | ||
459 | } {a different invocation} | ||
460 | db2 close | ||
461 | sqlite3_soft_heap_limit $soft_limit | ||
462 | |||
463 | #----------------------------------------------------------------------- | ||
464 | # The following tests verify the behaviour of the incremental IO | ||
465 | # APIs in the following cases: | ||
466 | # | ||
467 | # 7.1 A row that containing an open blob is modified. | ||
468 | # | ||
469 | # 7.2 A CREATE TABLE requires that an overflow page that is part | ||
470 | # of an open blob is moved. | ||
471 | # | ||
472 | # 7.3 An INCREMENTAL VACUUM moves an overflow page that is part | ||
473 | # of an open blob. | ||
474 | # | ||
475 | # In the first case above, correct behaviour is for all subsequent | ||
476 | # read/write operations on the blob-handle to return SQLITE_ABORT. | ||
477 | # More accurately, blob-handles are invalidated whenever the table | ||
478 | # they belong to is written to. | ||
479 | # | ||
480 | # The second two cases have no external effect. They are testing | ||
481 | # that the internal cache of overflow page numbers is correctly | ||
482 | # invalidated. | ||
483 | # | ||
484 | do_test incrblob-7.1.0 { | ||
485 | execsql { | ||
486 | BEGIN; | ||
487 | DROP TABLE blobs; | ||
488 | CREATE TABLE t1 (a, b, c, d BLOB); | ||
489 | INSERT INTO t1(a, b, c, d) VALUES(1, 2, 3, 4); | ||
490 | COMMIT; | ||
491 | } | ||
492 | } {} | ||
493 | |||
494 | foreach {tn arg} {1 "" 2 -readonly} { | ||
495 | |||
496 | execsql { | ||
497 | UPDATE t1 SET d = zeroblob(10000); | ||
498 | } | ||
499 | |||
500 | do_test incrblob-7.1.$tn.1 { | ||
501 | set ::b [eval db incrblob $arg t1 d 1] | ||
502 | binary scan [sqlite3_blob_read $::b 5000 5] c* c | ||
503 | set c | ||
504 | } {0 0 0 0 0} | ||
505 | do_test incrblob-7.1.$tn.2 { | ||
506 | execsql { | ||
507 | UPDATE t1 SET d = 15; | ||
508 | } | ||
509 | } {} | ||
510 | do_test incrblob-7.1.$tn.3 { | ||
511 | set rc [catch { sqlite3_blob_read $::b 5000 5 } msg] | ||
512 | list $rc $msg | ||
513 | } {1 SQLITE_ABORT} | ||
514 | do_test incrblob-7.1.$tn.4 { | ||
515 | execsql { | ||
516 | SELECT d FROM t1; | ||
517 | } | ||
518 | } {15} | ||
519 | do_test incrblob-7.1.$tn.5 { | ||
520 | set rc [catch { close $::b } msg] | ||
521 | list $rc $msg | ||
522 | } {0 {}} | ||
523 | do_test incrblob-7.1.$tn.6 { | ||
524 | execsql { | ||
525 | SELECT d FROM t1; | ||
526 | } | ||
527 | } {15} | ||
528 | |||
529 | } | ||
530 | |||
531 | set fd [open [info script]] | ||
532 | fconfigure $fd -translation binary | ||
533 | set ::data [read $fd 14000] | ||
534 | close $fd | ||
535 | |||
536 | db close | ||
537 | file delete -force test.db test.db-journal | ||
538 | sqlite3 db test.db | ||
539 | |||
540 | do_test incrblob-7.2.1 { | ||
541 | execsql { | ||
542 | PRAGMA auto_vacuum = "incremental"; | ||
543 | CREATE TABLE t1(a INTEGER PRIMARY KEY, b); -- root@page3 | ||
544 | INSERT INTO t1 VALUES(123, $::data); | ||
545 | } | ||
546 | set ::b [db incrblob -readonly t1 b 123] | ||
547 | read $::b | ||
548 | } $::data | ||
549 | do_test incrblob-7.2.2 { | ||
550 | execsql { | ||
551 | CREATE TABLE t2(a INTEGER PRIMARY KEY, b); -- root@page4 | ||
552 | } | ||
553 | seek $::b 0 | ||
554 | read $::b | ||
555 | } $::data | ||
556 | do_test incrblob-7.2.3 { | ||
557 | close $::b | ||
558 | execsql { | ||
559 | SELECT rootpage FROM sqlite_master; | ||
560 | } | ||
561 | } {3 4} | ||
562 | |||
563 | set ::otherdata "[string range $::data 0 1000][string range $::data 1001 end]" | ||
564 | do_test incrblob-7.3.1 { | ||
565 | execsql { | ||
566 | INSERT INTO t2 VALUES(456, $::otherdata); | ||
567 | } | ||
568 | set ::b [db incrblob -readonly t2 b 456] | ||
569 | read $::b | ||
570 | } $::otherdata | ||
571 | do_test incrblob-7.3.2 { | ||
572 | expr [file size test.db]/1024 | ||
573 | } 30 | ||
574 | do_test incrblob-7.3.3 { | ||
575 | execsql { | ||
576 | DELETE FROM t1 WHERE a = 123; | ||
577 | PRAGMA INCREMENTAL_VACUUM(0); | ||
578 | } | ||
579 | seek $::b 0 | ||
580 | read $::b | ||
581 | } $::otherdata | ||
582 | |||
583 | # Attempt to write on a read-only blob. Make sure the error code | ||
584 | # gets set. Ticket #2464. | ||
585 | # | ||
586 | do_test incrblob-7.4 { | ||
587 | set rc [catch {sqlite3_blob_write $::b 10 HELLO} msg] | ||
588 | lappend rc $msg | ||
589 | } {1 SQLITE_READONLY} | ||
590 | do_test incrblob-7.5 { | ||
591 | sqlite3_errcode db | ||
592 | } {SQLITE_READONLY} | ||
593 | do_test incrblob-7.6 { | ||
594 | sqlite3_errmsg db | ||
595 | } {attempt to write a readonly database} | ||
596 | |||
597 | finish_test | ||