blob: 97945da4f188e6757c1464a3b216e7ba5be50639 [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
dan586b9c82010-05-03 08:04:49 +0000492file delete -force bak.db-wal
danielk197704103022009-02-03 16:51:24 +0000493foreach {writer file} {db test.db db3 test.db db :memory:} {
494 incr iTest
495 catch { file delete bak.db }
496 sqlite3 db2 bak.db
497 catch { file delete $file }
498 sqlite3 db $file
499 sqlite3 db3 $file
500
501 do_test backup-5.$iTest.1.1 {
502 execsql {
503 BEGIN;
504 CREATE TABLE t1(a, b);
505 CREATE INDEX i1 ON t1(a, b);
506 INSERT INTO t1 VALUES(1, randstr(1000,1000));
507 INSERT INTO t1 VALUES(2, randstr(1000,1000));
508 INSERT INTO t1 VALUES(3, randstr(1000,1000));
509 INSERT INTO t1 VALUES(4, randstr(1000,1000));
510 INSERT INTO t1 VALUES(5, randstr(1000,1000));
511 COMMIT;
512 }
513 expr {[execsql {PRAGMA page_count}] > 10}
514 } {1}
515 do_test backup-5.$iTest.1.2 {
516 sqlite3_backup B db2 main db main
517 B step 5
518 } {SQLITE_OK}
519 do_test backup-5.$iTest.1.3 {
520 execsql { UPDATE t1 SET a = a + 1 } $writer
521 B step 50
522 } {SQLITE_DONE}
523 do_test backup-5.$iTest.1.4 {
524 B finish
525 } {SQLITE_OK}
526 integrity_check backup-5.$iTest.1.5 db2
527 test_contents backup-5.$iTest.1.6 db main db2 main
528
529 do_test backup-5.$iTest.2.1 {
530 execsql {
531 PRAGMA cache_size = 10;
532 BEGIN;
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 INSERT INTO t1 SELECT '', randstr(1000,1000) FROM t1;
537 COMMIT;
538 }
539 } {}
540 do_test backup-5.$iTest.2.2 {
541 sqlite3_backup B db2 main db main
542 B step 50
543 } {SQLITE_OK}
544 do_test backup-5.$iTest.2.3 {
545 execsql {
546 BEGIN;
547 UPDATE t1 SET a = a + 1;
548 ROLLBACK;
549 } $writer
550 B step 5000
551 } {SQLITE_DONE}
552 do_test backup-5.$iTest.2.4 {
553 B finish
554 } {SQLITE_OK}
555 integrity_check backup-5.$iTest.2.5 db2
556 test_contents backup-5.$iTest.2.6 db main db2 main
557
558 do_test backup-5.$iTest.3.1 {
559 execsql { UPDATE t1 SET b = randstr(1000,1000) }
560 } {}
561 do_test backup-5.$iTest.3.2 {
562 sqlite3_backup B db2 main db main
563 B step 50
564 } {SQLITE_OK}
565 do_test backup-5.$iTest.3.3 {
566 execsql { VACUUM } $writer
567 B step 5000
568 } {SQLITE_DONE}
569 do_test backup-5.$iTest.3.4 {
570 B finish
571 } {SQLITE_OK}
572 integrity_check backup-5.$iTest.3.5 db2
573 test_contents backup-5.$iTest.3.6 db main db2 main
574
575 do_test backup-5.$iTest.4.1 {
576 execsql { UPDATE t1 SET b = randstr(1000,1000) }
577 } {}
578 do_test backup-5.$iTest.4.2 {
579 sqlite3_backup B db2 main db main
580 B step 50
581 } {SQLITE_OK}
582 do_test backup-5.$iTest.4.3 {
583 execsql {
584 PRAGMA page_size = 2048;
585 VACUUM;
586 } $writer
587 B step 5000
588 } {SQLITE_DONE}
589 do_test backup-5.$iTest.4.4 {
590 B finish
591 } {SQLITE_OK}
592 integrity_check backup-5.$iTest.4.5 db2
593 test_contents backup-5.$iTest.4.6 db main db2 main
594
shanece14f622009-02-11 16:06:18 +0000595 catch {db close}
596 catch {db2 close}
597 catch {db3 close}
danielk197704103022009-02-03 16:51:24 +0000598 catch { file delete bak.db }
599 sqlite3 db2 bak.db
600 catch { file delete $file }
601 sqlite3 db $file
602 sqlite3 db3 $file
603 do_test backup-5.$iTest.5.1 {
604 execsql {
605 PRAGMA auto_vacuum = incremental;
606 BEGIN;
607 CREATE TABLE t1(a, b);
608 CREATE INDEX i1 ON t1(a, b);
609 INSERT INTO t1 VALUES(1, randstr(1000,1000));
610 INSERT INTO t1 VALUES(2, randstr(1000,1000));
611 INSERT INTO t1 VALUES(3, randstr(1000,1000));
612 INSERT INTO t1 VALUES(4, randstr(1000,1000));
613 INSERT INTO t1 VALUES(5, randstr(1000,1000));
614 COMMIT;
615 }
616 } {}
617 do_test backup-5.$iTest.5.2 {
618 sqlite3_backup B db2 main db main
619 B step 8
620 } {SQLITE_OK}
621 do_test backup-5.$iTest.5.3 {
622 execsql {
623 DELETE FROM t1;
624 PRAGMA incremental_vacuum;
625 } $writer
626 B step 50
627 } {SQLITE_DONE}
628 do_test backup-5.$iTest.5.4 {
629 B finish
630 } {SQLITE_OK}
631 integrity_check backup-5.$iTest.5.5 db2
632 test_contents backup-5.$iTest.5.6 db main db2 main
shanece14f622009-02-11 16:06:18 +0000633 catch {db close}
634 catch {db2 close}
635 catch {db3 close}
danielk197704103022009-02-03 16:51:24 +0000636}
danielk197704103022009-02-03 16:51:24 +0000637#
638# End of backup-5.* tests.
639#---------------------------------------------------------------------
640
641#---------------------------------------------------------------------
642# Test the sqlite3_backup_remaining() and backup_pagecount() APIs.
643#
644do_test backup-6.1 {
645 catch { file delete -force test.db }
646 catch { file delete -force test2.db }
647 sqlite3 db test.db
648 sqlite3 db2 test2.db
649 execsql {
650 BEGIN;
651 CREATE TABLE t1(a, b);
652 CREATE INDEX i1 ON t1(a, b);
653 INSERT INTO t1 VALUES(1, randstr(1000,1000));
654 INSERT INTO t1 VALUES(2, randstr(1000,1000));
655 INSERT INTO t1 VALUES(3, randstr(1000,1000));
656 INSERT INTO t1 VALUES(4, randstr(1000,1000));
657 INSERT INTO t1 VALUES(5, randstr(1000,1000));
658 COMMIT;
659 }
660} {}
661do_test backup-6.2 {
662 set nTotal [expr {[file size test.db]/1024}]
663 sqlite3_backup B db2 main db main
664 B step 1
665} {SQLITE_OK}
666do_test backup-6.3 {
667 B pagecount
668} $nTotal
669do_test backup-6.4 {
670 B remaining
671} [expr $nTotal-1]
672do_test backup-6.5 {
673 B step 5
674 list [B remaining] [B pagecount]
675} [list [expr $nTotal-6] $nTotal]
676do_test backup-6.6 {
677 execsql { CREATE TABLE t2(a PRIMARY KEY, b) }
678 B step 1
679 list [B remaining] [B pagecount]
680} [list [expr $nTotal-5] [expr $nTotal+2]]
681
682do_test backup-6.X {
683 B finish
684} {SQLITE_OK}
685
shanece14f622009-02-11 16:06:18 +0000686catch {db close}
687catch {db2 close}
danielk197704103022009-02-03 16:51:24 +0000688
689#---------------------------------------------------------------------
690# Test cases backup-7.* test that SQLITE_BUSY and SQLITE_LOCKED errors
691# are returned correctly:
692#
693# backup-7.1.*: Source database is externally locked (return SQLITE_BUSY).
694#
695# backup-7.2.*: Attempt to step the backup process while a
696# write-transaction is underway on the source pager (return
697# SQLITE_LOCKED).
698#
699# backup-7.3.*: Destination database is externally locked (return SQLITE_BUSY).
700#
701do_test backup-7.0 {
702 catch { file delete -force test.db }
703 catch { file delete -force test2.db }
704 sqlite3 db2 test2.db
705 sqlite3 db test.db
706 execsql {
707 CREATE TABLE t1(a, b);
708 CREATE INDEX i1 ON t1(a, b);
709 INSERT INTO t1 VALUES(1, randstr(1000,1000));
710 INSERT INTO t1 SELECT a+ 1, randstr(1000,1000) FROM t1;
711 INSERT INTO t1 SELECT a+ 2, randstr(1000,1000) FROM t1;
712 INSERT INTO t1 SELECT a+ 4, randstr(1000,1000) FROM t1;
713 INSERT INTO t1 SELECT a+ 8, randstr(1000,1000) FROM t1;
714 INSERT INTO t1 SELECT a+16, randstr(1000,1000) FROM t1;
715 INSERT INTO t1 SELECT a+32, randstr(1000,1000) FROM t1;
716 INSERT INTO t1 SELECT a+64, randstr(1000,1000) FROM t1;
717 }
718} {}
719
720do_test backup-7.1.1 {
721 sqlite3_backup B db2 main db main
722 B step 5
723} {SQLITE_OK}
724do_test backup-7.1.2 {
725 sqlite3 db3 test.db
726 execsql { BEGIN EXCLUSIVE } db3
727 B step 5
728} {SQLITE_BUSY}
729do_test backup-7.1.3 {
730 execsql { ROLLBACK } db3
731 B step 5
732} {SQLITE_OK}
733do_test backup-7.2.1 {
734 execsql {
735 BEGIN;
736 INSERT INTO t1 VALUES(1, 4);
737 }
738} {}
739do_test backup-7.2.2 {
740 B step 5000
danielk1977404ca072009-03-16 13:19:36 +0000741} {SQLITE_BUSY}
danielk197704103022009-02-03 16:51:24 +0000742do_test backup-7.2.3 {
743 execsql { ROLLBACK }
744 B step 5000
745} {SQLITE_DONE}
746do_test backup-7.2.4 {
747 B finish
748} {SQLITE_OK}
749test_contents backup-7.2.5 db main db2 main
750integrity_check backup-7.3.6 db2
751
752do_test backup-7.3.1 {
753 db2 close
754 db3 close
755 file delete -force test2.db
756 sqlite3 db2 test2.db
757 sqlite3 db3 test2.db
758
759 sqlite3_backup B db2 main db main
760 execsql { BEGIN ; CREATE TABLE t2(a, b); } db3
761
762 B step 5
763} {SQLITE_BUSY}
764do_test backup-7.3.2 {
765 execsql { COMMIT } db3
766 B step 5000
767} {SQLITE_DONE}
768do_test backup-7.3.3 {
769 B finish
770} {SQLITE_OK}
771test_contents backup-7.3.4 db main db2 main
772integrity_check backup-7.3.5 db2
773catch { db2 close }
774catch { db3 close }
775
776#-----------------------------------------------------------------------
777# The following tests, backup-8.*, test attaching multiple backup
778# processes to the same source database. Also, reading from the source
779# database while a read transaction is active.
780#
781# These tests reuse the database "test.db" left over from backup-7.*.
782#
783do_test backup-8.1 {
784 catch { file delete -force test2.db }
785 catch { file delete -force test3.db }
786 sqlite3 db2 test2.db
787 sqlite3 db3 test3.db
788
789 sqlite3_backup B2 db2 main db main
790 sqlite3_backup B3 db3 main db main
791 list [B2 finish] [B3 finish]
792} {SQLITE_OK SQLITE_OK}
793do_test backup-8.2 {
794 sqlite3_backup B3 db3 main db main
795 sqlite3_backup B2 db2 main db main
796 list [B2 finish] [B3 finish]
797} {SQLITE_OK SQLITE_OK}
798do_test backup-8.3 {
799 sqlite3_backup B2 db2 main db main
800 sqlite3_backup B3 db3 main db main
801 B2 step 5
802} {SQLITE_OK}
803do_test backup-8.4 {
804 execsql {
805 BEGIN;
806 SELECT * FROM sqlite_master;
807 }
808 B3 step 5
809} {SQLITE_OK}
810do_test backup-8.5 {
811 list [B3 step 5000] [B3 finish]
812} {SQLITE_DONE SQLITE_OK}
813do_test backup-8.6 {
814 list [B2 step 5000] [B2 finish]
815} {SQLITE_DONE SQLITE_OK}
816test_contents backup-8.7 db main db2 main
817test_contents backup-8.8 db main db3 main
818do_test backup-8.9 {
819 execsql { PRAGMA lock_status }
820} {main shared temp closed}
821do_test backup-8.10 {
822 execsql COMMIT
823} {}
824catch { db2 close }
825catch { db3 close }
826
danielk197703ab0352009-02-06 05:59:44 +0000827#-----------------------------------------------------------------------
828# The following tests, backup-9.*, test that:
829#
830# * Passing 0 as an argument to sqlite3_backup_step() means no pages
831# are backed up (backup-9.1.*), and
832# * Passing a negative value as an argument to sqlite3_backup_step() means
833# all pages are backed up (backup-9.2.*).
834#
835# These tests reuse the database "test.db" left over from backup-7.*.
836#
837do_test backup-9.1.1 {
838 sqlite3 db2 test2.db
839 sqlite3_backup B db2 main db main
840 B step 1
841} {SQLITE_OK}
842do_test backup-9.1.2 {
843 set nRemaining [B remaining]
844 expr {$nRemaining>100}
845} {1}
846do_test backup-9.1.3 {
847 B step 0
848} {SQLITE_OK}
849do_test backup-9.1.4 {
850 B remaining
851} $nRemaining
852
853do_test backup-9.2.1 {
854 B step -1
855} {SQLITE_DONE}
856do_test backup-9.2.2 {
857 B remaining
858} {0}
859do_test backup-9.2.3 {
860 B finish
861} {SQLITE_OK}
862catch {db2 close}
danielk197704103022009-02-03 16:51:24 +0000863
danielk1977e70f4f62009-05-13 07:52:06 +0000864ifcapable memorymanage {
865 db close
866 file delete -force test.db
867 file delete -force bak.db
868
869 sqlite3 db test.db
870 sqlite3 db2 test.db
871 sqlite3 db3 bak.db
872
873 do_test backup-10.1.1 {
874 execsql {
875 BEGIN;
876 CREATE TABLE t1(a, b);
877 INSERT INTO t1 VALUES(1, randstr(1000,1000));
878 INSERT INTO t1 VALUES(2, randstr(1000,1000));
879 INSERT INTO t1 VALUES(3, randstr(1000,1000));
880 INSERT INTO t1 VALUES(4, randstr(1000,1000));
881 INSERT INTO t1 VALUES(5, randstr(1000,1000));
882 CREATE INDEX i1 ON t1(a, b);
883 COMMIT;
884 }
885 } {}
886 do_test backup-10.1.2 {
887 sqlite3_backup B db3 main db2 main
888 B step 5
889 } {SQLITE_OK}
890 do_test backup-10.1.3 {
891 execsql {
892 UPDATE t1 SET b = randstr(500,500);
893 }
894 } {}
895 sqlite3_release_memory [expr 1024*1024]
896 do_test backup-10.1.3 {
897 B step 50
898 } {SQLITE_DONE}
899 do_test backup-10.1.4 {
900 B finish
901 } {SQLITE_OK}
902 do_test backup-10.1.5 {
903 execsql { PRAGMA integrity_check } db3
904 } {ok}
905
906 db2 close
907 db3 close
908}
909
dan33d58bc2010-01-13 14:08:01 +0000910
dan3306c4a2010-04-23 19:15:00 +0000911#-----------------------------------------------------------------------
dan33d58bc2010-01-13 14:08:01 +0000912# Test that if the database is written to via the same database handle being
913# used as the source by a backup operation:
914#
915# 10.1.*: If the db is in-memory, the backup is restarted.
916# 10.2.*: If the db is a file, the backup is not restarted.
917#
918db close
919file delete -force test.db test.db-journal
920foreach {tn file rc} {
921 1 test.db SQLITE_DONE
922 2 :memory: SQLITE_OK
923} {
924 do_test backup-10.$tn.1 {
925 sqlite3 db $file
926 execsql {
927 CREATE TABLE t1(a INTEGER PRIMARY KEY, b BLOB);
928 BEGIN;
929 INSERT INTO t1 VALUES(NULL, randomblob(200));
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 INSERT INTO t1 SELECT NULL, randomblob(200) FROM t1;
938 COMMIT;
939 SELECT count(*) FROM t1;
940 }
941 } {256}
942
943 do_test backup-10.$tn.2 {
944 set pgs [execsql {pragma page_count}]
945 expr {$pgs > 50 && $pgs < 75}
946 } {1}
947
948 do_test backup-10.$tn.3 {
949 file delete -force bak.db bak.db-journal
950 sqlite3 db2 bak.db
951 sqlite3_backup B db2 main db main
952 B step 50
953 } {SQLITE_OK}
954
955 do_test backup-10.$tn.4 {
956 execsql { UPDATE t1 SET b = randomblob(200) WHERE a IN (1, 250) }
957 } {}
958
959 do_test backup-10.$tn.5 {
960 B step 50
961 } $rc
962
shaneh942179f2010-03-09 15:10:30 +0000963 do_test backup-10.$tn.6 {
dan33d58bc2010-01-13 14:08:01 +0000964 B finish
965 } {SQLITE_OK}
shaneh942179f2010-03-09 15:10:30 +0000966
967 db2 close
dan33d58bc2010-01-13 14:08:01 +0000968}
969
danielk197704103022009-02-03 16:51:24 +0000970finish_test