Annotation of embedaddon/sqlite3/test/backup.test, revision 1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>