blob: ca8de8eccab30a3c24f47586419e46165aaf6152 [file] [log] [blame]
drhdc2c4912009-02-04 22:46:47 +00001# 2009 January 30
danielk197704103022009-02-03 16:51:24 +00002#
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 regression tests for SQLite library. The
12# focus of this file is testing the sqlite3_backup_XXX API.
13#
drhdda70fe2009-06-05 17:09:11 +000014# $Id: backup.test,v 1.11 2009/06/05 17:09:12 drh Exp $
danielk197704103022009-02-03 16:51:24 +000015
16set testdir [file dirname $argv0]
17source $testdir/tester.tcl
18
19#---------------------------------------------------------------------
20# Test organization:
21#
22# backup-1.*: Warm-body tests.
23#
24# backup-2.*: Test backup under various conditions. To and from in-memory
25# databases. To and from empty/populated databases. etc.
26#
27# backup-3.*: Verify that the locking-page (pending byte page) is handled.
28#
29# backup-4.*: Test various error conditions.
30#
31# backup-5.*: Test the source database being modified during a backup.
32#
33# backup-6.*: Test the backup_remaining() and backup_pagecount() APIs.
34#
35# backup-7.*: Test SQLITE_BUSY and SQLITE_LOCKED errors.
36#
37# backup-8.*: Test multiple simultaneous backup operations.
38#
danielk197703ab0352009-02-06 05:59:44 +000039# backup-9.*: Test that passing a negative argument to backup_step() is
40# interpreted as "copy the whole file".
dan3306c4a2010-04-23 19:15:00 +000041#
42# backup-10.*: Test writing the source database mid backup.
danielk197703ab0352009-02-06 05:59:44 +000043#
danielk197704103022009-02-03 16:51:24 +000044
45proc data_checksum {db file} { $db one "SELECT md5sum(a, b) FROM ${file}.t1" }
46proc test_contents {name db1 file1 db2 file2} {
47 $db2 eval {select * from sqlite_master}
48 $db1 eval {select * from sqlite_master}
49 set checksum [data_checksum $db2 $file2]
50 uplevel [list do_test $name [list data_checksum $db1 $file1] $checksum]
51}
52
53do_test backup-1.1 {
54 execsql {
55 BEGIN;
56 CREATE TABLE t1(a, b);
57 CREATE INDEX i1 ON t1(a, b);
58 INSERT INTO t1 VALUES(1, randstr(1000,1000));
59 INSERT INTO t1 VALUES(2, randstr(1000,1000));
60 INSERT INTO t1 VALUES(3, randstr(1000,1000));
61 INSERT INTO t1 VALUES(4, randstr(1000,1000));
62 INSERT INTO t1 VALUES(5, randstr(1000,1000));
63 COMMIT;
64 }
65} {}
66
67# Sanity check to verify that the [test_contents] proc works.
68#
69test_contents backup-1.2 db main db main
70
71# Check that it is possible to create and finish backup operations.
72#
73do_test backup-1.3.1 {
74 file delete test2.db
75 sqlite3 db2 test2.db
76 sqlite3_backup B db2 main db main
77} {B}
78do_test backup-1.3.2 {
79 B finish
80} {SQLITE_OK}
81do_test backup-1.3.3 {
82 info commands B
83} {}
84
85# Simplest backup operation. Backup test.db to test2.db. test2.db is
86# initially empty. test.db uses the default page size.
87#
88do_test backup-1.4.1 {
89 sqlite3_backup B db2 main db main
90} {B}
91do_test backup-1.4.2 {
92 B step 200
93} {SQLITE_DONE}
94do_test backup-1.4.3 {
95 B finish
96} {SQLITE_OK}
97do_test backup-1.4.4 {
98 info commands B
99} {}
100test_contents backup-1.4.5 db2 main db main
101db close
102db2 close
103#
104# End of backup-1.* tests.
105#---------------------------------------------------------------------
106
107
108#---------------------------------------------------------------------
109# The following tests, backup-2.*, are based on the following procedure:
110#
111# 1) Populate the source database.
112# 2) Populate the destination database.
113# 3) Run the backup to completion. (backup-2.*.1)
114# 4) Integrity check the destination db. (backup-2.*.2)
115# 5) Check that the contents of the destination db is the same as that
116# of the source db. (backup-2.*.3)
117#
118# The test is run with all possible combinations of the following
119# input parameters, except that if the destination is an in-memory
120# database, the only page size tested is 1024 bytes (the same as the
121# source page-size).
122#
123# * Source database is an in-memory database, OR
124# * Source database is a file-backed database.
125#
126# * Target database is an in-memory database, OR
127# * Target database is a file-backed database.
128#
129# * Destination database is a main file, OR
130# * Destination database is an attached file, OR
131# * Destination database is a temp database.
132#
133# * Target database is empty (zero bytes), OR
134# * Target database is larger than the source, OR
135# * Target database is smaller than the source.
136#
137# * Target database page-size is the same as the source, OR
138# * Target database page-size is larger than the source, OR
139# * Target database page-size is smaller than the source.
140#
141# * Each call to step copies a single page, OR
142# * A single call to step copies the entire source database.
143#
144set iTest 1
145foreach zSrcFile {test.db :memory:} {
146foreach zDestFile {test2.db :memory:} {
147foreach zOpenScript [list {
148 sqlite3 db $zSrcFile
149 sqlite3 db2 $zSrcFile
150 db2 eval "ATTACH '$zDestFile' AS bak"
151 set db_dest db2
152 set file_dest bak
153} {
154 sqlite3 db $zSrcFile
155 sqlite3 db2 $zDestFile
156 set db_dest db2
157 set file_dest main
158} {
159 sqlite3 db $zSrcFile
160 sqlite3 db2 $zDestFile
161 set db_dest db2
162 set file_dest temp
163}] {
164foreach rows_dest {0 3 10} {
165foreach pgsz_dest {512 1024 2048} {
166foreach nPagePerStep {1 200} {
167
168 # Open the databases.
169 catch { file delete test.db }
170 catch { file delete test2.db }
171 eval $zOpenScript
172
danielk19773d781c22009-02-11 15:11:00 +0000173 # Set to true if copying to an in-memory destination. Copying to an
174 # in-memory destination is only possible if the initial destination
175 # page size is the same as the source page size (in this case 1024 bytes).
176 #
177 set isMemDest [expr {
178 $zDestFile eq ":memory:" || $file_dest eq "temp" && $TEMP_STORE==3
179 }]
danielk197704103022009-02-03 16:51:24 +0000180
danielk19773d781c22009-02-11 15:11:00 +0000181 if { $isMemDest==0 || $pgsz_dest == 1024 } {
danielk197704103022009-02-03 16:51:24 +0000182 if 0 {
183 puts -nonewline "Test $iTest: src=$zSrcFile dest=$zDestFile"
184 puts -nonewline " (as $db_dest.$file_dest)"
185 puts -nonewline " rows_dest=$rows_dest pgsz_dest=$pgsz_dest"
186 puts ""
187 }
188
189 # Set up the content of the source database.
190 execsql {
danielk19773d781c22009-02-11 15:11:00 +0000191 PRAGMA page_size = 1024;
danielk197704103022009-02-03 16:51:24 +0000192 BEGIN;
193 CREATE TABLE t1(a, b);
194 CREATE INDEX i1 ON t1(a, b);
195 INSERT INTO t1 VALUES(1, randstr(1000,1000));
196 INSERT INTO t1 VALUES(2, randstr(1000,1000));
197 INSERT INTO t1 VALUES(3, randstr(1000,1000));
198 INSERT INTO t1 VALUES(4, randstr(1000,1000));
199 INSERT INTO t1 VALUES(5, randstr(1000,1000));
200 COMMIT;
201 }
202
203
204
205 # Set up the content of the target database.
206 execsql "PRAGMA ${file_dest}.page_size = ${pgsz_dest}" $db_dest
207 if {$rows_dest != 0} {
208 execsql "
209 BEGIN;
210 CREATE TABLE ${file_dest}.t1(a, b);
211 CREATE INDEX ${file_dest}.i1 ON t1(a, b);
212 " $db_dest
213 for {set ii 0} {$ii < $rows_dest} {incr ii} {
214 execsql "
215 INSERT INTO ${file_dest}.t1 VALUES(1, randstr(1000,1000))
216 " $db_dest
217 }
218 }
219
220 # Backup the source database.
221 do_test backup-2.$iTest.1 {
222 sqlite3_backup B $db_dest $file_dest db main
223 while {[B step $nPagePerStep]=="SQLITE_OK"} {}
224 B finish
225 } {SQLITE_OK}
226
227 # Run integrity check on the backup.
228 do_test backup-2.$iTest.2 {
229 execsql "PRAGMA ${file_dest}.integrity_check" $db_dest
230 } {ok}
231
232 test_contents backup-2.$iTest.3 db main $db_dest $file_dest
233
234 }
235
236 db close
237 catch {db2 close}
238 incr iTest
239
240} } } } } }
241#
242# End of backup-2.* tests.
243#---------------------------------------------------------------------
244
245#---------------------------------------------------------------------
246# These tests, backup-3.*, ensure that nothing goes wrong if either
247# the source or destination database are large enough to include the
248# the locking-page (the page that contains the range of bytes that
249# the locks are applied to). These tests assume that the pending
250# byte is at offset 0x00010000 (64KB offset), as set by tester.tcl,
251# not at the 1GB offset as it usually is.
252#
253# The test procedure is as follows (same procedure as used for
254# the backup-2.* tests):
255#
256# 1) Populate the source database.
257# 2) Populate the destination database.
258# 3) Run the backup to completion. (backup-3.*.1)
259# 4) Integrity check the destination db. (backup-3.*.2)
260# 5) Check that the contents of the destination db is the same as that
261# of the source db. (backup-3.*.3)
262#
263# The test procedure is run with the following parameters varied:
264#
265# * Source database includes pending-byte page.
266# * Source database does not include pending-byte page.
267#
268# * Target database includes pending-byte page.
269# * Target database does not include pending-byte page.
270#
271# * Target database page-size is the same as the source, OR
272# * Target database page-size is larger than the source, OR
273# * Target database page-size is smaller than the source.
274#
275set iTest 1
danielk19773d0cbc32009-02-09 18:55:45 +0000276foreach nSrcPg {10 64 65 66 100} {
danielk197704103022009-02-03 16:51:24 +0000277foreach nDestRow {10 100} {
278foreach nDestPgsz {512 1024 2048 4096} {
279
280 catch { file delete test.db }
281 catch { file delete test2.db }
282 sqlite3 db test.db
283 sqlite3 db2 test2.db
284
285 # Set up the content of the two databases.
286 #
danielk19773d0cbc32009-02-09 18:55:45 +0000287 execsql { PRAGMA page_size = 1024 }
288 execsql "PRAGMA page_size = $nDestPgsz" db2
289 foreach db {db db2} {
danielk197704103022009-02-03 16:51:24 +0000290 execsql {
291 BEGIN;
292 CREATE TABLE t1(a, b);
293 CREATE INDEX i1 ON t1(a, b);
danielk19773d0cbc32009-02-09 18:55:45 +0000294 COMMIT;
danielk197704103022009-02-03 16:51:24 +0000295 } $db
danielk197704103022009-02-03 16:51:24 +0000296 }
danielk19773d0cbc32009-02-09 18:55:45 +0000297 while {[file size test.db]/1024 < $nSrcPg} {
298 execsql { INSERT INTO t1 VALUES($ii, randstr(200,200)) }
299 }
300
301 for {set ii 0} {$ii < $nDestRow} {incr ii} {
302 execsql { INSERT INTO t1 VALUES($ii, randstr(1000,1000)) } db2
303 }
304
danielk197704103022009-02-03 16:51:24 +0000305 # Backup the source database.
306 do_test backup-3.$iTest.1 {
307 sqlite3_backup B db main db2 main
308 while {[B step 10]=="SQLITE_OK"} {}
309 B finish
310 } {SQLITE_OK}
311
312 # Run integrity check on the backup.
313 do_test backup-3.$iTest.2 {
314 execsql "PRAGMA integrity_check" db2
315 } {ok}
316
317 test_contents backup-3.$iTest.3 db main db2 main
318
319 db close
320 db2 close
321 incr iTest
322}
323}
324}
danielk1977f2a79f22009-02-12 17:01:49 +0000325
326#--------------------------------------------------------------------
327do_test backup-3.$iTest.1 {
328 catch { file delete -force test.db }
329 catch { file delete -force test2.db }
330 sqlite3 db test.db
331 set iTab 1
332
333 db eval { PRAGMA page_size = 512 }
334 while {[file size test.db] <= $::sqlite_pending_byte} {
335 db eval "CREATE TABLE t${iTab}(a, b, c)"
336 incr iTab
337 }
338
339 sqlite3 db2 test2.db
340 db2 eval { PRAGMA page_size = 4096 }
341 while {[file size test2.db] < $::sqlite_pending_byte} {
342 db2 eval "CREATE TABLE t${iTab}(a, b, c)"
343 incr iTab
344 }
345
346 sqlite3_backup B db2 main db main
347 B step -1
348} {SQLITE_DONE}
349
350do_test backup-3.$iTest.2 {
351 B finish
352} {SQLITE_OK}
353
danielk197704103022009-02-03 16:51:24 +0000354#
355# End of backup-3.* tests.
356#---------------------------------------------------------------------
357
358
359#---------------------------------------------------------------------
360# The following tests, backup-4.*, test various error conditions:
361#
362# backup-4.1.*: Test invalid database names.
363#
364# backup-4.2.*: Test that the source database cannot be detached while
365# a backup is in progress.
366#
367# backup-4.3.*: Test that the source database handle cannot be closed
368# while a backup is in progress.
369#
370# backup-4.4.*: Test an attempt to specify the same handle for the
371# source and destination databases.
372#
373# backup-4.5.*: Test that an in-memory destination with a different
374# page-size to the source database is an error.
375#
376sqlite3 db test.db
377sqlite3 db2 test2.db
378
379do_test backup-4.1.1 {
380 catch { sqlite3_backup B db aux db2 main }
381} {1}
382do_test backup-4.1.2 {
383 sqlite3_errmsg db
384} {unknown database aux}
385do_test backup-4.1.3 {
386 catch { sqlite3_backup B db main db2 aux }
387} {1}
388do_test backup-4.1.4 {
389 sqlite3_errmsg db
390} {unknown database aux}
391
392do_test backup-4.2.1 {
danielk19773d781c22009-02-11 15:11:00 +0000393 catch { file delete -force test3.db }
394 catch { file delete -force test4.db }
395 execsql {
396 ATTACH 'test3.db' AS aux1;
397 CREATE TABLE aux1.t1(a, b);
398 }
399 execsql {
400 ATTACH 'test4.db' AS aux2;
401 CREATE TABLE aux2.t2(a, b);
402 } db2
danielk197704103022009-02-03 16:51:24 +0000403 sqlite3_backup B db aux1 db2 aux2
404} {B}
405do_test backup-4.2.2 {
406 catchsql { DETACH aux2 } db2
407} {1 {database aux2 is locked}}
408do_test backup-4.2.3 {
409 B step 50
410} {SQLITE_DONE}
411do_test backup-4.2.4 {
412 B finish
413} {SQLITE_OK}
414
415do_test backup-4.3.1 {
416 sqlite3_backup B db aux1 db2 aux2
417} {B}
418do_test backup-4.3.2 {
419 db2 cache flush
420 sqlite3_close db2
421} {SQLITE_BUSY}
422do_test backup-4.3.3 {
423 sqlite3_errmsg db2
drhb309bec2009-02-04 17:40:57 +0000424} {unable to close due to unfinished backup operation}
danielk197704103022009-02-03 16:51:24 +0000425do_test backup-4.3.4 {
426 B step 50
427} {SQLITE_DONE}
428do_test backup-4.3.5 {
429 B finish
430} {SQLITE_OK}
431
432do_test backup-4.4.1 {
433 set rc [catch {sqlite3_backup B db main db aux1}]
434 list $rc [sqlite3_errcode db] [sqlite3_errmsg db]
drhb309bec2009-02-04 17:40:57 +0000435} {1 SQLITE_ERROR {source and destination must be distinct}}
danielk197704103022009-02-03 16:51:24 +0000436db close
437db2 close
438
439do_test backup-4.5.1 {
440 catch { file delete -force test.db }
441 sqlite3 db test.db
442 sqlite3 db2 :memory:
443 execsql {
444 CREATE TABLE t1(a, b);
445 INSERT INTO t1 VALUES(1, 2);
446 }
447 execsql {
448 PRAGMA page_size = 4096;
449 CREATE TABLE t2(a, b);
450 INSERT INTO t2 VALUES(3, 4);
451 } db2
452 sqlite3_backup B db2 main db main
453} {B}
454do_test backup-4.5.2 {
455 B step 5000
456} {SQLITE_READONLY}
457do_test backup-4.5.3 {
458 B finish
459} {SQLITE_READONLY}
460
461db close
462db2 close
463#
464# End of backup-5.* tests.
465#---------------------------------------------------------------------
466
467#---------------------------------------------------------------------
468# The following tests, backup-5.*, test that the backup works properly
469# when the source database is modified during the backup. Test cases
470# are organized as follows:
471#
472# backup-5.x.1.*: Nothing special. Modify the database mid-backup.
473#
474# backup-5.x.2.*: Modify the database mid-backup so that one or more
475# pages are written out due to cache stress. Then
476# rollback the transaction.
477#
478# backup-5.x.3.*: Database is vacuumed.
479#
480# backup-5.x.4.*: Database is vacuumed and the page-size modified.
481#
482# backup-5.x.5.*: Database is shrunk via incr-vacuum.
483#
484# Each test is run three times, in the following configurations:
485#
486# 1) Backing up file-to-file. The writer writes via an external pager.
487# 2) Backing up file-to-file. The writer writes via the same pager as
488# is used by the backup operation.
489# 3) Backing up memory-to-file.
490#
491set iTest 0
492foreach {writer file} {db test.db db3 test.db db :memory:} {
493 incr iTest
494 catch { file delete bak.db }
495 sqlite3 db2 bak.db
496 catch { file delete $file }
497 sqlite3 db $file
498 sqlite3 db3 $file
499
500 do_test backup-5.$iTest.1.1 {
501 execsql {
502 BEGIN;
503 CREATE TABLE t1(a, b);
504 CREATE INDEX i1 ON t1(a, b);
505 INSERT INTO t1 VALUES(1, randstr(1000,1000));
506 INSERT INTO t1 VALUES(2, randstr(1000,1000));
507 INSERT INTO t1 VALUES(3, randstr(1000,1000));
508 INSERT INTO t1 VALUES(4, randstr(1000,1000));
509 INSERT INTO t1 VALUES(5, randstr(1000,1000));
510 COMMIT;
511 }
512 expr {[execsql {PRAGMA page_count}] > 10}
513 } {1}
514 do_test backup-5.$iTest.1.2 {
515 sqlite3_backup B db2 main db main
516 B step 5
517 } {SQLITE_OK}
518 do_test backup-5.$iTest.1.3 {
519 execsql { UPDATE t1 SET a = a + 1 } $writer
520 B step 50
521 } {SQLITE_DONE}
522 do_test backup-5.$iTest.1.4 {
523 B finish
524 } {SQLITE_OK}
525 integrity_check backup-5.$iTest.1.5 db2
526 test_contents backup-5.$iTest.1.6 db main db2 main
527
528 do_test backup-5.$iTest.2.1 {
529 execsql {
530 PRAGMA cache_size = 10;
531 BEGIN;
532 INSERT INTO t1 SELECT '', randstr(1000,1000) FROM t1;
533 INSERT INTO t1 SELECT '', randstr(1000,1000) FROM t1;
534 INSERT INTO t1 SELECT '', randstr(1000,1000) FROM t1;
535 INSERT INTO t1 SELECT '', randstr(1000,1000) FROM t1;
536 COMMIT;
537 }
538 } {}
539 do_test backup-5.$iTest.2.2 {
540 sqlite3_backup B db2 main db main
541 B step 50
542 } {SQLITE_OK}
543 do_test backup-5.$iTest.2.3 {
544 execsql {
545 BEGIN;
546 UPDATE t1 SET a = a + 1;
547 ROLLBACK;
548 } $writer
549 B step 5000
550 } {SQLITE_DONE}
551 do_test backup-5.$iTest.2.4 {
552 B finish
553 } {SQLITE_OK}
554 integrity_check backup-5.$iTest.2.5 db2
555 test_contents backup-5.$iTest.2.6 db main db2 main
556
557 do_test backup-5.$iTest.3.1 {
558 execsql { UPDATE t1 SET b = randstr(1000,1000) }
559 } {}
560 do_test backup-5.$iTest.3.2 {
561 sqlite3_backup B db2 main db main
562 B step 50
563 } {SQLITE_OK}
564 do_test backup-5.$iTest.3.3 {
565 execsql { VACUUM } $writer
566 B step 5000
567 } {SQLITE_DONE}
568 do_test backup-5.$iTest.3.4 {
569 B finish
570 } {SQLITE_OK}
571 integrity_check backup-5.$iTest.3.5 db2
572 test_contents backup-5.$iTest.3.6 db main db2 main
573
574 do_test backup-5.$iTest.4.1 {
575 execsql { UPDATE t1 SET b = randstr(1000,1000) }
576 } {}
577 do_test backup-5.$iTest.4.2 {
578 sqlite3_backup B db2 main db main
579 B step 50
580 } {SQLITE_OK}
581 do_test backup-5.$iTest.4.3 {
582 execsql {
583 PRAGMA page_size = 2048;
584 VACUUM;
585 } $writer
586 B step 5000
587 } {SQLITE_DONE}
588 do_test backup-5.$iTest.4.4 {
589 B finish
590 } {SQLITE_OK}
591 integrity_check backup-5.$iTest.4.5 db2
592 test_contents backup-5.$iTest.4.6 db main db2 main
593
shanece14f622009-02-11 16:06:18 +0000594 catch {db close}
595 catch {db2 close}
596 catch {db3 close}
danielk197704103022009-02-03 16:51:24 +0000597 catch { file delete bak.db }
598 sqlite3 db2 bak.db
599 catch { file delete $file }
600 sqlite3 db $file
601 sqlite3 db3 $file
602 do_test backup-5.$iTest.5.1 {
603 execsql {
604 PRAGMA auto_vacuum = incremental;
605 BEGIN;
606 CREATE TABLE t1(a, b);
607 CREATE INDEX i1 ON t1(a, b);
608 INSERT INTO t1 VALUES(1, randstr(1000,1000));
609 INSERT INTO t1 VALUES(2, randstr(1000,1000));
610 INSERT INTO t1 VALUES(3, randstr(1000,1000));
611 INSERT INTO t1 VALUES(4, randstr(1000,1000));
612 INSERT INTO t1 VALUES(5, randstr(1000,1000));
613 COMMIT;
614 }
615 } {}
616 do_test backup-5.$iTest.5.2 {
617 sqlite3_backup B db2 main db main
618 B step 8
619 } {SQLITE_OK}
620 do_test backup-5.$iTest.5.3 {
621 execsql {
622 DELETE FROM t1;
623 PRAGMA incremental_vacuum;
624 } $writer
625 B step 50
626 } {SQLITE_DONE}
627 do_test backup-5.$iTest.5.4 {
628 B finish
629 } {SQLITE_OK}
630 integrity_check backup-5.$iTest.5.5 db2
631 test_contents backup-5.$iTest.5.6 db main db2 main
shanece14f622009-02-11 16:06:18 +0000632 catch {db close}
633 catch {db2 close}
634 catch {db3 close}
danielk197704103022009-02-03 16:51:24 +0000635}
danielk197704103022009-02-03 16:51:24 +0000636#
637# End of backup-5.* tests.
638#---------------------------------------------------------------------
639
640#---------------------------------------------------------------------
641# Test the sqlite3_backup_remaining() and backup_pagecount() APIs.
642#
643do_test backup-6.1 {
644 catch { file delete -force test.db }
645 catch { file delete -force test2.db }
646 sqlite3 db test.db
647 sqlite3 db2 test2.db
648 execsql {
649 BEGIN;
650 CREATE TABLE t1(a, b);
651 CREATE INDEX i1 ON t1(a, b);
652 INSERT INTO t1 VALUES(1, randstr(1000,1000));
653 INSERT INTO t1 VALUES(2, randstr(1000,1000));
654 INSERT INTO t1 VALUES(3, randstr(1000,1000));
655 INSERT INTO t1 VALUES(4, randstr(1000,1000));
656 INSERT INTO t1 VALUES(5, randstr(1000,1000));
657 COMMIT;
658 }
659} {}
660do_test backup-6.2 {
661 set nTotal [expr {[file size test.db]/1024}]
662 sqlite3_backup B db2 main db main
663 B step 1
664} {SQLITE_OK}
665do_test backup-6.3 {
666 B pagecount
667} $nTotal
668do_test backup-6.4 {
669 B remaining
670} [expr $nTotal-1]
671do_test backup-6.5 {
672 B step 5
673 list [B remaining] [B pagecount]
674} [list [expr $nTotal-6] $nTotal]
675do_test backup-6.6 {
676 execsql { CREATE TABLE t2(a PRIMARY KEY, b) }
677 B step 1
678 list [B remaining] [B pagecount]
679} [list [expr $nTotal-5] [expr $nTotal+2]]
680
681do_test backup-6.X {
682 B finish
683} {SQLITE_OK}
684
shanece14f622009-02-11 16:06:18 +0000685catch {db close}
686catch {db2 close}
danielk197704103022009-02-03 16:51:24 +0000687
688#---------------------------------------------------------------------
689# Test cases backup-7.* test that SQLITE_BUSY and SQLITE_LOCKED errors
690# are returned correctly:
691#
692# backup-7.1.*: Source database is externally locked (return SQLITE_BUSY).
693#
694# backup-7.2.*: Attempt to step the backup process while a
695# write-transaction is underway on the source pager (return
696# SQLITE_LOCKED).
697#
698# backup-7.3.*: Destination database is externally locked (return SQLITE_BUSY).
699#
700do_test backup-7.0 {
701 catch { file delete -force test.db }
702 catch { file delete -force test2.db }
703 sqlite3 db2 test2.db
704 sqlite3 db test.db
705 execsql {
706 CREATE TABLE t1(a, b);
707 CREATE INDEX i1 ON t1(a, b);
708 INSERT INTO t1 VALUES(1, randstr(1000,1000));
709 INSERT INTO t1 SELECT a+ 1, randstr(1000,1000) FROM t1;
710 INSERT INTO t1 SELECT a+ 2, randstr(1000,1000) FROM t1;
711 INSERT INTO t1 SELECT a+ 4, randstr(1000,1000) FROM t1;
712 INSERT INTO t1 SELECT a+ 8, randstr(1000,1000) FROM t1;
713 INSERT INTO t1 SELECT a+16, randstr(1000,1000) FROM t1;
714 INSERT INTO t1 SELECT a+32, randstr(1000,1000) FROM t1;
715 INSERT INTO t1 SELECT a+64, randstr(1000,1000) FROM t1;
716 }
717} {}
718
719do_test backup-7.1.1 {
720 sqlite3_backup B db2 main db main
721 B step 5
722} {SQLITE_OK}
723do_test backup-7.1.2 {
724 sqlite3 db3 test.db
725 execsql { BEGIN EXCLUSIVE } db3
726 B step 5
727} {SQLITE_BUSY}
728do_test backup-7.1.3 {
729 execsql { ROLLBACK } db3
730 B step 5
731} {SQLITE_OK}
732do_test backup-7.2.1 {
733 execsql {
734 BEGIN;
735 INSERT INTO t1 VALUES(1, 4);
736 }
737} {}
738do_test backup-7.2.2 {
739 B step 5000
danielk1977404ca072009-03-16 13:19:36 +0000740} {SQLITE_BUSY}
danielk197704103022009-02-03 16:51:24 +0000741do_test backup-7.2.3 {
742 execsql { ROLLBACK }
743 B step 5000
744} {SQLITE_DONE}
745do_test backup-7.2.4 {
746 B finish
747} {SQLITE_OK}
748test_contents backup-7.2.5 db main db2 main
749integrity_check backup-7.3.6 db2
750
751do_test backup-7.3.1 {
752 db2 close
753 db3 close
754 file delete -force test2.db
755 sqlite3 db2 test2.db
756 sqlite3 db3 test2.db
757
758 sqlite3_backup B db2 main db main
759 execsql { BEGIN ; CREATE TABLE t2(a, b); } db3
760
761 B step 5
762} {SQLITE_BUSY}
763do_test backup-7.3.2 {
764 execsql { COMMIT } db3
765 B step 5000
766} {SQLITE_DONE}
767do_test backup-7.3.3 {
768 B finish
769} {SQLITE_OK}
770test_contents backup-7.3.4 db main db2 main
771integrity_check backup-7.3.5 db2
772catch { db2 close }
773catch { db3 close }
774
775#-----------------------------------------------------------------------
776# The following tests, backup-8.*, test attaching multiple backup
777# processes to the same source database. Also, reading from the source
778# database while a read transaction is active.
779#
780# These tests reuse the database "test.db" left over from backup-7.*.
781#
782do_test backup-8.1 {
783 catch { file delete -force test2.db }
784 catch { file delete -force test3.db }
785 sqlite3 db2 test2.db
786 sqlite3 db3 test3.db
787
788 sqlite3_backup B2 db2 main db main
789 sqlite3_backup B3 db3 main db main
790 list [B2 finish] [B3 finish]
791} {SQLITE_OK SQLITE_OK}
792do_test backup-8.2 {
793 sqlite3_backup B3 db3 main db main
794 sqlite3_backup B2 db2 main db main
795 list [B2 finish] [B3 finish]
796} {SQLITE_OK SQLITE_OK}
797do_test backup-8.3 {
798 sqlite3_backup B2 db2 main db main
799 sqlite3_backup B3 db3 main db main
800 B2 step 5
801} {SQLITE_OK}
802do_test backup-8.4 {
803 execsql {
804 BEGIN;
805 SELECT * FROM sqlite_master;
806 }
807 B3 step 5
808} {SQLITE_OK}
809do_test backup-8.5 {
810 list [B3 step 5000] [B3 finish]
811} {SQLITE_DONE SQLITE_OK}
812do_test backup-8.6 {
813 list [B2 step 5000] [B2 finish]
814} {SQLITE_DONE SQLITE_OK}
815test_contents backup-8.7 db main db2 main
816test_contents backup-8.8 db main db3 main
817do_test backup-8.9 {
818 execsql { PRAGMA lock_status }
819} {main shared temp closed}
820do_test backup-8.10 {
821 execsql COMMIT
822} {}
823catch { db2 close }
824catch { db3 close }
825
danielk197703ab0352009-02-06 05:59:44 +0000826#-----------------------------------------------------------------------
827# The following tests, backup-9.*, test that:
828#
829# * Passing 0 as an argument to sqlite3_backup_step() means no pages
830# are backed up (backup-9.1.*), and
831# * Passing a negative value as an argument to sqlite3_backup_step() means
832# all pages are backed up (backup-9.2.*).
833#
834# These tests reuse the database "test.db" left over from backup-7.*.
835#
836do_test backup-9.1.1 {
837 sqlite3 db2 test2.db
838 sqlite3_backup B db2 main db main
839 B step 1
840} {SQLITE_OK}
841do_test backup-9.1.2 {
842 set nRemaining [B remaining]
843 expr {$nRemaining>100}
844} {1}
845do_test backup-9.1.3 {
846 B step 0
847} {SQLITE_OK}
848do_test backup-9.1.4 {
849 B remaining
850} $nRemaining
851
852do_test backup-9.2.1 {
853 B step -1
854} {SQLITE_DONE}
855do_test backup-9.2.2 {
856 B remaining
857} {0}
858do_test backup-9.2.3 {
859 B finish
860} {SQLITE_OK}
861catch {db2 close}
danielk197704103022009-02-03 16:51:24 +0000862
danielk1977e70f4f62009-05-13 07:52:06 +0000863ifcapable memorymanage {
864 db close
865 file delete -force test.db
866 file delete -force bak.db
867
868 sqlite3 db test.db
869 sqlite3 db2 test.db
870 sqlite3 db3 bak.db
871
872 do_test backup-10.1.1 {
873 execsql {
874 BEGIN;
875 CREATE TABLE t1(a, b);
876 INSERT INTO t1 VALUES(1, randstr(1000,1000));
877 INSERT INTO t1 VALUES(2, randstr(1000,1000));
878 INSERT INTO t1 VALUES(3, randstr(1000,1000));
879 INSERT INTO t1 VALUES(4, randstr(1000,1000));
880 INSERT INTO t1 VALUES(5, randstr(1000,1000));
881 CREATE INDEX i1 ON t1(a, b);
882 COMMIT;
883 }
884 } {}
885 do_test backup-10.1.2 {
886 sqlite3_backup B db3 main db2 main
887 B step 5
888 } {SQLITE_OK}
889 do_test backup-10.1.3 {
890 execsql {
891 UPDATE t1 SET b = randstr(500,500);
892 }
893 } {}
894 sqlite3_release_memory [expr 1024*1024]
895 do_test backup-10.1.3 {
896 B step 50
897 } {SQLITE_DONE}
898 do_test backup-10.1.4 {
899 B finish
900 } {SQLITE_OK}
901 do_test backup-10.1.5 {
902 execsql { PRAGMA integrity_check } db3
903 } {ok}
904
905 db2 close
906 db3 close
907}
908
dan33d58bc2010-01-13 14:08:01 +0000909
dan3306c4a2010-04-23 19:15:00 +0000910#-----------------------------------------------------------------------
dan33d58bc2010-01-13 14:08:01 +0000911# Test that if the database is written to via the same database handle being
912# used as the source by a backup operation:
913#
914# 10.1.*: If the db is in-memory, the backup is restarted.
915# 10.2.*: If the db is a file, the backup is not restarted.
916#
917db close
918file delete -force test.db test.db-journal
919foreach {tn file rc} {
920 1 test.db SQLITE_DONE
921 2 :memory: SQLITE_OK
922} {
923 do_test backup-10.$tn.1 {
924 sqlite3 db $file
925 execsql {
926 CREATE TABLE t1(a INTEGER PRIMARY KEY, b BLOB);
927 BEGIN;
928 INSERT INTO t1 VALUES(NULL, randomblob(200));
929 INSERT INTO t1 SELECT NULL, randomblob(200) FROM t1;
930 INSERT INTO t1 SELECT NULL, randomblob(200) FROM t1;
931 INSERT INTO t1 SELECT NULL, randomblob(200) FROM t1;
932 INSERT INTO t1 SELECT NULL, randomblob(200) FROM t1;
933 INSERT INTO t1 SELECT NULL, randomblob(200) FROM t1;
934 INSERT INTO t1 SELECT NULL, randomblob(200) FROM t1;
935 INSERT INTO t1 SELECT NULL, randomblob(200) FROM t1;
936 INSERT INTO t1 SELECT NULL, randomblob(200) FROM t1;
937 COMMIT;
938 SELECT count(*) FROM t1;
939 }
940 } {256}
941
942 do_test backup-10.$tn.2 {
943 set pgs [execsql {pragma page_count}]
944 expr {$pgs > 50 && $pgs < 75}
945 } {1}
946
947 do_test backup-10.$tn.3 {
948 file delete -force bak.db bak.db-journal
949 sqlite3 db2 bak.db
950 sqlite3_backup B db2 main db main
951 B step 50
952 } {SQLITE_OK}
953
954 do_test backup-10.$tn.4 {
955 execsql { UPDATE t1 SET b = randomblob(200) WHERE a IN (1, 250) }
956 } {}
957
958 do_test backup-10.$tn.5 {
959 B step 50
960 } $rc
961
shaneh942179f2010-03-09 15:10:30 +0000962 do_test backup-10.$tn.6 {
dan33d58bc2010-01-13 14:08:01 +0000963 B finish
964 } {SQLITE_OK}
shaneh942179f2010-03-09 15:10:30 +0000965
966 db2 close
dan33d58bc2010-01-13 14:08:01 +0000967}
968
danielk197704103022009-02-03 16:51:24 +0000969finish_test