Annotation of embedaddon/sqlite3/test/rollback.test, revision 1.1
1.1 ! misho 1: # 2004 June 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 verifying that a rollback in one statement
! 13: # caused by an ON CONFLICT ROLLBACK clause aborts any other pending
! 14: # statements.
! 15: #
! 16: # $Id: rollback.test,v 1.11 2009/06/26 07:12:07 danielk1977 Exp $
! 17:
! 18: set testdir [file dirname $argv0]
! 19: source $testdir/tester.tcl
! 20:
! 21: set DB [sqlite3_connection_pointer db]
! 22:
! 23: do_test rollback-1.1 {
! 24: execsql {
! 25: CREATE TABLE t1(a);
! 26: INSERT INTO t1 VALUES(1);
! 27: INSERT INTO t1 VALUES(2);
! 28: INSERT INTO t1 VALUES(3);
! 29: INSERT INTO t1 VALUES(4);
! 30: SELECT * FROM t1;
! 31: }
! 32: } {1 2 3 4}
! 33:
! 34: ifcapable conflict {
! 35: do_test rollback-1.2 {
! 36: execsql {
! 37: CREATE TABLE t3(a unique on conflict rollback);
! 38: INSERT INTO t3 SELECT a FROM t1;
! 39: BEGIN;
! 40: INSERT INTO t1 SELECT * FROM t1;
! 41: }
! 42: } {}
! 43: }
! 44: do_test rollback-1.3 {
! 45: set STMT [sqlite3_prepare $DB "SELECT a FROM t1" -1 TAIL]
! 46: sqlite3_step $STMT
! 47: } {SQLITE_ROW}
! 48:
! 49: ifcapable conflict {
! 50: # This causes a ROLLBACK, which deletes the table out from underneath the
! 51: # SELECT statement.
! 52: #
! 53: do_test rollback-1.4 {
! 54: catchsql {
! 55: INSERT INTO t3 SELECT a FROM t1;
! 56: }
! 57: } {1 {column a is not unique}}
! 58:
! 59: # Try to continue with the SELECT statement
! 60: #
! 61: do_test rollback-1.5 {
! 62: sqlite3_step $STMT
! 63: } {SQLITE_ERROR}
! 64:
! 65: # Restart the SELECT statement
! 66: #
! 67: do_test rollback-1.6 { sqlite3_reset $STMT } {SQLITE_ABORT}
! 68: } else {
! 69: do_test rollback-1.6 { sqlite3_reset $STMT } {SQLITE_OK}
! 70: }
! 71:
! 72: do_test rollback-1.7 {
! 73: sqlite3_step $STMT
! 74: } {SQLITE_ROW}
! 75: do_test rollback-1.8 {
! 76: sqlite3_step $STMT
! 77: } {SQLITE_ROW}
! 78: do_test rollback-1.9 {
! 79: sqlite3_finalize $STMT
! 80: } {SQLITE_OK}
! 81:
! 82: if {$tcl_platform(platform) == "unix"
! 83: && [permutation] ne "onefile"
! 84: && [permutation] ne "inmemory_journal"
! 85: } {
! 86: do_test rollback-2.1 {
! 87: execsql {
! 88: BEGIN;
! 89: INSERT INTO t3 VALUES('hello world');
! 90: }
! 91: forcecopy test.db testA.db
! 92: forcecopy test.db-journal testA.db-journal
! 93: execsql {
! 94: COMMIT;
! 95: }
! 96: } {}
! 97:
! 98: # At this point files testA.db and testA.db-journal are present in the
! 99: # file system. This block adds a master-journal file pointer to the
! 100: # end of testA.db-journal. The master-journal file does not exist.
! 101: #
! 102: set mj [file normalize testA.db-mj-123]
! 103: binary scan $mj c* a
! 104: set cksum 0
! 105: foreach i $a { incr cksum $i }
! 106: set mj_pgno [expr $sqlite_pending_byte / 1024]
! 107: set zAppend [binary format Ia*IIa8 $mj_pgno $mj [string length $mj] $cksum \
! 108: "\xd9\xd5\x05\xf9\x20\xa1\x63\xd7"
! 109: ]
! 110: set iOffset [expr (([file size testA.db-journal] + 511)/512)*512]
! 111: set fd [open testA.db-journal a+]
! 112: fconfigure $fd -encoding binary -translation binary
! 113: seek $fd $iOffset
! 114: puts -nonewline $fd $zAppend
! 115:
! 116: # Also, fix the first journal-header in the journal-file. Because the
! 117: # journal file has not yet been synced, the 8-byte magic string at the
! 118: # start of the first journal-header has not been written by SQLite.
! 119: # So write it now.
! 120: seek $fd 0
! 121: puts -nonewline $fd "\xd9\xd5\x05\xf9\x20\xa1\x63\xd7"
! 122: close $fd
! 123:
! 124: # Open a handle on testA.db and use it to query the database. At one
! 125: # point the first query would attempt a hot rollback, attempt to open
! 126: # the master-journal file and return SQLITE_CANTOPEN when it could not
! 127: # be opened. This is incorrect, it should simply delete the journal
! 128: # file and proceed with the query.
! 129: #
! 130: do_test rollback-2.2 {
! 131: sqlite3 db2 testA.db
! 132: execsql {
! 133: SELECT distinct tbl_name FROM sqlite_master;
! 134: } db2
! 135: } {t1 t3}
! 136: if {[lsearch {exclusive persistent_journal no_journal} [permutation]]<0} {
! 137: do_test rollback-2.3 {
! 138: file exists testA.db-journal
! 139: } 0
! 140: }
! 141: do_test rollback-2.4 {
! 142: execsql {
! 143: SELECT distinct tbl_name FROM sqlite_master;
! 144: } db2
! 145: } {t1 t3}
! 146:
! 147: db2 close
! 148: }
! 149:
! 150: finish_test
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>