-C Add\stests\sfor\s"PRAGMA\scheckpoint_fullfsync".
-D 2010-11-19T18:48:10
+C Add\sextra\stests\sfor\stest_superlock.c.
+D 2010-11-20T10:57:45
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in e7a59672eaeb04408d1fa8501618d7501a3c5e39
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F test/subquery.test b524f57c9574b2c0347045b4510ef795d4686796
F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4
F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
-F test/superlock.test f9241e8738fe8d05655fd096e4c8a88ee22d8990
+F test/superlock.test 070e7fd9ccf91755b6f8e03ede27995a73220672
F test/sync.test ded6b39d8d8ca3c0c5518516c6371b3316d3e3a3
F test/table.test 04ba066432430657712d167ebf28080fe878d305
F test/tableapi.test 7262a8cbaa9965d429f1cbd2747edc185fa56516
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 570e79a8eb3bb2d2a15c46c55fbf52c9dd3e3ae8
-R a950411020f2e9a3c9e01441aa43e538
+P 765aa1b862fa38cede89bafe0e10c094e0544b7e
+R 27d92142897c9c2c878d22b56828d49b
U dan
-Z 40fbbee993478998a34279e6b6efa9ec
+Z 81c82ffdb9a719f67547d604c72658bc
set testprefix superlock
+# Test organization:
+#
+# 1.*: Test superlock on a rollback database. Test that once the db is
+# superlocked, it is not possible for a second client to read from
+# it.
+#
+# 2.*: Test superlock on a WAL database with zero frames in the WAL file.
+# Test that once the db is superlocked, it is not possible to read,
+# write or checkpoint the db.
+#
+# 3.*: As 2.*, for WAL databases with one or more frames in the WAL.
+#
+# 4.*: As 2.*, for WAL databases with one or more checkpointed frames
+# in the WAL.
+#
+# 5.*: Test that a call to sqlite3demo_superlock() uses the busy handler
+# correctly to wait for existing clients to clear on a WAL database.
+# And returns SQLITE_BUSY if no busy handler is defined or the busy
+# handler returns 0 before said clients relinquish their locks.
+#
+# 6.*: Test that if a superlocked WAL database is overwritten, existing
+# clients run the recovery to build the new wal-index after the
+# superlock is released.
+#
+#
+
do_execsql_test 1.1 {
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES(1, 2);
do_test 4.6 { unlock } {}
do_multiclient_test tn {
+
proc busyhandler {x} {
switch -- $x {
1 { sql1 "COMMIT" }
do_test 5.$tn.6 { csql1 "PRAGMA wal_checkpoint" } {1 {database is locked}}
do_test 5.$tn.7 { unlock } {}
+
+
+ do_test 5.$tn.8 {
+ sql1 { BEGIN ; SELECT * FROM t1 }
+ sql2 { BEGIN ; INSERT INTO t1 VALUES(5, 6) }
+ sql3 { BEGIN ; SELECT * FROM t1 }
+ } {1 2 3 4}
+
+ do_test 5.$tn.9 {
+ list [catch {sqlite3demo_superlock unlock test.db} msg] $msg
+ } {1 {database is locked}}
+ do_test 5.$tn.10 {
+ sql1 COMMIT
+ list [catch {sqlite3demo_superlock unlock test.db} msg] $msg
+ } {1 {database is locked}}
+ do_test 5.$tn.11 {
+ sql2 COMMIT
+ list [catch {sqlite3demo_superlock unlock test.db} msg] $msg
+ } {1 {database is locked}}
+ do_test 5.$tn.12 {
+ sql3 COMMIT
+ list [catch {sqlite3demo_superlock unlock test.db} msg] $msg
+ } {0 unlock}
+ unlock
+}
+
+proc read_content {file} {
+ if {[file exists $file]==0} {return ""}
+ set fd [open $file]
+ fconfigure $fd -encoding binary -translation binary
+ set content [read $fd]
+ close $fd
+ return $content
}
+proc write_content {file content} {
+ set fd [open $file w+]
+ fconfigure $fd -encoding binary -translation binary
+ puts -nonewline $fd $content
+ close $fd
+}
+
+# Both $file1 and $file2 are database files. This function takes a
+# superlock on each, then exchanges the content of the two files (i.e.
+# overwrites $file1 with the initial contents of $file2, and overwrites
+# $file2 with the initial contents of $file1). The contents of any WAL
+# file is also exchanged.
+#
+proc db_swap {file1 file2} {
+ sqlite3demo_superlock unlock1 $file1
+ sqlite3demo_superlock unlock2 $file2
+
+ set db1 [read_content $file1]
+ set db2 [read_content $file2]
+ write_content $file1 $db2
+ write_content $file2 $db1
+
+ set wal1 [read_content ${file1}-wal]
+ set wal2 [read_content ${file2}-wal]
+ write_content ${file1}-wal $wal2
+ write_content ${file2}-wal $wal1
+
+ unlock1
+ unlock2
+}
+
+forcedelete test.db
+sqlite3 db test.db
+do_execsql_test 6.1 {
+ ATTACH 'test.db2' AS aux;
+ PRAGMA aux.journal_mode = wal;
+ CREATE TABLE aux.t2(x, y);
+ INSERT INTO aux.t2 VALUES('a', 'b');
+ PRAGMA schema_version = 450;
+ DETACH aux;
+
+ PRAGMA main.journal_mode = wal;
+ CREATE TABLE t1(a, b);
+ INSERT INTO t1 VALUES(1, 2);
+ INSERT INTO t1 VALUES(3, 4);
+ SELECT * FROM t1;
+} {wal wal 1 2 3 4}
+
+
+db_swap test.db2 test.db
+do_catchsql_test 6.2 { SELECT * FROM t1 } {1 {no such table: t1}}
+do_catchsql_test 6.3 { SELECT * FROM t2 } {0 {a b}}
+
+db_swap test.db2 test.db
+do_catchsql_test 6.4 { SELECT * FROM t1 } {0 {1 2 3 4}}
+do_catchsql_test 6.5 { SELECT * FROM t2 } {1 {no such table: t2}}
+
+do_execsql_test 6.6 { PRAGMA wal_checkpoint }
+
+db_swap test.db2 test.db
+do_catchsql_test 6.7 { SELECT * FROM t1 } {1 {no such table: t1}}
+do_catchsql_test 6.8 { SELECT * FROM t2 } {0 {a b}}
+
+db_swap test.db2 test.db
+do_catchsql_test 6.9 { SELECT * FROM t1 } {0 {1 2 3 4}}
+do_catchsql_test 6.10 { SELECT * FROM t2 } {1 {no such table: t2}}
+
+do_execsql_test 6.11 {
+ PRAGMA journal_mode = delete;
+ PRAGMA page_size = 512;
+ VACUUM;
+ PRAGMA journal_mode = wal;
+ INSERT INTO t1 VALUES(5, 6);
+} {delete wal}
+
+db_swap test.db2 test.db
+do_catchsql_test 6.12 { SELECT * FROM t1 } {1 {no such table: t1}}
+do_catchsql_test 6.13 { SELECT * FROM t2 } {0 {a b}}
+
+db_swap test.db2 test.db
+do_catchsql_test 6.14 { SELECT * FROM t1 } {0 {1 2 3 4 5 6}}
+do_catchsql_test 6.15 { SELECT * FROM t2 } {1 {no such table: t2}}
finish_test