1dc2c4915Sdrh# 2009 January 30 20410302eSdanielk1977# 30410302eSdanielk1977# The author disclaims copyright to this source code. In place of 40410302eSdanielk1977# a legal notice, here is a blessing: 50410302eSdanielk1977# 60410302eSdanielk1977# May you do good and not evil. 70410302eSdanielk1977# May you find forgiveness for yourself and forgive others. 80410302eSdanielk1977# May you share freely, never taking more than you give. 90410302eSdanielk1977# 100410302eSdanielk1977#*********************************************************************** 110410302eSdanielk1977# This file implements regression tests for SQLite library. The 120410302eSdanielk1977# focus of this file is testing the sqlite3_backup_XXX API. 130410302eSdanielk1977# 14dda70fe3Sdrh# $Id: backup.test,v 1.11 2009/06/05 17:09:12 drh Exp $ 150410302eSdanielk1977 160410302eSdanielk1977set testdir [file dirname $argv0] 170410302eSdanielk1977source $testdir/tester.tcl 180410302eSdanielk1977 1968928b6cSdando_not_use_codec 2068928b6cSdan 210410302eSdanielk1977#--------------------------------------------------------------------- 220410302eSdanielk1977# Test organization: 230410302eSdanielk1977# 240410302eSdanielk1977# backup-1.*: Warm-body tests. 250410302eSdanielk1977# 260410302eSdanielk1977# backup-2.*: Test backup under various conditions. To and from in-memory 270410302eSdanielk1977# databases. To and from empty/populated databases. etc. 280410302eSdanielk1977# 290410302eSdanielk1977# backup-3.*: Verify that the locking-page (pending byte page) is handled. 300410302eSdanielk1977# 310410302eSdanielk1977# backup-4.*: Test various error conditions. 320410302eSdanielk1977# 330410302eSdanielk1977# backup-5.*: Test the source database being modified during a backup. 340410302eSdanielk1977# 350410302eSdanielk1977# backup-6.*: Test the backup_remaining() and backup_pagecount() APIs. 360410302eSdanielk1977# 370410302eSdanielk1977# backup-7.*: Test SQLITE_BUSY and SQLITE_LOCKED errors. 380410302eSdanielk1977# 390410302eSdanielk1977# backup-8.*: Test multiple simultaneous backup operations. 400410302eSdanielk1977# 4103ab0357Sdanielk1977# backup-9.*: Test that passing a negative argument to backup_step() is 4203ab0357Sdanielk1977# interpreted as "copy the whole file". 4303ab0357Sdanielk1977# 443306c4a9Sdan# backup-10.*: Test writing the source database mid backup. 453306c4a9Sdan# 460410302eSdanielk1977 470410302eSdanielk1977proc data_checksum {db file} { $db one "SELECT md5sum(a, b) FROM ${file}.t1" } 480410302eSdanielk1977proc test_contents {name db1 file1 db2 file2} { 490410302eSdanielk1977 $db2 eval {select * from sqlite_master} 500410302eSdanielk1977 $db1 eval {select * from sqlite_master} 510410302eSdanielk1977 set checksum [data_checksum $db2 $file2] 520410302eSdanielk1977 uplevel [list do_test $name [list data_checksum $db1 $file1] $checksum] 530410302eSdanielk1977} 540410302eSdanielk1977 550410302eSdanielk1977do_test backup-1.1 { 560410302eSdanielk1977 execsql { 570410302eSdanielk1977 BEGIN; 580410302eSdanielk1977 CREATE TABLE t1(a, b); 590410302eSdanielk1977 CREATE INDEX i1 ON t1(a, b); 600410302eSdanielk1977 INSERT INTO t1 VALUES(1, randstr(1000,1000)); 610410302eSdanielk1977 INSERT INTO t1 VALUES(2, randstr(1000,1000)); 620410302eSdanielk1977 INSERT INTO t1 VALUES(3, randstr(1000,1000)); 630410302eSdanielk1977 INSERT INTO t1 VALUES(4, randstr(1000,1000)); 640410302eSdanielk1977 INSERT INTO t1 VALUES(5, randstr(1000,1000)); 650410302eSdanielk1977 COMMIT; 660410302eSdanielk1977 } 670410302eSdanielk1977} {} 680410302eSdanielk1977 690410302eSdanielk1977# Sanity check to verify that the [test_contents] proc works. 700410302eSdanielk1977# 710410302eSdanielk1977test_contents backup-1.2 db main db main 720410302eSdanielk1977 730410302eSdanielk1977# Check that it is possible to create and finish backup operations. 740410302eSdanielk1977# 750410302eSdanielk1977do_test backup-1.3.1 { 76fda06befSmistachkin delete_file test2.db 770410302eSdanielk1977 sqlite3 db2 test2.db 780410302eSdanielk1977 sqlite3_backup B db2 main db main 790410302eSdanielk1977} {B} 800410302eSdanielk1977do_test backup-1.3.2 { 810410302eSdanielk1977 B finish 820410302eSdanielk1977} {SQLITE_OK} 830410302eSdanielk1977do_test backup-1.3.3 { 840410302eSdanielk1977 info commands B 850410302eSdanielk1977} {} 860410302eSdanielk1977 870410302eSdanielk1977# Simplest backup operation. Backup test.db to test2.db. test2.db is 880410302eSdanielk1977# initially empty. test.db uses the default page size. 890410302eSdanielk1977# 900410302eSdanielk1977do_test backup-1.4.1 { 910410302eSdanielk1977 sqlite3_backup B db2 main db main 920410302eSdanielk1977} {B} 930410302eSdanielk1977do_test backup-1.4.2 { 940410302eSdanielk1977 B step 200 950410302eSdanielk1977} {SQLITE_DONE} 960410302eSdanielk1977do_test backup-1.4.3 { 970410302eSdanielk1977 B finish 980410302eSdanielk1977} {SQLITE_OK} 990410302eSdanielk1977do_test backup-1.4.4 { 1000410302eSdanielk1977 info commands B 1010410302eSdanielk1977} {} 1020410302eSdanielk1977test_contents backup-1.4.5 db2 main db main 1030410302eSdanielk1977db close 1040410302eSdanielk1977db2 close 1050410302eSdanielk1977# 1060410302eSdanielk1977# End of backup-1.* tests. 1070410302eSdanielk1977#--------------------------------------------------------------------- 1080410302eSdanielk1977 1090410302eSdanielk1977 1100410302eSdanielk1977#--------------------------------------------------------------------- 1110410302eSdanielk1977# The following tests, backup-2.*, are based on the following procedure: 1120410302eSdanielk1977# 1130410302eSdanielk1977# 1) Populate the source database. 1140410302eSdanielk1977# 2) Populate the destination database. 1150410302eSdanielk1977# 3) Run the backup to completion. (backup-2.*.1) 1160410302eSdanielk1977# 4) Integrity check the destination db. (backup-2.*.2) 1170410302eSdanielk1977# 5) Check that the contents of the destination db is the same as that 1180410302eSdanielk1977# of the source db. (backup-2.*.3) 1190410302eSdanielk1977# 1200410302eSdanielk1977# The test is run with all possible combinations of the following 1210410302eSdanielk1977# input parameters, except that if the destination is an in-memory 1220410302eSdanielk1977# database, the only page size tested is 1024 bytes (the same as the 1230410302eSdanielk1977# source page-size). 1240410302eSdanielk1977# 1250410302eSdanielk1977# * Source database is an in-memory database, OR 1260410302eSdanielk1977# * Source database is a file-backed database. 1270410302eSdanielk1977# 1280410302eSdanielk1977# * Target database is an in-memory database, OR 1290410302eSdanielk1977# * Target database is a file-backed database. 1300410302eSdanielk1977# 1310410302eSdanielk1977# * Destination database is a main file, OR 1320410302eSdanielk1977# * Destination database is an attached file, OR 1330410302eSdanielk1977# * Destination database is a temp database. 1340410302eSdanielk1977# 1350410302eSdanielk1977# * Target database is empty (zero bytes), OR 1360410302eSdanielk1977# * Target database is larger than the source, OR 1370410302eSdanielk1977# * Target database is smaller than the source. 1380410302eSdanielk1977# 1390410302eSdanielk1977# * Target database page-size is the same as the source, OR 1400410302eSdanielk1977# * Target database page-size is larger than the source, OR 1410410302eSdanielk1977# * Target database page-size is smaller than the source. 1420410302eSdanielk1977# 1430410302eSdanielk1977# * Each call to step copies a single page, OR 1440410302eSdanielk1977# * A single call to step copies the entire source database. 1450410302eSdanielk1977# 1460410302eSdanielk1977set iTest 1 1470410302eSdanielk1977foreach zSrcFile {test.db :memory:} { 1480410302eSdanielk1977foreach zDestFile {test2.db :memory:} { 1490410302eSdanielk1977foreach zOpenScript [list { 1500410302eSdanielk1977 sqlite3 db $zSrcFile 1510410302eSdanielk1977 sqlite3 db2 $zSrcFile 1520410302eSdanielk1977 db2 eval "ATTACH '$zDestFile' AS bak" 1530410302eSdanielk1977 set db_dest db2 1540410302eSdanielk1977 set file_dest bak 1550410302eSdanielk1977} { 1560410302eSdanielk1977 sqlite3 db $zSrcFile 1570410302eSdanielk1977 sqlite3 db2 $zDestFile 1580410302eSdanielk1977 set db_dest db2 1590410302eSdanielk1977 set file_dest main 1600410302eSdanielk1977} { 1610410302eSdanielk1977 sqlite3 db $zSrcFile 1620410302eSdanielk1977 sqlite3 db2 $zDestFile 1630410302eSdanielk1977 set db_dest db2 1640410302eSdanielk1977 set file_dest temp 1650410302eSdanielk1977}] { 1660410302eSdanielk1977foreach rows_dest {0 3 10} { 1679bf01363Sdanforeach pgsz_dest {512 1024 2048 4096} { 1680410302eSdanielk1977foreach nPagePerStep {1 200} { 1690410302eSdanielk1977 1700410302eSdanielk1977 # Open the databases. 171fda06befSmistachkin catch { delete_file test.db } 172fda06befSmistachkin catch { delete_file test2.db } 1730410302eSdanielk1977 eval $zOpenScript 1740410302eSdanielk1977 1753d781c21Sdanielk1977 # Set to true if copying to an in-memory destination. Copying to an 1763d781c21Sdanielk1977 # in-memory destination is only possible if the initial destination 1773d781c21Sdanielk1977 # page size is the same as the source page size (in this case 1024 bytes). 1783d781c21Sdanielk1977 # 1799bf01363Sdan set isMemDest [expr { $zDestFile eq ":memory:" || $file_dest eq "temp" }] 1800410302eSdanielk1977 1810410302eSdanielk1977 if 0 { 1820410302eSdanielk1977 puts -nonewline "Test $iTest: src=$zSrcFile dest=$zDestFile" 1830410302eSdanielk1977 puts -nonewline " (as $db_dest.$file_dest)" 1840410302eSdanielk1977 puts -nonewline " rows_dest=$rows_dest pgsz_dest=$pgsz_dest" 1850410302eSdanielk1977 puts "" 1860410302eSdanielk1977 } 1870410302eSdanielk1977 1889bf01363Sdan if { $isMemDest==0 || $pgsz_dest==1024 || $rows_dest==0 } { 1899bf01363Sdan 1900410302eSdanielk1977 # Set up the content of the source database. 1910410302eSdanielk1977 execsql { 1923d781c21Sdanielk1977 PRAGMA page_size = 1024; 1930410302eSdanielk1977 BEGIN; 1940410302eSdanielk1977 CREATE TABLE t1(a, b); 1950410302eSdanielk1977 CREATE INDEX i1 ON t1(a, b); 1960410302eSdanielk1977 INSERT INTO t1 VALUES(1, randstr(1000,1000)); 1970410302eSdanielk1977 INSERT INTO t1 VALUES(2, randstr(1000,1000)); 1980410302eSdanielk1977 INSERT INTO t1 VALUES(3, randstr(1000,1000)); 1990410302eSdanielk1977 INSERT INTO t1 VALUES(4, randstr(1000,1000)); 2000410302eSdanielk1977 INSERT INTO t1 VALUES(5, randstr(1000,1000)); 2010410302eSdanielk1977 COMMIT; 2020410302eSdanielk1977 } 2030410302eSdanielk1977 2040410302eSdanielk1977 2050410302eSdanielk1977 2060410302eSdanielk1977 # Set up the content of the target database. 2070410302eSdanielk1977 execsql "PRAGMA ${file_dest}.page_size = ${pgsz_dest}" $db_dest 2080410302eSdanielk1977 if {$rows_dest != 0} { 2090410302eSdanielk1977 execsql " 2100410302eSdanielk1977 BEGIN; 2110410302eSdanielk1977 CREATE TABLE ${file_dest}.t1(a, b); 2120410302eSdanielk1977 CREATE INDEX ${file_dest}.i1 ON t1(a, b); 2130410302eSdanielk1977 " $db_dest 2140410302eSdanielk1977 for {set ii 0} {$ii < $rows_dest} {incr ii} { 2150410302eSdanielk1977 execsql " 2160410302eSdanielk1977 INSERT INTO ${file_dest}.t1 VALUES(1, randstr(1000,1000)) 2170410302eSdanielk1977 " $db_dest 2180410302eSdanielk1977 } 219fad01993Sdan execsql COMMIT $db_dest 2200410302eSdanielk1977 } 2210410302eSdanielk1977 2220410302eSdanielk1977 # Backup the source database. 2230410302eSdanielk1977 do_test backup-2.$iTest.1 { 2240410302eSdanielk1977 sqlite3_backup B $db_dest $file_dest db main 2250410302eSdanielk1977 while {[B step $nPagePerStep]=="SQLITE_OK"} {} 2260410302eSdanielk1977 B finish 2270410302eSdanielk1977 } {SQLITE_OK} 2280410302eSdanielk1977 2290410302eSdanielk1977 # Run integrity check on the backup. 2300410302eSdanielk1977 do_test backup-2.$iTest.2 { 2310410302eSdanielk1977 execsql "PRAGMA ${file_dest}.integrity_check" $db_dest 2320410302eSdanielk1977 } {ok} 2330410302eSdanielk1977 2340410302eSdanielk1977 test_contents backup-2.$iTest.3 db main $db_dest $file_dest 2350410302eSdanielk1977 2360410302eSdanielk1977 } 2370410302eSdanielk1977 2380410302eSdanielk1977 db close 2390410302eSdanielk1977 catch {db2 close} 2400410302eSdanielk1977 incr iTest 2410410302eSdanielk1977 2420410302eSdanielk1977} } } } } } 2430410302eSdanielk1977# 2440410302eSdanielk1977# End of backup-2.* tests. 2450410302eSdanielk1977#--------------------------------------------------------------------- 2460410302eSdanielk1977 2470410302eSdanielk1977#--------------------------------------------------------------------- 2480410302eSdanielk1977# These tests, backup-3.*, ensure that nothing goes wrong if either 2490410302eSdanielk1977# the source or destination database are large enough to include the 2500410302eSdanielk1977# the locking-page (the page that contains the range of bytes that 2510410302eSdanielk1977# the locks are applied to). These tests assume that the pending 2520410302eSdanielk1977# byte is at offset 0x00010000 (64KB offset), as set by tester.tcl, 2530410302eSdanielk1977# not at the 1GB offset as it usually is. 2540410302eSdanielk1977# 2550410302eSdanielk1977# The test procedure is as follows (same procedure as used for 2560410302eSdanielk1977# the backup-2.* tests): 2570410302eSdanielk1977# 2580410302eSdanielk1977# 1) Populate the source database. 2590410302eSdanielk1977# 2) Populate the destination database. 2600410302eSdanielk1977# 3) Run the backup to completion. (backup-3.*.1) 2610410302eSdanielk1977# 4) Integrity check the destination db. (backup-3.*.2) 2620410302eSdanielk1977# 5) Check that the contents of the destination db is the same as that 2630410302eSdanielk1977# of the source db. (backup-3.*.3) 2640410302eSdanielk1977# 2650410302eSdanielk1977# The test procedure is run with the following parameters varied: 2660410302eSdanielk1977# 2670410302eSdanielk1977# * Source database includes pending-byte page. 2680410302eSdanielk1977# * Source database does not include pending-byte page. 2690410302eSdanielk1977# 2700410302eSdanielk1977# * Target database includes pending-byte page. 2710410302eSdanielk1977# * Target database does not include pending-byte page. 2720410302eSdanielk1977# 2730410302eSdanielk1977# * Target database page-size is the same as the source, OR 2740410302eSdanielk1977# * Target database page-size is larger than the source, OR 2750410302eSdanielk1977# * Target database page-size is smaller than the source. 2760410302eSdanielk1977# 2770410302eSdanielk1977set iTest 1 2783d0cbc33Sdanielk1977foreach nSrcPg {10 64 65 66 100} { 2790410302eSdanielk1977foreach nDestRow {10 100} { 2800410302eSdanielk1977foreach nDestPgsz {512 1024 2048 4096} { 2810410302eSdanielk1977 282fda06befSmistachkin catch { delete_file test.db } 283fda06befSmistachkin catch { delete_file test2.db } 2840410302eSdanielk1977 sqlite3 db test.db 2850410302eSdanielk1977 sqlite3 db2 test2.db 2860410302eSdanielk1977 2870410302eSdanielk1977 # Set up the content of the two databases. 2880410302eSdanielk1977 # 2893d0cbc33Sdanielk1977 execsql { PRAGMA page_size = 1024 } 2903d0cbc33Sdanielk1977 execsql "PRAGMA page_size = $nDestPgsz" db2 2913d0cbc33Sdanielk1977 foreach db {db db2} { 2920410302eSdanielk1977 execsql { 2930410302eSdanielk1977 BEGIN; 2940410302eSdanielk1977 CREATE TABLE t1(a, b); 2950410302eSdanielk1977 CREATE INDEX i1 ON t1(a, b); 2963d0cbc33Sdanielk1977 COMMIT; 2970410302eSdanielk1977 } $db 2980410302eSdanielk1977 } 2993d0cbc33Sdanielk1977 while {[file size test.db]/1024 < $nSrcPg} { 3003d0cbc33Sdanielk1977 execsql { INSERT INTO t1 VALUES($ii, randstr(200,200)) } 3013d0cbc33Sdanielk1977 } 3023d0cbc33Sdanielk1977 3033d0cbc33Sdanielk1977 for {set ii 0} {$ii < $nDestRow} {incr ii} { 3043d0cbc33Sdanielk1977 execsql { INSERT INTO t1 VALUES($ii, randstr(1000,1000)) } db2 3050410302eSdanielk1977 } 3060410302eSdanielk1977 3070410302eSdanielk1977 # Backup the source database. 3080410302eSdanielk1977 do_test backup-3.$iTest.1 { 3090410302eSdanielk1977 sqlite3_backup B db main db2 main 3100410302eSdanielk1977 while {[B step 10]=="SQLITE_OK"} {} 3110410302eSdanielk1977 B finish 3120410302eSdanielk1977 } {SQLITE_OK} 3130410302eSdanielk1977 3140410302eSdanielk1977 # Run integrity check on the backup. 3150410302eSdanielk1977 do_test backup-3.$iTest.2 { 3160410302eSdanielk1977 execsql "PRAGMA integrity_check" db2 3170410302eSdanielk1977 } {ok} 3180410302eSdanielk1977 3190410302eSdanielk1977 test_contents backup-3.$iTest.3 db main db2 main 3200410302eSdanielk1977 3210410302eSdanielk1977 db close 3220410302eSdanielk1977 db2 close 3230410302eSdanielk1977 incr iTest 3240410302eSdanielk1977} 3250410302eSdanielk1977} 3260410302eSdanielk1977} 327f2a79f22Sdanielk1977 328f2a79f22Sdanielk1977#-------------------------------------------------------------------- 329f2a79f22Sdanielk1977do_test backup-3.$iTest.1 { 330fda06befSmistachkin catch { forcedelete test.db } 331fda06befSmistachkin catch { forcedelete test2.db } 332f2a79f22Sdanielk1977 sqlite3 db test.db 333f2a79f22Sdanielk1977 set iTab 1 334f2a79f22Sdanielk1977 335f2a79f22Sdanielk1977 db eval { PRAGMA page_size = 512 } 336f2a79f22Sdanielk1977 while {[file size test.db] <= $::sqlite_pending_byte} { 337f2a79f22Sdanielk1977 db eval "CREATE TABLE t${iTab}(a, b, c)" 338f2a79f22Sdanielk1977 incr iTab 339f2a79f22Sdanielk1977 } 340f2a79f22Sdanielk1977 341f2a79f22Sdanielk1977 sqlite3 db2 test2.db 342f2a79f22Sdanielk1977 db2 eval { PRAGMA page_size = 4096 } 343f2a79f22Sdanielk1977 while {[file size test2.db] < $::sqlite_pending_byte} { 344f2a79f22Sdanielk1977 db2 eval "CREATE TABLE t${iTab}(a, b, c)" 345f2a79f22Sdanielk1977 incr iTab 346f2a79f22Sdanielk1977 } 347f2a79f22Sdanielk1977 348f2a79f22Sdanielk1977 sqlite3_backup B db2 main db main 349f2a79f22Sdanielk1977 B step -1 350f2a79f22Sdanielk1977} {SQLITE_DONE} 351f2a79f22Sdanielk1977 352f2a79f22Sdanielk1977do_test backup-3.$iTest.2 { 353f2a79f22Sdanielk1977 B finish 354f2a79f22Sdanielk1977} {SQLITE_OK} 355f2a79f22Sdanielk1977 3560410302eSdanielk1977# 3570410302eSdanielk1977# End of backup-3.* tests. 3580410302eSdanielk1977#--------------------------------------------------------------------- 3590410302eSdanielk1977 3600410302eSdanielk1977 3610410302eSdanielk1977#--------------------------------------------------------------------- 3620410302eSdanielk1977# The following tests, backup-4.*, test various error conditions: 3630410302eSdanielk1977# 3640410302eSdanielk1977# backup-4.1.*: Test invalid database names. 3650410302eSdanielk1977# 3660410302eSdanielk1977# backup-4.2.*: Test that the source database cannot be detached while 3670410302eSdanielk1977# a backup is in progress. 3680410302eSdanielk1977# 3690410302eSdanielk1977# backup-4.3.*: Test that the source database handle cannot be closed 3700410302eSdanielk1977# while a backup is in progress. 3710410302eSdanielk1977# 3720410302eSdanielk1977# backup-4.4.*: Test an attempt to specify the same handle for the 3730410302eSdanielk1977# source and destination databases. 3740410302eSdanielk1977# 3750410302eSdanielk1977# backup-4.5.*: Test that an in-memory destination with a different 3760410302eSdanielk1977# page-size to the source database is an error. 3770410302eSdanielk1977# 3780410302eSdanielk1977sqlite3 db test.db 3790410302eSdanielk1977sqlite3 db2 test2.db 3800410302eSdanielk1977 3810410302eSdanielk1977do_test backup-4.1.1 { 3820410302eSdanielk1977 catch { sqlite3_backup B db aux db2 main } 3830410302eSdanielk1977} {1} 3840410302eSdanielk1977do_test backup-4.1.2 { 3850410302eSdanielk1977 sqlite3_errmsg db 3860410302eSdanielk1977} {unknown database aux} 3870410302eSdanielk1977do_test backup-4.1.3 { 3880410302eSdanielk1977 catch { sqlite3_backup B db main db2 aux } 3890410302eSdanielk1977} {1} 3900410302eSdanielk1977do_test backup-4.1.4 { 3910410302eSdanielk1977 sqlite3_errmsg db 3920410302eSdanielk1977} {unknown database aux} 3930410302eSdanielk1977 3940410302eSdanielk1977do_test backup-4.2.1 { 395fda06befSmistachkin catch { forcedelete test3.db } 396fda06befSmistachkin catch { forcedelete test4.db } 3973d781c21Sdanielk1977 execsql { 3983d781c21Sdanielk1977 ATTACH 'test3.db' AS aux1; 3993d781c21Sdanielk1977 CREATE TABLE aux1.t1(a, b); 4003d781c21Sdanielk1977 } 4013d781c21Sdanielk1977 execsql { 4023d781c21Sdanielk1977 ATTACH 'test4.db' AS aux2; 4033d781c21Sdanielk1977 CREATE TABLE aux2.t2(a, b); 4043d781c21Sdanielk1977 } db2 4050410302eSdanielk1977 sqlite3_backup B db aux1 db2 aux2 4060410302eSdanielk1977} {B} 4070410302eSdanielk1977do_test backup-4.2.2 { 4080410302eSdanielk1977 catchsql { DETACH aux2 } db2 4090410302eSdanielk1977} {1 {database aux2 is locked}} 4100410302eSdanielk1977do_test backup-4.2.3 { 4110410302eSdanielk1977 B step 50 4120410302eSdanielk1977} {SQLITE_DONE} 4130410302eSdanielk1977do_test backup-4.2.4 { 4140410302eSdanielk1977 B finish 4150410302eSdanielk1977} {SQLITE_OK} 4160410302eSdanielk1977 4170410302eSdanielk1977do_test backup-4.3.1 { 4180410302eSdanielk1977 sqlite3_backup B db aux1 db2 aux2 4190410302eSdanielk1977} {B} 4200410302eSdanielk1977do_test backup-4.3.2 { 4210410302eSdanielk1977 db2 cache flush 422167cd6abSdrh sqlite3_close db2 423167cd6abSdrh} {SQLITE_BUSY} 424167cd6abSdrhdo_test backup-4.3.3 { 425167cd6abSdrh sqlite3_errmsg db2 426167cd6abSdrh} {unable to close due to unfinalized statements or unfinished backups} 4270410302eSdanielk1977do_test backup-4.3.4 { 4280410302eSdanielk1977 B step 50 4290410302eSdanielk1977} {SQLITE_DONE} 4300410302eSdanielk1977do_test backup-4.3.5 { 4310410302eSdanielk1977 B finish 4320410302eSdanielk1977} {SQLITE_OK} 4330410302eSdanielk1977 4340410302eSdanielk1977do_test backup-4.4.1 { 4350410302eSdanielk1977 set rc [catch {sqlite3_backup B db main db aux1}] 4360410302eSdanielk1977 list $rc [sqlite3_errcode db] [sqlite3_errmsg db] 437b309becdSdrh} {1 SQLITE_ERROR {source and destination must be distinct}} 4380410302eSdanielk1977db close 439167cd6abSdrhdb2 close 4400410302eSdanielk1977 4410410302eSdanielk1977do_test backup-4.5.1 { 442fda06befSmistachkin catch { forcedelete test.db } 4430410302eSdanielk1977 sqlite3 db test.db 4440410302eSdanielk1977 sqlite3 db2 :memory: 4450410302eSdanielk1977 execsql { 4460410302eSdanielk1977 CREATE TABLE t1(a, b); 4470410302eSdanielk1977 INSERT INTO t1 VALUES(1, 2); 4480410302eSdanielk1977 } 4490410302eSdanielk1977 execsql { 4500410302eSdanielk1977 PRAGMA page_size = 4096; 4510410302eSdanielk1977 CREATE TABLE t2(a, b); 4520410302eSdanielk1977 INSERT INTO t2 VALUES(3, 4); 4530410302eSdanielk1977 } db2 4540410302eSdanielk1977 sqlite3_backup B db2 main db main 4550410302eSdanielk1977} {B} 4560410302eSdanielk1977do_test backup-4.5.2 { 4570410302eSdanielk1977 B step 5000 4580410302eSdanielk1977} {SQLITE_READONLY} 4590410302eSdanielk1977do_test backup-4.5.3 { 4600410302eSdanielk1977 B finish 4610410302eSdanielk1977} {SQLITE_READONLY} 4620410302eSdanielk1977 4630410302eSdanielk1977db close 4640410302eSdanielk1977db2 close 4650410302eSdanielk1977# 4661feff7f1Sdan# End of backup-4.* tests. 4670410302eSdanielk1977#--------------------------------------------------------------------- 4680410302eSdanielk1977 4690410302eSdanielk1977#--------------------------------------------------------------------- 4700410302eSdanielk1977# The following tests, backup-5.*, test that the backup works properly 4710410302eSdanielk1977# when the source database is modified during the backup. Test cases 4720410302eSdanielk1977# are organized as follows: 4730410302eSdanielk1977# 4740410302eSdanielk1977# backup-5.x.1.*: Nothing special. Modify the database mid-backup. 4750410302eSdanielk1977# 4760410302eSdanielk1977# backup-5.x.2.*: Modify the database mid-backup so that one or more 4770410302eSdanielk1977# pages are written out due to cache stress. Then 4780410302eSdanielk1977# rollback the transaction. 4790410302eSdanielk1977# 4800410302eSdanielk1977# backup-5.x.3.*: Database is vacuumed. 4810410302eSdanielk1977# 4820410302eSdanielk1977# backup-5.x.4.*: Database is vacuumed and the page-size modified. 4830410302eSdanielk1977# 4840410302eSdanielk1977# backup-5.x.5.*: Database is shrunk via incr-vacuum. 4850410302eSdanielk1977# 4860410302eSdanielk1977# Each test is run three times, in the following configurations: 4870410302eSdanielk1977# 4880410302eSdanielk1977# 1) Backing up file-to-file. The writer writes via an external pager. 4890410302eSdanielk1977# 2) Backing up file-to-file. The writer writes via the same pager as 4900410302eSdanielk1977# is used by the backup operation. 4910410302eSdanielk1977# 3) Backing up memory-to-file. 4920410302eSdanielk1977# 4930410302eSdanielk1977set iTest 0 494fda06befSmistachkinforcedelete bak.db-wal 4950410302eSdanielk1977foreach {writer file} {db test.db db3 test.db db :memory:} { 4960410302eSdanielk1977 incr iTest 497fda06befSmistachkin catch { delete_file bak.db } 4980410302eSdanielk1977 sqlite3 db2 bak.db 499fda06befSmistachkin catch { delete_file $file } 5000410302eSdanielk1977 sqlite3 db $file 5010410302eSdanielk1977 sqlite3 db3 $file 5020410302eSdanielk1977 5030410302eSdanielk1977 do_test backup-5.$iTest.1.1 { 5040410302eSdanielk1977 execsql { 5050410302eSdanielk1977 BEGIN; 5060410302eSdanielk1977 CREATE TABLE t1(a, b); 5070410302eSdanielk1977 CREATE INDEX i1 ON t1(a, b); 5080410302eSdanielk1977 INSERT INTO t1 VALUES(1, randstr(1000,1000)); 5090410302eSdanielk1977 INSERT INTO t1 VALUES(2, randstr(1000,1000)); 5100410302eSdanielk1977 INSERT INTO t1 VALUES(3, randstr(1000,1000)); 5110410302eSdanielk1977 INSERT INTO t1 VALUES(4, randstr(1000,1000)); 5120410302eSdanielk1977 INSERT INTO t1 VALUES(5, randstr(1000,1000)); 5130410302eSdanielk1977 COMMIT; 5140410302eSdanielk1977 } 5150410302eSdanielk1977 expr {[execsql {PRAGMA page_count}] > 10} 5160410302eSdanielk1977 } {1} 5170410302eSdanielk1977 do_test backup-5.$iTest.1.2 { 5180410302eSdanielk1977 sqlite3_backup B db2 main db main 5190410302eSdanielk1977 B step 5 5200410302eSdanielk1977 } {SQLITE_OK} 5210410302eSdanielk1977 do_test backup-5.$iTest.1.3 { 5220410302eSdanielk1977 execsql { UPDATE t1 SET a = a + 1 } $writer 5230410302eSdanielk1977 B step 50 5240410302eSdanielk1977 } {SQLITE_DONE} 5250410302eSdanielk1977 do_test backup-5.$iTest.1.4 { 5260410302eSdanielk1977 B finish 5270410302eSdanielk1977 } {SQLITE_OK} 5280410302eSdanielk1977 integrity_check backup-5.$iTest.1.5 db2 5290410302eSdanielk1977 test_contents backup-5.$iTest.1.6 db main db2 main 5300410302eSdanielk1977 5310410302eSdanielk1977 do_test backup-5.$iTest.2.1 { 5320410302eSdanielk1977 execsql { 5330410302eSdanielk1977 PRAGMA cache_size = 10; 5340410302eSdanielk1977 BEGIN; 5350410302eSdanielk1977 INSERT INTO t1 SELECT '', randstr(1000,1000) FROM t1; 5360410302eSdanielk1977 INSERT INTO t1 SELECT '', randstr(1000,1000) FROM t1; 5370410302eSdanielk1977 INSERT INTO t1 SELECT '', randstr(1000,1000) FROM t1; 5380410302eSdanielk1977 INSERT INTO t1 SELECT '', randstr(1000,1000) FROM t1; 5390410302eSdanielk1977 COMMIT; 5400410302eSdanielk1977 } 5410410302eSdanielk1977 } {} 5420410302eSdanielk1977 do_test backup-5.$iTest.2.2 { 5430410302eSdanielk1977 sqlite3_backup B db2 main db main 5440410302eSdanielk1977 B step 50 5450410302eSdanielk1977 } {SQLITE_OK} 5460410302eSdanielk1977 do_test backup-5.$iTest.2.3 { 5470410302eSdanielk1977 execsql { 5480410302eSdanielk1977 BEGIN; 5490410302eSdanielk1977 UPDATE t1 SET a = a + 1; 5500410302eSdanielk1977 ROLLBACK; 5510410302eSdanielk1977 } $writer 5520410302eSdanielk1977 B step 5000 5530410302eSdanielk1977 } {SQLITE_DONE} 5540410302eSdanielk1977 do_test backup-5.$iTest.2.4 { 5550410302eSdanielk1977 B finish 5560410302eSdanielk1977 } {SQLITE_OK} 5570410302eSdanielk1977 integrity_check backup-5.$iTest.2.5 db2 5580410302eSdanielk1977 test_contents backup-5.$iTest.2.6 db main db2 main 5590410302eSdanielk1977 5600410302eSdanielk1977 do_test backup-5.$iTest.3.1 { 5610410302eSdanielk1977 execsql { UPDATE t1 SET b = randstr(1000,1000) } 5620410302eSdanielk1977 } {} 5630410302eSdanielk1977 do_test backup-5.$iTest.3.2 { 5640410302eSdanielk1977 sqlite3_backup B db2 main db main 5650410302eSdanielk1977 B step 50 5660410302eSdanielk1977 } {SQLITE_OK} 5670410302eSdanielk1977 do_test backup-5.$iTest.3.3 { 5680410302eSdanielk1977 execsql { VACUUM } $writer 5690410302eSdanielk1977 B step 5000 5700410302eSdanielk1977 } {SQLITE_DONE} 5710410302eSdanielk1977 do_test backup-5.$iTest.3.4 { 5720410302eSdanielk1977 B finish 5730410302eSdanielk1977 } {SQLITE_OK} 5740410302eSdanielk1977 integrity_check backup-5.$iTest.3.5 db2 5750410302eSdanielk1977 test_contents backup-5.$iTest.3.6 db main db2 main 5760410302eSdanielk1977 5770410302eSdanielk1977 do_test backup-5.$iTest.4.1 { 5780410302eSdanielk1977 execsql { UPDATE t1 SET b = randstr(1000,1000) } 5790410302eSdanielk1977 } {} 5800410302eSdanielk1977 do_test backup-5.$iTest.4.2 { 5810410302eSdanielk1977 sqlite3_backup B db2 main db main 5820410302eSdanielk1977 B step 50 5830410302eSdanielk1977 } {SQLITE_OK} 5840410302eSdanielk1977 do_test backup-5.$iTest.4.3 { 5850410302eSdanielk1977 execsql { 5860410302eSdanielk1977 PRAGMA page_size = 2048; 5870410302eSdanielk1977 VACUUM; 5880410302eSdanielk1977 } $writer 5890410302eSdanielk1977 B step 5000 5900410302eSdanielk1977 } {SQLITE_DONE} 5910410302eSdanielk1977 do_test backup-5.$iTest.4.4 { 5920410302eSdanielk1977 B finish 5930410302eSdanielk1977 } {SQLITE_OK} 5940410302eSdanielk1977 integrity_check backup-5.$iTest.4.5 db2 5950410302eSdanielk1977 test_contents backup-5.$iTest.4.6 db main db2 main 5960410302eSdanielk1977 597ce14f624Sshane catch {db close} 598ce14f624Sshane catch {db2 close} 599ce14f624Sshane catch {db3 close} 600fda06befSmistachkin catch { delete_file bak.db } 6010410302eSdanielk1977 sqlite3 db2 bak.db 602fda06befSmistachkin catch { delete_file $file } 6030410302eSdanielk1977 sqlite3 db $file 6040410302eSdanielk1977 sqlite3 db3 $file 6050410302eSdanielk1977 do_test backup-5.$iTest.5.1 { 6060410302eSdanielk1977 execsql { 6070410302eSdanielk1977 PRAGMA auto_vacuum = incremental; 6080410302eSdanielk1977 BEGIN; 6090410302eSdanielk1977 CREATE TABLE t1(a, b); 6100410302eSdanielk1977 CREATE INDEX i1 ON t1(a, b); 6110410302eSdanielk1977 INSERT INTO t1 VALUES(1, randstr(1000,1000)); 6120410302eSdanielk1977 INSERT INTO t1 VALUES(2, randstr(1000,1000)); 6130410302eSdanielk1977 INSERT INTO t1 VALUES(3, randstr(1000,1000)); 6140410302eSdanielk1977 INSERT INTO t1 VALUES(4, randstr(1000,1000)); 6150410302eSdanielk1977 INSERT INTO t1 VALUES(5, randstr(1000,1000)); 6160410302eSdanielk1977 COMMIT; 6170410302eSdanielk1977 } 6180410302eSdanielk1977 } {} 6190410302eSdanielk1977 do_test backup-5.$iTest.5.2 { 6200410302eSdanielk1977 sqlite3_backup B db2 main db main 6210410302eSdanielk1977 B step 8 6220410302eSdanielk1977 } {SQLITE_OK} 6230410302eSdanielk1977 do_test backup-5.$iTest.5.3 { 6240410302eSdanielk1977 execsql { 6250410302eSdanielk1977 DELETE FROM t1; 6260410302eSdanielk1977 PRAGMA incremental_vacuum; 6270410302eSdanielk1977 } $writer 6280410302eSdanielk1977 B step 50 6290410302eSdanielk1977 } {SQLITE_DONE} 6300410302eSdanielk1977 do_test backup-5.$iTest.5.4 { 6310410302eSdanielk1977 B finish 6320410302eSdanielk1977 } {SQLITE_OK} 6330410302eSdanielk1977 integrity_check backup-5.$iTest.5.5 db2 6340410302eSdanielk1977 test_contents backup-5.$iTest.5.6 db main db2 main 6350410302eSdanielk1977 catch {db close} 6360410302eSdanielk1977 catch {db2 close} 6370410302eSdanielk1977 catch {db3 close} 638ce14f624Sshane} 6390410302eSdanielk1977# 6400410302eSdanielk1977# End of backup-5.* tests. 6410410302eSdanielk1977#--------------------------------------------------------------------- 6420410302eSdanielk1977 6430410302eSdanielk1977#--------------------------------------------------------------------- 6440410302eSdanielk1977# Test the sqlite3_backup_remaining() and backup_pagecount() APIs. 6450410302eSdanielk1977# 6460410302eSdanielk1977do_test backup-6.1 { 647fda06befSmistachkin catch { forcedelete test.db } 648fda06befSmistachkin catch { forcedelete test2.db } 6490410302eSdanielk1977 sqlite3 db test.db 6500410302eSdanielk1977 sqlite3 db2 test2.db 6510410302eSdanielk1977 execsql { 6520410302eSdanielk1977 BEGIN; 6530410302eSdanielk1977 CREATE TABLE t1(a, b); 6540410302eSdanielk1977 CREATE INDEX i1 ON t1(a, b); 6550410302eSdanielk1977 INSERT INTO t1 VALUES(1, randstr(1000,1000)); 6560410302eSdanielk1977 INSERT INTO t1 VALUES(2, randstr(1000,1000)); 6570410302eSdanielk1977 INSERT INTO t1 VALUES(3, randstr(1000,1000)); 6580410302eSdanielk1977 INSERT INTO t1 VALUES(4, randstr(1000,1000)); 6590410302eSdanielk1977 INSERT INTO t1 VALUES(5, randstr(1000,1000)); 6600410302eSdanielk1977 COMMIT; 6610410302eSdanielk1977 } 6620410302eSdanielk1977} {} 6630410302eSdanielk1977do_test backup-6.2 { 6640410302eSdanielk1977 set nTotal [expr {[file size test.db]/1024}] 6650410302eSdanielk1977 sqlite3_backup B db2 main db main 6660410302eSdanielk1977 B step 1 6670410302eSdanielk1977} {SQLITE_OK} 6680410302eSdanielk1977do_test backup-6.3 { 6690410302eSdanielk1977 B pagecount 6700410302eSdanielk1977} $nTotal 6710410302eSdanielk1977do_test backup-6.4 { 6720410302eSdanielk1977 B remaining 6730410302eSdanielk1977} [expr $nTotal-1] 6740410302eSdanielk1977do_test backup-6.5 { 6750410302eSdanielk1977 B step 5 6760410302eSdanielk1977 list [B remaining] [B pagecount] 6770410302eSdanielk1977} [list [expr $nTotal-6] $nTotal] 6780410302eSdanielk1977do_test backup-6.6 { 6790410302eSdanielk1977 execsql { CREATE TABLE t2(a PRIMARY KEY, b) } 6800410302eSdanielk1977 B step 1 6810410302eSdanielk1977 list [B remaining] [B pagecount] 6820410302eSdanielk1977} [list [expr $nTotal-5] [expr $nTotal+2]] 6830410302eSdanielk1977 6840410302eSdanielk1977do_test backup-6.X { 6850410302eSdanielk1977 B finish 6860410302eSdanielk1977} {SQLITE_OK} 6870410302eSdanielk1977 688ce14f624Sshanecatch {db close} 689ce14f624Sshanecatch {db2 close} 6900410302eSdanielk1977 6910410302eSdanielk1977#--------------------------------------------------------------------- 6920410302eSdanielk1977# Test cases backup-7.* test that SQLITE_BUSY and SQLITE_LOCKED errors 6930410302eSdanielk1977# are returned correctly: 6940410302eSdanielk1977# 6950410302eSdanielk1977# backup-7.1.*: Source database is externally locked (return SQLITE_BUSY). 6960410302eSdanielk1977# 6970410302eSdanielk1977# backup-7.2.*: Attempt to step the backup process while a 6980410302eSdanielk1977# write-transaction is underway on the source pager (return 6990410302eSdanielk1977# SQLITE_LOCKED). 7000410302eSdanielk1977# 7010410302eSdanielk1977# backup-7.3.*: Destination database is externally locked (return SQLITE_BUSY). 7020410302eSdanielk1977# 7030410302eSdanielk1977do_test backup-7.0 { 704fda06befSmistachkin catch { forcedelete test.db } 705fda06befSmistachkin catch { forcedelete test2.db } 7060410302eSdanielk1977 sqlite3 db2 test2.db 7070410302eSdanielk1977 sqlite3 db test.db 7080410302eSdanielk1977 execsql { 7090410302eSdanielk1977 CREATE TABLE t1(a, b); 7100410302eSdanielk1977 CREATE INDEX i1 ON t1(a, b); 7110410302eSdanielk1977 INSERT INTO t1 VALUES(1, randstr(1000,1000)); 7120410302eSdanielk1977 INSERT INTO t1 SELECT a+ 1, randstr(1000,1000) FROM t1; 7130410302eSdanielk1977 INSERT INTO t1 SELECT a+ 2, randstr(1000,1000) FROM t1; 7140410302eSdanielk1977 INSERT INTO t1 SELECT a+ 4, randstr(1000,1000) FROM t1; 7150410302eSdanielk1977 INSERT INTO t1 SELECT a+ 8, randstr(1000,1000) FROM t1; 7160410302eSdanielk1977 INSERT INTO t1 SELECT a+16, randstr(1000,1000) FROM t1; 7170410302eSdanielk1977 INSERT INTO t1 SELECT a+32, randstr(1000,1000) FROM t1; 7180410302eSdanielk1977 INSERT INTO t1 SELECT a+64, randstr(1000,1000) FROM t1; 7190410302eSdanielk1977 } 7200410302eSdanielk1977} {} 7210410302eSdanielk1977 7220410302eSdanielk1977do_test backup-7.1.1 { 7230410302eSdanielk1977 sqlite3_backup B db2 main db main 7240410302eSdanielk1977 B step 5 7250410302eSdanielk1977} {SQLITE_OK} 7260410302eSdanielk1977do_test backup-7.1.2 { 7270410302eSdanielk1977 sqlite3 db3 test.db 7280410302eSdanielk1977 execsql { BEGIN EXCLUSIVE } db3 7290410302eSdanielk1977 B step 5 7300410302eSdanielk1977} {SQLITE_BUSY} 7310410302eSdanielk1977do_test backup-7.1.3 { 7320410302eSdanielk1977 execsql { ROLLBACK } db3 7330410302eSdanielk1977 B step 5 7340410302eSdanielk1977} {SQLITE_OK} 7350410302eSdanielk1977do_test backup-7.2.1 { 7360410302eSdanielk1977 execsql { 7370410302eSdanielk1977 BEGIN; 7380410302eSdanielk1977 INSERT INTO t1 VALUES(1, 4); 7390410302eSdanielk1977 } 7400410302eSdanielk1977} {} 7410410302eSdanielk1977do_test backup-7.2.2 { 7420410302eSdanielk1977 B step 5000 743404ca075Sdanielk1977} {SQLITE_BUSY} 7440410302eSdanielk1977do_test backup-7.2.3 { 7450410302eSdanielk1977 execsql { ROLLBACK } 7460410302eSdanielk1977 B step 5000 7470410302eSdanielk1977} {SQLITE_DONE} 7480410302eSdanielk1977do_test backup-7.2.4 { 7490410302eSdanielk1977 B finish 7500410302eSdanielk1977} {SQLITE_OK} 7510410302eSdanielk1977test_contents backup-7.2.5 db main db2 main 7520410302eSdanielk1977integrity_check backup-7.3.6 db2 7530410302eSdanielk1977 7540410302eSdanielk1977do_test backup-7.3.1 { 7550410302eSdanielk1977 db2 close 7560410302eSdanielk1977 db3 close 757fda06befSmistachkin forcedelete test2.db 7580410302eSdanielk1977 sqlite3 db2 test2.db 7590410302eSdanielk1977 sqlite3 db3 test2.db 7600410302eSdanielk1977 7610410302eSdanielk1977 sqlite3_backup B db2 main db main 7620410302eSdanielk1977 execsql { BEGIN ; CREATE TABLE t2(a, b); } db3 7630410302eSdanielk1977 7640410302eSdanielk1977 B step 5 7650410302eSdanielk1977} {SQLITE_BUSY} 7660410302eSdanielk1977do_test backup-7.3.2 { 7670410302eSdanielk1977 execsql { COMMIT } db3 7680410302eSdanielk1977 B step 5000 7690410302eSdanielk1977} {SQLITE_DONE} 7700410302eSdanielk1977do_test backup-7.3.3 { 7710410302eSdanielk1977 B finish 7720410302eSdanielk1977} {SQLITE_OK} 7730410302eSdanielk1977test_contents backup-7.3.4 db main db2 main 7740410302eSdanielk1977integrity_check backup-7.3.5 db2 7750410302eSdanielk1977catch { db2 close } 7760410302eSdanielk1977catch { db3 close } 7770410302eSdanielk1977 7780410302eSdanielk1977#----------------------------------------------------------------------- 7790410302eSdanielk1977# The following tests, backup-8.*, test attaching multiple backup 7800410302eSdanielk1977# processes to the same source database. Also, reading from the source 7810410302eSdanielk1977# database while a read transaction is active. 7820410302eSdanielk1977# 7830410302eSdanielk1977# These tests reuse the database "test.db" left over from backup-7.*. 7840410302eSdanielk1977# 7850410302eSdanielk1977do_test backup-8.1 { 786fda06befSmistachkin catch { forcedelete test2.db } 787fda06befSmistachkin catch { forcedelete test3.db } 7880410302eSdanielk1977 sqlite3 db2 test2.db 7890410302eSdanielk1977 sqlite3 db3 test3.db 7900410302eSdanielk1977 7910410302eSdanielk1977 sqlite3_backup B2 db2 main db main 7920410302eSdanielk1977 sqlite3_backup B3 db3 main db main 7930410302eSdanielk1977 list [B2 finish] [B3 finish] 7940410302eSdanielk1977} {SQLITE_OK SQLITE_OK} 7950410302eSdanielk1977do_test backup-8.2 { 7960410302eSdanielk1977 sqlite3_backup B3 db3 main db main 7970410302eSdanielk1977 sqlite3_backup B2 db2 main db main 7980410302eSdanielk1977 list [B2 finish] [B3 finish] 7990410302eSdanielk1977} {SQLITE_OK SQLITE_OK} 8000410302eSdanielk1977do_test backup-8.3 { 8010410302eSdanielk1977 sqlite3_backup B2 db2 main db main 8020410302eSdanielk1977 sqlite3_backup B3 db3 main db main 8030410302eSdanielk1977 B2 step 5 8040410302eSdanielk1977} {SQLITE_OK} 8050410302eSdanielk1977do_test backup-8.4 { 8060410302eSdanielk1977 execsql { 8070410302eSdanielk1977 BEGIN; 8080410302eSdanielk1977 SELECT * FROM sqlite_master; 8090410302eSdanielk1977 } 8100410302eSdanielk1977 B3 step 5 8110410302eSdanielk1977} {SQLITE_OK} 8120410302eSdanielk1977do_test backup-8.5 { 8130410302eSdanielk1977 list [B3 step 5000] [B3 finish] 8140410302eSdanielk1977} {SQLITE_DONE SQLITE_OK} 8150410302eSdanielk1977do_test backup-8.6 { 8160410302eSdanielk1977 list [B2 step 5000] [B2 finish] 8170410302eSdanielk1977} {SQLITE_DONE SQLITE_OK} 8180410302eSdanielk1977test_contents backup-8.7 db main db2 main 8190410302eSdanielk1977test_contents backup-8.8 db main db3 main 8200410302eSdanielk1977do_test backup-8.9 { 8210410302eSdanielk1977 execsql { PRAGMA lock_status } 8220410302eSdanielk1977} {main shared temp closed} 8230410302eSdanielk1977do_test backup-8.10 { 8240410302eSdanielk1977 execsql COMMIT 8250410302eSdanielk1977} {} 8260410302eSdanielk1977catch { db2 close } 8270410302eSdanielk1977catch { db3 close } 8280410302eSdanielk1977 82903ab0357Sdanielk1977#----------------------------------------------------------------------- 83003ab0357Sdanielk1977# The following tests, backup-9.*, test that: 83103ab0357Sdanielk1977# 83203ab0357Sdanielk1977# * Passing 0 as an argument to sqlite3_backup_step() means no pages 83303ab0357Sdanielk1977# are backed up (backup-9.1.*), and 83403ab0357Sdanielk1977# * Passing a negative value as an argument to sqlite3_backup_step() means 83503ab0357Sdanielk1977# all pages are backed up (backup-9.2.*). 83603ab0357Sdanielk1977# 83703ab0357Sdanielk1977# These tests reuse the database "test.db" left over from backup-7.*. 83803ab0357Sdanielk1977# 83903ab0357Sdanielk1977do_test backup-9.1.1 { 84003ab0357Sdanielk1977 sqlite3 db2 test2.db 84103ab0357Sdanielk1977 sqlite3_backup B db2 main db main 84203ab0357Sdanielk1977 B step 1 84303ab0357Sdanielk1977} {SQLITE_OK} 84403ab0357Sdanielk1977do_test backup-9.1.2 { 84503ab0357Sdanielk1977 set nRemaining [B remaining] 84603ab0357Sdanielk1977 expr {$nRemaining>100} 84703ab0357Sdanielk1977} {1} 84803ab0357Sdanielk1977do_test backup-9.1.3 { 84903ab0357Sdanielk1977 B step 0 85003ab0357Sdanielk1977} {SQLITE_OK} 85103ab0357Sdanielk1977do_test backup-9.1.4 { 85203ab0357Sdanielk1977 B remaining 85303ab0357Sdanielk1977} $nRemaining 85403ab0357Sdanielk1977 85503ab0357Sdanielk1977do_test backup-9.2.1 { 85603ab0357Sdanielk1977 B step -1 85703ab0357Sdanielk1977} {SQLITE_DONE} 85803ab0357Sdanielk1977do_test backup-9.2.2 { 85903ab0357Sdanielk1977 B remaining 86003ab0357Sdanielk1977} {0} 86103ab0357Sdanielk1977do_test backup-9.2.3 { 86203ab0357Sdanielk1977 B finish 86303ab0357Sdanielk1977} {SQLITE_OK} 86403ab0357Sdanielk1977catch {db2 close} 8650410302eSdanielk1977 866e70f4f64Sdanielk1977ifcapable memorymanage { 867e70f4f64Sdanielk1977 db close 868fda06befSmistachkin forcedelete test.db 869fda06befSmistachkin forcedelete bak.db 870e70f4f64Sdanielk1977 871e70f4f64Sdanielk1977 sqlite3 db test.db 872e70f4f64Sdanielk1977 sqlite3 db2 test.db 873e70f4f64Sdanielk1977 sqlite3 db3 bak.db 874e70f4f64Sdanielk1977 875e70f4f64Sdanielk1977 do_test backup-10.1.1 { 876e70f4f64Sdanielk1977 execsql { 877e70f4f64Sdanielk1977 BEGIN; 878e70f4f64Sdanielk1977 CREATE TABLE t1(a, b); 879e70f4f64Sdanielk1977 INSERT INTO t1 VALUES(1, randstr(1000,1000)); 880e70f4f64Sdanielk1977 INSERT INTO t1 VALUES(2, randstr(1000,1000)); 881e70f4f64Sdanielk1977 INSERT INTO t1 VALUES(3, randstr(1000,1000)); 882e70f4f64Sdanielk1977 INSERT INTO t1 VALUES(4, randstr(1000,1000)); 883e70f4f64Sdanielk1977 INSERT INTO t1 VALUES(5, randstr(1000,1000)); 884e70f4f64Sdanielk1977 CREATE INDEX i1 ON t1(a, b); 885e70f4f64Sdanielk1977 COMMIT; 886e70f4f64Sdanielk1977 } 887e70f4f64Sdanielk1977 } {} 888e70f4f64Sdanielk1977 do_test backup-10.1.2 { 889e70f4f64Sdanielk1977 sqlite3_backup B db3 main db2 main 890e70f4f64Sdanielk1977 B step 5 891e70f4f64Sdanielk1977 } {SQLITE_OK} 892e70f4f64Sdanielk1977 do_test backup-10.1.3 { 893e70f4f64Sdanielk1977 execsql { 894e70f4f64Sdanielk1977 UPDATE t1 SET b = randstr(500,500); 895e70f4f64Sdanielk1977 } 896e70f4f64Sdanielk1977 } {} 897e70f4f64Sdanielk1977 sqlite3_release_memory [expr 1024*1024] 898e70f4f64Sdanielk1977 do_test backup-10.1.3 { 899e70f4f64Sdanielk1977 B step 50 900e70f4f64Sdanielk1977 } {SQLITE_DONE} 901e70f4f64Sdanielk1977 do_test backup-10.1.4 { 902e70f4f64Sdanielk1977 B finish 903e70f4f64Sdanielk1977 } {SQLITE_OK} 904e70f4f64Sdanielk1977 do_test backup-10.1.5 { 905e70f4f64Sdanielk1977 execsql { PRAGMA integrity_check } db3 906e70f4f64Sdanielk1977 } {ok} 907e70f4f64Sdanielk1977 908e70f4f64Sdanielk1977 db2 close 909e70f4f64Sdanielk1977 db3 close 910e70f4f64Sdanielk1977} 911e70f4f64Sdanielk1977 91233d58bceSdan 9133306c4a9Sdan#----------------------------------------------------------------------- 91433d58bceSdan# Test that if the database is written to via the same database handle being 91533d58bceSdan# used as the source by a backup operation: 91633d58bceSdan# 91733d58bceSdan# 10.1.*: If the db is in-memory, the backup is restarted. 91833d58bceSdan# 10.2.*: If the db is a file, the backup is not restarted. 91933d58bceSdan# 92033d58bceSdandb close 921fda06befSmistachkinforcedelete test.db test.db-journal 92233d58bceSdanforeach {tn file rc} { 92333d58bceSdan 1 test.db SQLITE_DONE 92433d58bceSdan 2 :memory: SQLITE_OK 92533d58bceSdan} { 92633d58bceSdan do_test backup-10.$tn.1 { 92733d58bceSdan sqlite3 db $file 92833d58bceSdan execsql { 92933d58bceSdan CREATE TABLE t1(a INTEGER PRIMARY KEY, b BLOB); 93033d58bceSdan BEGIN; 93133d58bceSdan INSERT INTO t1 VALUES(NULL, randomblob(200)); 93233d58bceSdan INSERT INTO t1 SELECT NULL, randomblob(200) FROM t1; 93333d58bceSdan INSERT INTO t1 SELECT NULL, randomblob(200) FROM t1; 93433d58bceSdan INSERT INTO t1 SELECT NULL, randomblob(200) FROM t1; 93533d58bceSdan INSERT INTO t1 SELECT NULL, randomblob(200) FROM t1; 93633d58bceSdan INSERT INTO t1 SELECT NULL, randomblob(200) FROM t1; 93733d58bceSdan INSERT INTO t1 SELECT NULL, randomblob(200) FROM t1; 93833d58bceSdan INSERT INTO t1 SELECT NULL, randomblob(200) FROM t1; 93933d58bceSdan INSERT INTO t1 SELECT NULL, randomblob(200) FROM t1; 94033d58bceSdan COMMIT; 94133d58bceSdan SELECT count(*) FROM t1; 94233d58bceSdan } 94333d58bceSdan } {256} 94433d58bceSdan 94533d58bceSdan do_test backup-10.$tn.2 { 94633d58bceSdan set pgs [execsql {pragma page_count}] 94733d58bceSdan expr {$pgs > 50 && $pgs < 75} 94833d58bceSdan } {1} 94933d58bceSdan 95033d58bceSdan do_test backup-10.$tn.3 { 951fda06befSmistachkin forcedelete bak.db bak.db-journal 95233d58bceSdan sqlite3 db2 bak.db 95333d58bceSdan sqlite3_backup B db2 main db main 95433d58bceSdan B step 50 95533d58bceSdan } {SQLITE_OK} 95633d58bceSdan 95733d58bceSdan do_test backup-10.$tn.4 { 95833d58bceSdan execsql { UPDATE t1 SET b = randomblob(200) WHERE a IN (1, 250) } 95933d58bceSdan } {} 96033d58bceSdan 96133d58bceSdan do_test backup-10.$tn.5 { 96233d58bceSdan B step 50 96333d58bceSdan } $rc 96433d58bceSdan 965942179f3Sshaneh do_test backup-10.$tn.6 { 96633d58bceSdan B finish 96733d58bceSdan } {SQLITE_OK} 96833d58bceSdan 96933d58bceSdan db2 close 970942179f3Sshaneh} 971942179f3Sshaneh 972*92ecf306Sdrh# 2021-01-31 https://sqlite.org/forum/forumpost/8b39fbf3e7 973*92ecf306Sdrh# 974*92ecf306Sdrhdo_test backup-11.1 { 975*92ecf306Sdrh sqlite3 db1 :memory: 976*92ecf306Sdrh sqlite3 db2 :memory: 977*92ecf306Sdrh sqlite3_backup B db1 main db2 temp 978*92ecf306Sdrh B finish 979*92ecf306Sdrh} {SQLITE_OK} 980*92ecf306Sdrh 9810410302eSdanielk1977finish_test 982