1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
# 2016 October 31
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. The
# focus of this file is testing the SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE
# option.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/lock_common.tcl
source $testdir/malloc_common.tcl
source $testdir/wal_common.tcl
ifcapable !wal {finish_test ; return }
if {[permutation]=="journaltest" || [permutation]=="inmemory_journal"} {
finish_test
return
}
set testprefix nockpt
do_execsql_test 1.0 {
PRAGMA auto_vacuum=OFF;
PRAGMA page_size = 1024;
PRAGMA journal_mode = wal;
CREATE TABLE c1(x, y, z);
INSERT INTO c1 VALUES(1, 2, 3);
} {wal}
do_test 1.1 { file exists test.db-wal } 1
do_test 1.2 { file size test.db-wal } [wal_file_size 3 1024]
do_test 1.3 { db close } {}
do_test 1.4 { file exists test.db-wal } 0
sqlite3 db test.db
do_execsql_test 1.5 {
INSERT INTO c1 VALUES(4, 5, 6);
INSERT INTO c1 VALUES(7, 8, 9);
}
do_test 1.6 { file exists test.db-wal } 1
do_test 1.7 { sqlite3_db_config db NO_CKPT_ON_CLOSE 1 } {1}
do_test 1.8 { file size test.db-wal } [wal_file_size 2 1024]
do_test 1.9 { db close } {}
do_test 1.10 { file exists test.db-wal } 1
do_test 1.11 { file size test.db-wal } [wal_file_size 2 1024]
sqlite3 db test.db
do_execsql_test 1.12 {
SELECT * FROM c1
} {1 2 3 4 5 6 7 8 9}
do_execsql_test 1.13 { PRAGMA main.journal_mode } {wal}
do_test 1.14 { sqlite3_db_config db NO_CKPT_ON_CLOSE 1 } {1}
do_execsql_test 1.14 { PRAGMA main.journal_mode = delete } {delete}
do_test 1.15 { file exists test.db-wal } {0}
if {$::tcl_platform(platform)!="windows"} {
#-------------------------------------------------------------------------
# Test an unusual scenario:
#
# 1. A wal mode db is opened and written. Then sqlite3_close_v2() used
# to close the db handle while there is still an unfinalized
# statement (so the db handle stays open).
#
# 2. The db, wal and *-shm files are deleted from the file system.
#
# 3. Another connection creates a new wal mode db at the same file-system
# location as the previous one.
#
# 4. The statement left unfinalized in (1) is finalized.
#
# The test is to ensure that the connection left open in step (1) does
# not try to delete the wal file from the file-system as part of step
# 4.
#
reset_db
db close
# Open a connection on a wal database. Write to it a bit. Then prepare
# a statement and call sqlite3_close_v2() (so that the statement handle
# holds the db connection open).
#
set ::db1 [sqlite3_open_v2 test.db SQLITE_OPEN_READWRITE ""]
do_test 2.0 {
lindex [
sqlite3_exec $::db1 {
PRAGMA journal_mode = wal;
CREATE TABLE t1(x PRIMARY KEY, y UNIQUE, z);
INSERT INTO t1 VALUES(1, 2, 3);
PRAGMA wal_checkpoint;
}] 0
} {0}
set ::stmt [sqlite3_prepare $::db1 "SELECT * FROM t1" -1 dummy]
sqlite3_close_v2 $::db1
# Delete the database, wal and shm files.
#
forcedelete test.db test.db-wal test.db-shm
# Open and populate a new database file at the same file-system location
# as the one just deleted. Contrive a partial checkpoint on it.
#
sqlite3 db test.db
sqlite3 db2 test.db
do_execsql_test 2.1 {
PRAGMA auto_vacuum=OFF;
PRAGMA journal_mode = wal;
CREATE TABLE y1(a PRIMARY KEY, b UNIQUE, c);
INSERT INTO y1 VALUES('a', 'b', 'c');
INSERT INTO y1 VALUES('d', 'e', 'f');
} {wal}
do_execsql_test -db db2 2.2 {
BEGIN;
SELECT * FROM y1;
} {a b c d e f}
do_execsql_test 2.3 {
UPDATE y1 SET c='g' WHERE a='d';
PRAGMA wal_checkpoint;
} {0 11 10}
do_execsql_test -db db2 2.4 {
COMMIT
}
# Finalize the statement handle, causing the first connection to be
# closed. Test that this has not corrupted the database file by
# deleting the new wal file from the file-system. If it has, this
# test should fail with an IO or corruption error.
#
do_test 2.5 {
sqlite3_finalize $::stmt
sqlite3 db3 test.db
execsql {
PRAGMA integrity_check;
SELECT * FROM y1;
} db3
} {ok a b c d e g}
}
finish_test
|