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