diff options
Diffstat (limited to 'libraries/sqlite/unix/sqlite-3.5.1/test/tester.tcl')
-rw-r--r-- | libraries/sqlite/unix/sqlite-3.5.1/test/tester.tcl | 554 |
1 files changed, 554 insertions, 0 deletions
diff --git a/libraries/sqlite/unix/sqlite-3.5.1/test/tester.tcl b/libraries/sqlite/unix/sqlite-3.5.1/test/tester.tcl new file mode 100644 index 0000000..a1ca65c --- /dev/null +++ b/libraries/sqlite/unix/sqlite-3.5.1/test/tester.tcl | |||
@@ -0,0 +1,554 @@ | |||
1 | # 2001 September 15 | ||
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 | # This file implements some common TCL routines used for regression | ||
12 | # testing the SQLite library | ||
13 | # | ||
14 | # $Id: tester.tcl,v 1.91 2007/09/01 09:02:54 danielk1977 Exp $ | ||
15 | |||
16 | |||
17 | set tcl_precision 15 | ||
18 | set sqlite_pending_byte 0x0010000 | ||
19 | |||
20 | # | ||
21 | # Check the command-line arguments for a default soft-heap-limit. | ||
22 | # Store this default value in the global variable ::soft_limit and | ||
23 | # update the soft-heap-limit each time this script is run. In that | ||
24 | # way if an individual test file changes the soft-heap-limit, it | ||
25 | # will be reset at the start of the next test file. | ||
26 | # | ||
27 | if {![info exists soft_limit]} { | ||
28 | set soft_limit 0 | ||
29 | for {set i 0} {$i<[llength $argv]} {incr i} { | ||
30 | if {[regexp {^--soft-heap-limit=(.+)$} [lindex $argv $i] all value]} { | ||
31 | if {$value!="off"} { | ||
32 | set soft_limit $value | ||
33 | } | ||
34 | set argv [lreplace $argv $i $i] | ||
35 | } | ||
36 | } | ||
37 | } | ||
38 | sqlite3_soft_heap_limit $soft_limit | ||
39 | |||
40 | # | ||
41 | # Check the command-line arguments to set the memory debugger | ||
42 | # backtrace depth. | ||
43 | # | ||
44 | # See the sqlite3_memdebug_backtrace() function in mem2.c or | ||
45 | # test_malloc.c for additional information. | ||
46 | # | ||
47 | for {set i 0} {$i<[llength $argv]} {incr i} { | ||
48 | if {[regexp {^--backtrace=(\d+)$} [lindex $argv $i] all value]} { | ||
49 | sqlite3_memdebug_backtrace $value | ||
50 | set argv [lreplace $argv $i $i] | ||
51 | } | ||
52 | } | ||
53 | |||
54 | |||
55 | # Use the pager codec if it is available | ||
56 | # | ||
57 | if {[sqlite3 -has-codec] && [info command sqlite_orig]==""} { | ||
58 | rename sqlite3 sqlite_orig | ||
59 | proc sqlite3 {args} { | ||
60 | if {[llength $args]==2 && [string index [lindex $args 0] 0]!="-"} { | ||
61 | lappend args -key {xyzzy} | ||
62 | } | ||
63 | uplevel 1 sqlite_orig $args | ||
64 | } | ||
65 | } | ||
66 | |||
67 | |||
68 | # Create a test database | ||
69 | # | ||
70 | catch {db close} | ||
71 | file delete -force test.db | ||
72 | file delete -force test.db-journal | ||
73 | sqlite3 db ./test.db | ||
74 | set ::DB [sqlite3_connection_pointer db] | ||
75 | if {[info exists ::SETUP_SQL]} { | ||
76 | db eval $::SETUP_SQL | ||
77 | } | ||
78 | |||
79 | # Abort early if this script has been run before. | ||
80 | # | ||
81 | if {[info exists nTest]} return | ||
82 | |||
83 | # Set the test counters to zero | ||
84 | # | ||
85 | set nErr 0 | ||
86 | set nTest 0 | ||
87 | set skip_test 0 | ||
88 | set failList {} | ||
89 | set maxErr 1000 | ||
90 | if {![info exists speedTest]} { | ||
91 | set speedTest 0 | ||
92 | } | ||
93 | |||
94 | # Invoke the do_test procedure to run a single test | ||
95 | # | ||
96 | proc do_test {name cmd expected} { | ||
97 | global argv nErr nTest skip_test maxErr | ||
98 | sqlite3_memdebug_settitle $name | ||
99 | if {$skip_test} { | ||
100 | set skip_test 0 | ||
101 | return | ||
102 | } | ||
103 | if {[llength $argv]==0} { | ||
104 | set go 1 | ||
105 | } else { | ||
106 | set go 0 | ||
107 | foreach pattern $argv { | ||
108 | if {[string match $pattern $name]} { | ||
109 | set go 1 | ||
110 | break | ||
111 | } | ||
112 | } | ||
113 | } | ||
114 | if {!$go} return | ||
115 | incr nTest | ||
116 | puts -nonewline $name... | ||
117 | flush stdout | ||
118 | if {[catch {uplevel #0 "$cmd;\n"} result]} { | ||
119 | puts "\nError: $result" | ||
120 | incr nErr | ||
121 | lappend ::failList $name | ||
122 | if {$nErr>$maxErr} {puts "*** Giving up..."; finalize_testing} | ||
123 | } elseif {[string compare $result $expected]} { | ||
124 | puts "\nExpected: \[$expected\]\n Got: \[$result\]" | ||
125 | incr nErr | ||
126 | lappend ::failList $name | ||
127 | if {$nErr>=$maxErr} {puts "*** Giving up..."; finalize_testing} | ||
128 | } else { | ||
129 | puts " Ok" | ||
130 | } | ||
131 | flush stdout | ||
132 | } | ||
133 | |||
134 | # Run an SQL script. | ||
135 | # Return the number of microseconds per statement. | ||
136 | # | ||
137 | proc speed_trial {name numstmt units sql} { | ||
138 | puts -nonewline [format {%-21.21s } $name...] | ||
139 | flush stdout | ||
140 | set speed [time {sqlite3_exec_nr db $sql}] | ||
141 | set tm [lindex $speed 0] | ||
142 | set rate [expr {1000000.0*$numstmt/$tm}] | ||
143 | set u2 $units/s | ||
144 | puts [format {%12d uS %20.5f %s} $tm $rate $u2] | ||
145 | global total_time | ||
146 | set total_time [expr {$total_time+$tm}] | ||
147 | } | ||
148 | proc speed_trial_init {name} { | ||
149 | global total_time | ||
150 | set total_time 0 | ||
151 | } | ||
152 | proc speed_trial_summary {name} { | ||
153 | global total_time | ||
154 | puts [format {%-21.21s %12d uS TOTAL} $name $total_time] | ||
155 | } | ||
156 | |||
157 | # Run this routine last | ||
158 | # | ||
159 | proc finish_test {} { | ||
160 | finalize_testing | ||
161 | } | ||
162 | proc finalize_testing {} { | ||
163 | global nTest nErr sqlite_open_file_count | ||
164 | |||
165 | catch {db close} | ||
166 | catch {db2 close} | ||
167 | catch {db3 close} | ||
168 | |||
169 | sqlite3 db {} | ||
170 | # sqlite3_clear_tsd_memdebug | ||
171 | db close | ||
172 | set heaplimit [sqlite3_soft_heap_limit] | ||
173 | if {$heaplimit!=$::soft_limit} { | ||
174 | puts "soft-heap-limit changed by this script\ | ||
175 | from $::soft_limit to $heaplimit" | ||
176 | } elseif {$heaplimit!="" && $heaplimit>0} { | ||
177 | puts "soft-heap-limit set to $heaplimit" | ||
178 | } | ||
179 | sqlite3_soft_heap_limit 0 | ||
180 | incr nTest | ||
181 | puts "$nErr errors out of $nTest tests" | ||
182 | if {$nErr>0} { | ||
183 | puts "Failures on these tests: $::failList" | ||
184 | } | ||
185 | if {$nErr>0 && ![working_64bit_int]} { | ||
186 | puts "******************************************************************" | ||
187 | puts "N.B.: The version of TCL that you used to build this test harness" | ||
188 | puts "is defective in that it does not support 64-bit integers. Some or" | ||
189 | puts "all of the test failures above might be a result from this defect" | ||
190 | puts "in your TCL build." | ||
191 | puts "******************************************************************" | ||
192 | } | ||
193 | if {$sqlite_open_file_count} { | ||
194 | puts "$sqlite_open_file_count files were left open" | ||
195 | incr nErr | ||
196 | } | ||
197 | if {[sqlite3_memory_used]>0} { | ||
198 | puts "Unfreed memory: [sqlite3_memory_used] bytes" | ||
199 | incr nErr | ||
200 | ifcapable memdebug { | ||
201 | puts "Writing unfreed memory log to \"./memleak.txt\"" | ||
202 | sqlite3_memdebug_dump ./memleak.txt | ||
203 | } | ||
204 | } else { | ||
205 | puts "All memory allocations freed - no leaks" | ||
206 | } | ||
207 | puts "Maximum memory usage: [sqlite3_memory_highwater] bytes" | ||
208 | foreach f [glob -nocomplain test.db-*-journal] { | ||
209 | file delete -force $f | ||
210 | } | ||
211 | foreach f [glob -nocomplain test.db-mj*] { | ||
212 | file delete -force $f | ||
213 | } | ||
214 | exit [expr {$nErr>0}] | ||
215 | } | ||
216 | |||
217 | # A procedure to execute SQL | ||
218 | # | ||
219 | proc execsql {sql {db db}} { | ||
220 | # puts "SQL = $sql" | ||
221 | uplevel [list $db eval $sql] | ||
222 | } | ||
223 | |||
224 | # Execute SQL and catch exceptions. | ||
225 | # | ||
226 | proc catchsql {sql {db db}} { | ||
227 | # puts "SQL = $sql" | ||
228 | set r [catch {$db eval $sql} msg] | ||
229 | lappend r $msg | ||
230 | return $r | ||
231 | } | ||
232 | |||
233 | # Do an VDBE code dump on the SQL given | ||
234 | # | ||
235 | proc explain {sql {db db}} { | ||
236 | puts "" | ||
237 | puts "addr opcode p1 p2 p3 " | ||
238 | puts "---- ------------ ------ ------ ---------------" | ||
239 | $db eval "explain $sql" {} { | ||
240 | puts [format {%-4d %-12.12s %-6d %-6d %s} $addr $opcode $p1 $p2 $p3] | ||
241 | } | ||
242 | } | ||
243 | |||
244 | # Another procedure to execute SQL. This one includes the field | ||
245 | # names in the returned list. | ||
246 | # | ||
247 | proc execsql2 {sql} { | ||
248 | set result {} | ||
249 | db eval $sql data { | ||
250 | foreach f $data(*) { | ||
251 | lappend result $f $data($f) | ||
252 | } | ||
253 | } | ||
254 | return $result | ||
255 | } | ||
256 | |||
257 | # Use the non-callback API to execute multiple SQL statements | ||
258 | # | ||
259 | proc stepsql {dbptr sql} { | ||
260 | set sql [string trim $sql] | ||
261 | set r 0 | ||
262 | while {[string length $sql]>0} { | ||
263 | if {[catch {sqlite3_prepare $dbptr $sql -1 sqltail} vm]} { | ||
264 | return [list 1 $vm] | ||
265 | } | ||
266 | set sql [string trim $sqltail] | ||
267 | # while {[sqlite_step $vm N VAL COL]=="SQLITE_ROW"} { | ||
268 | # foreach v $VAL {lappend r $v} | ||
269 | # } | ||
270 | while {[sqlite3_step $vm]=="SQLITE_ROW"} { | ||
271 | for {set i 0} {$i<[sqlite3_data_count $vm]} {incr i} { | ||
272 | lappend r [sqlite3_column_text $vm $i] | ||
273 | } | ||
274 | } | ||
275 | if {[catch {sqlite3_finalize $vm} errmsg]} { | ||
276 | return [list 1 $errmsg] | ||
277 | } | ||
278 | } | ||
279 | return $r | ||
280 | } | ||
281 | |||
282 | # Delete a file or directory | ||
283 | # | ||
284 | proc forcedelete {filename} { | ||
285 | if {[catch {file delete -force $filename}]} { | ||
286 | exec rm -rf $filename | ||
287 | } | ||
288 | } | ||
289 | |||
290 | # Do an integrity check of the entire database | ||
291 | # | ||
292 | proc integrity_check {name} { | ||
293 | ifcapable integrityck { | ||
294 | do_test $name { | ||
295 | execsql {PRAGMA integrity_check} | ||
296 | } {ok} | ||
297 | } | ||
298 | } | ||
299 | |||
300 | # Evaluate a boolean expression of capabilities. If true, execute the | ||
301 | # code. Omit the code if false. | ||
302 | # | ||
303 | proc ifcapable {expr code {else ""} {elsecode ""}} { | ||
304 | regsub -all {[a-z_0-9]+} $expr {$::sqlite_options(&)} e2 | ||
305 | if ($e2) { | ||
306 | set c [catch {uplevel 1 $code} r] | ||
307 | } else { | ||
308 | set c [catch {uplevel 1 $elsecode} r] | ||
309 | } | ||
310 | return -code $c $r | ||
311 | } | ||
312 | |||
313 | # This proc execs a seperate process that crashes midway through executing | ||
314 | # the SQL script $sql on database test.db. | ||
315 | # | ||
316 | # The crash occurs during a sync() of file $crashfile. When the crash | ||
317 | # occurs a random subset of all unsynced writes made by the process are | ||
318 | # written into the files on disk. Argument $crashdelay indicates the | ||
319 | # number of file syncs to wait before crashing. | ||
320 | # | ||
321 | # The return value is a list of two elements. The first element is a | ||
322 | # boolean, indicating whether or not the process actually crashed or | ||
323 | # reported some other error. The second element in the returned list is the | ||
324 | # error message. This is "child process exited abnormally" if the crash | ||
325 | # occured. | ||
326 | # | ||
327 | # crashsql -delay CRASHDELAY -file CRASHFILE ?-blocksize BLOCKSIZE? $sql | ||
328 | # | ||
329 | proc crashsql {args} { | ||
330 | if {$::tcl_platform(platform)!="unix"} { | ||
331 | error "crashsql should only be used on unix" | ||
332 | } | ||
333 | |||
334 | set blocksize "" | ||
335 | set crashdelay 1 | ||
336 | set crashfile "" | ||
337 | set dc "" | ||
338 | set sql [lindex $args end] | ||
339 | |||
340 | for {set ii 0} {$ii < [llength $args]-1} {incr ii 2} { | ||
341 | set z [lindex $args $ii] | ||
342 | set n [string length $z] | ||
343 | set z2 [lindex $args [expr $ii+1]] | ||
344 | |||
345 | if {$n>1 && [string first $z -delay]==0} {set crashdelay $z2} \ | ||
346 | elseif {$n>1 && [string first $z -file]==0} {set crashfile $z2} \ | ||
347 | elseif {$n>1 && [string first $z -blocksize]==0} {set blocksize "-s $z2" } \ | ||
348 | elseif {$n>1 && [string first $z -characteristics]==0} {set dc "-c {$z2}" } \ | ||
349 | else { error "Unrecognized option: $z" } | ||
350 | } | ||
351 | |||
352 | if {$crashfile eq ""} { | ||
353 | error "Compulsory option -file missing" | ||
354 | } | ||
355 | |||
356 | set cfile [file join [pwd] $crashfile] | ||
357 | |||
358 | set f [open crash.tcl w] | ||
359 | puts $f "sqlite3_crash_enable 1" | ||
360 | puts $f "sqlite3_crashparams $blocksize $dc $crashdelay $cfile" | ||
361 | puts $f "set sqlite_pending_byte $::sqlite_pending_byte" | ||
362 | puts $f "sqlite3 db test.db -vfs crash" | ||
363 | |||
364 | # This block sets the cache size of the main database to 10 | ||
365 | # pages. This is done in case the build is configured to omit | ||
366 | # "PRAGMA cache_size". | ||
367 | puts $f {db eval {SELECT * FROM sqlite_master;}} | ||
368 | puts $f {set bt [btree_from_db db]} | ||
369 | puts $f {btree_set_cache_size $bt 10} | ||
370 | |||
371 | puts $f "db eval {" | ||
372 | puts $f "$sql" | ||
373 | puts $f "}" | ||
374 | close $f | ||
375 | |||
376 | set r [catch { | ||
377 | exec [info nameofexec] crash.tcl >@stdout | ||
378 | } msg] | ||
379 | lappend r $msg | ||
380 | } | ||
381 | |||
382 | # Usage: do_ioerr_test <test number> <options...> | ||
383 | # | ||
384 | # This proc is used to implement test cases that check that IO errors | ||
385 | # are correctly handled. The first argument, <test number>, is an integer | ||
386 | # used to name the tests executed by this proc. Options are as follows: | ||
387 | # | ||
388 | # -tclprep TCL script to run to prepare test. | ||
389 | # -sqlprep SQL script to run to prepare test. | ||
390 | # -tclbody TCL script to run with IO error simulation. | ||
391 | # -sqlbody TCL script to run with IO error simulation. | ||
392 | # -exclude List of 'N' values not to test. | ||
393 | # -erc Use extended result codes | ||
394 | # -persist Make simulated I/O errors persistent | ||
395 | # -start Value of 'N' to begin with (default 1) | ||
396 | # | ||
397 | # -cksum Boolean. If true, test that the database does | ||
398 | # not change during the execution of the test case. | ||
399 | # | ||
400 | proc do_ioerr_test {testname args} { | ||
401 | |||
402 | set ::ioerropts(-start) 1 | ||
403 | set ::ioerropts(-cksum) 0 | ||
404 | set ::ioerropts(-erc) 0 | ||
405 | set ::ioerropts(-count) 100000000 | ||
406 | set ::ioerropts(-persist) 1 | ||
407 | array set ::ioerropts $args | ||
408 | |||
409 | set ::go 1 | ||
410 | for {set n $::ioerropts(-start)} {$::go} {incr n} { | ||
411 | set ::TN $n | ||
412 | incr ::ioerropts(-count) -1 | ||
413 | if {$::ioerropts(-count)<0} break | ||
414 | |||
415 | # Skip this IO error if it was specified with the "-exclude" option. | ||
416 | if {[info exists ::ioerropts(-exclude)]} { | ||
417 | if {[lsearch $::ioerropts(-exclude) $n]!=-1} continue | ||
418 | } | ||
419 | |||
420 | # Delete the files test.db and test2.db, then execute the TCL and | ||
421 | # SQL (in that order) to prepare for the test case. | ||
422 | do_test $testname.$n.1 { | ||
423 | set ::sqlite_io_error_pending 0 | ||
424 | catch {db close} | ||
425 | catch {file delete -force test.db} | ||
426 | catch {file delete -force test.db-journal} | ||
427 | catch {file delete -force test2.db} | ||
428 | catch {file delete -force test2.db-journal} | ||
429 | set ::DB [sqlite3 db test.db; sqlite3_connection_pointer db] | ||
430 | sqlite3_extended_result_codes $::DB $::ioerropts(-erc) | ||
431 | if {[info exists ::ioerropts(-tclprep)]} { | ||
432 | eval $::ioerropts(-tclprep) | ||
433 | } | ||
434 | if {[info exists ::ioerropts(-sqlprep)]} { | ||
435 | execsql $::ioerropts(-sqlprep) | ||
436 | } | ||
437 | expr 0 | ||
438 | } {0} | ||
439 | |||
440 | # Read the 'checksum' of the database. | ||
441 | if {$::ioerropts(-cksum)} { | ||
442 | set checksum [cksum] | ||
443 | } | ||
444 | |||
445 | # Set the Nth IO error to fail. | ||
446 | do_test $testname.$n.2 [subst { | ||
447 | set ::sqlite_io_error_persist $::ioerropts(-persist) | ||
448 | set ::sqlite_io_error_pending $n | ||
449 | }] $n | ||
450 | |||
451 | # Create a single TCL script from the TCL and SQL specified | ||
452 | # as the body of the test. | ||
453 | set ::ioerrorbody {} | ||
454 | if {[info exists ::ioerropts(-tclbody)]} { | ||
455 | append ::ioerrorbody "$::ioerropts(-tclbody)\n" | ||
456 | } | ||
457 | if {[info exists ::ioerropts(-sqlbody)]} { | ||
458 | append ::ioerrorbody "db eval {$::ioerropts(-sqlbody)}" | ||
459 | } | ||
460 | |||
461 | # Execute the TCL Script created in the above block. If | ||
462 | # there are at least N IO operations performed by SQLite as | ||
463 | # a result of the script, the Nth will fail. | ||
464 | do_test $testname.$n.3 { | ||
465 | set r [catch $::ioerrorbody msg] | ||
466 | set rc [sqlite3_errcode $::DB] | ||
467 | if {$::ioerropts(-erc)} { | ||
468 | # If we are in extended result code mode, make sure all of the | ||
469 | # IOERRs we get back really do have their extended code values. | ||
470 | # If an extended result code is returned, the sqlite3_errcode | ||
471 | # TCLcommand will return a string of the form: SQLITE_IOERR+nnnn | ||
472 | # where nnnn is a number | ||
473 | if {[regexp {^SQLITE_IOERR} $rc] && ![regexp {IOERR\+\d} $rc]} { | ||
474 | return $rc | ||
475 | } | ||
476 | } else { | ||
477 | # If we are not in extended result code mode, make sure no | ||
478 | # extended error codes are returned. | ||
479 | if {[regexp {\+\d} $rc]} { | ||
480 | return $rc | ||
481 | } | ||
482 | } | ||
483 | # The test repeats as long as $::go is true. | ||
484 | set ::go [expr {$::sqlite_io_error_pending<=0}] | ||
485 | set s [expr $::sqlite_io_error_hit==0] | ||
486 | set ::sqlite_io_error_hit 0 | ||
487 | |||
488 | # One of two things must have happened. either | ||
489 | # 1. We never hit the IO error and the SQL returned OK | ||
490 | # 2. An IO error was hit and the SQL failed | ||
491 | # | ||
492 | expr { ($s && !$r && !$::go) || (!$s && $r && $::go) } | ||
493 | } {1} | ||
494 | |||
495 | # If an IO error occured, then the checksum of the database should | ||
496 | # be the same as before the script that caused the IO error was run. | ||
497 | if {$::go && $::ioerropts(-cksum)} { | ||
498 | do_test $testname.$n.4 { | ||
499 | catch {db close} | ||
500 | set ::DB [sqlite3 db test.db; sqlite3_connection_pointer db] | ||
501 | cksum | ||
502 | } $checksum | ||
503 | } | ||
504 | |||
505 | set ::sqlite_io_error_pending 0 | ||
506 | if {[info exists ::ioerropts(-cleanup)]} { | ||
507 | catch $::ioerropts(-cleanup) | ||
508 | } | ||
509 | } | ||
510 | set ::sqlite_io_error_pending 0 | ||
511 | set ::sqlite_io_error_persist 0 | ||
512 | unset ::ioerropts | ||
513 | } | ||
514 | |||
515 | # Return a checksum based on the contents of database 'db'. | ||
516 | # | ||
517 | proc cksum {{db db}} { | ||
518 | set txt [$db eval { | ||
519 | SELECT name, type, sql FROM sqlite_master order by name | ||
520 | }]\n | ||
521 | foreach tbl [$db eval { | ||
522 | SELECT name FROM sqlite_master WHERE type='table' order by name | ||
523 | }] { | ||
524 | append txt [$db eval "SELECT * FROM $tbl"]\n | ||
525 | } | ||
526 | foreach prag {default_synchronous default_cache_size} { | ||
527 | append txt $prag-[$db eval "PRAGMA $prag"]\n | ||
528 | } | ||
529 | set cksum [string length $txt]-[md5 $txt] | ||
530 | # puts $cksum-[file size test.db] | ||
531 | return $cksum | ||
532 | } | ||
533 | |||
534 | # Copy file $from into $to. This is used because some versions of | ||
535 | # TCL for windows (notably the 8.4.1 binary package shipped with the | ||
536 | # current mingw release) have a broken "file copy" command. | ||
537 | # | ||
538 | proc copy_file {from to} { | ||
539 | if {$::tcl_platform(platform)=="unix"} { | ||
540 | file copy -force $from $to | ||
541 | } else { | ||
542 | set f [open $from] | ||
543 | fconfigure $f -translation binary | ||
544 | set t [open $to w] | ||
545 | fconfigure $t -translation binary | ||
546 | puts -nonewline $t [read $f [file size $from]] | ||
547 | close $t | ||
548 | close $f | ||
549 | } | ||
550 | } | ||
551 | |||
552 | # If the library is compiled with the SQLITE_DEFAULT_AUTOVACUUM macro set | ||
553 | # to non-zero, then set the global variable $AUTOVACUUM to 1. | ||
554 | set AUTOVACUUM $sqlite_options(default_autovacuum) | ||