Enhance existing snapshot tests to serialize/deserialize snapshots. No new
tests. FossilOrigin-Name: 16b9bf92741e4c62874cffd7c6a61763c5054c7a
This commit is contained in:
parent
ba6eb8769f
commit
25accbca72
19
manifest
19
manifest
@ -1,5 +1,5 @@
|
||||
C Experimental\schanges\stoward\smaking\ssnapshots\sserializable.
|
||||
D 2016-11-15T17:37:56.374
|
||||
C Enhance\sexisting\ssnapshot\stests\sto\sserialize/deserialize\ssnapshots.\sNo\snew\ntests.
|
||||
D 2016-11-18T14:38:41.852
|
||||
F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4
|
||||
@ -397,7 +397,7 @@ F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247
|
||||
F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1
|
||||
F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9
|
||||
F src/tclsqlite.c aef87dcd8cb66564d560ab48d43d19ac812a1eab
|
||||
F src/test1.c f52bed152c97be23be794efa234374d0de593eeb
|
||||
F src/test1.c 58de30ed902f78531cf5cf52b883a26d107208c4
|
||||
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
|
||||
F src/test3.c d03f5b5da9a2410b7a91c64b0d3306ed28ab6fee
|
||||
F src/test4.c 18ec393bb4d0ad1de729f0b94da7267270f3d8e6
|
||||
@ -1102,7 +1102,7 @@ F test/skipscan2.test d1d1450952b7275f0b0a3a981f0230532743951a
|
||||
F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5
|
||||
F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2
|
||||
F test/skipscan6.test 5866039d03a56f5bd0b3d172a012074a1d90a15b
|
||||
F test/snapshot.test a19465046168b4420b5afeed37c3214e42a49f4a
|
||||
F test/snapshot.test bb34cc38828bf2e86a49207995fa7dfacd303832
|
||||
F test/snapshot_fault.test 062ff0438a074978d45e9f9a92e7ad459b74ee73
|
||||
F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f
|
||||
F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087
|
||||
@ -1534,10 +1534,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 663473850c4274270445b3771911fa773a8c405f
|
||||
R 1784ed6bcadef61e22ad39533122ebea
|
||||
T *branch * serializable-snapshot
|
||||
T *sym-serializable-snapshot *
|
||||
T -sym-trunk *
|
||||
U drh
|
||||
Z 8a16f1f47c269929c7f968ee35b8cb55
|
||||
P b6a81fa1fc1fb78a65894129851a4ec3986640de
|
||||
R 17ac6d49deba8d40db4fa5f6ce7fc2ca
|
||||
U dan
|
||||
Z cee5f11eb9093786088be3369dcd2153
|
||||
|
@ -1 +1 @@
|
||||
b6a81fa1fc1fb78a65894129851a4ec3986640de
|
||||
16b9bf92741e4c62874cffd7c6a61763c5054c7a
|
110
src/test1.c
110
src/test1.c
@ -2388,6 +2388,113 @@ static int SQLITE_TCLAPI test_snapshot_cmp(
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_SNAPSHOT */
|
||||
|
||||
#ifdef SQLITE_ENABLE_SNAPSHOT
|
||||
/*
|
||||
** Usage: sqlite3_snapshot_get_blob DB DBNAME
|
||||
*/
|
||||
static int SQLITE_TCLAPI test_snapshot_get_blob(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
int rc;
|
||||
sqlite3 *db;
|
||||
char *zName;
|
||||
sqlite3_snapshot *pSnapshot = 0;
|
||||
|
||||
if( objc!=3 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
|
||||
zName = Tcl_GetString(objv[2]);
|
||||
|
||||
rc = sqlite3_snapshot_get(db, zName, &pSnapshot);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
|
||||
return TCL_ERROR;
|
||||
}else{
|
||||
Tcl_SetObjResult(interp,
|
||||
Tcl_NewByteArrayObj((unsigned char*)pSnapshot, sizeof(sqlite3_snapshot))
|
||||
);
|
||||
sqlite3_snapshot_free(pSnapshot);
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_SNAPSHOT */
|
||||
|
||||
#ifdef SQLITE_ENABLE_SNAPSHOT
|
||||
/*
|
||||
** Usage: sqlite3_snapshot_open_blob DB DBNAME SNAPSHOT
|
||||
*/
|
||||
static int SQLITE_TCLAPI test_snapshot_open_blob(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
int rc;
|
||||
sqlite3 *db;
|
||||
char *zName;
|
||||
unsigned char *pBlob;
|
||||
int nBlob;
|
||||
|
||||
if( objc!=4 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME SNAPSHOT");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
|
||||
zName = Tcl_GetString(objv[2]);
|
||||
pBlob = Tcl_GetByteArrayFromObj(objv[3], &nBlob);
|
||||
if( nBlob!=sizeof(sqlite3_snapshot) ){
|
||||
Tcl_AppendResult(interp, "bad SNAPSHOT", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
rc = sqlite3_snapshot_open(db, zName, (sqlite3_snapshot*)pBlob);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_SNAPSHOT */
|
||||
|
||||
#ifdef SQLITE_ENABLE_SNAPSHOT
|
||||
/*
|
||||
** Usage: sqlite3_snapshot_cmp_blob SNAPSHOT1 SNAPSHOT2
|
||||
*/
|
||||
static int SQLITE_TCLAPI test_snapshot_cmp_blob(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
int res;
|
||||
unsigned char *p1;
|
||||
unsigned char *p2;
|
||||
int n1;
|
||||
int n2;
|
||||
|
||||
if( objc!=3 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "SNAPSHOT1 SNAPSHOT2");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
p1 = Tcl_GetByteArrayFromObj(objv[1], &n1);
|
||||
p2 = Tcl_GetByteArrayFromObj(objv[2], &n2);
|
||||
|
||||
if( n1!=sizeof(sqlite3_snapshot) || n1!=n2 ){
|
||||
Tcl_AppendResult(interp, "bad SNAPSHOT", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
res = sqlite3_snapshot_cmp((sqlite3_snapshot*)p1, (sqlite3_snapshot*)p2);
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(res));
|
||||
return TCL_OK;
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_SNAPSHOT */
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_delete_database FILENAME
|
||||
*/
|
||||
@ -7539,6 +7646,9 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
{ "sqlite3_snapshot_open", test_snapshot_open, 0 },
|
||||
{ "sqlite3_snapshot_free", test_snapshot_free, 0 },
|
||||
{ "sqlite3_snapshot_cmp", test_snapshot_cmp, 0 },
|
||||
{ "sqlite3_snapshot_get_blob", test_snapshot_get_blob, 0 },
|
||||
{ "sqlite3_snapshot_open_blob", test_snapshot_open_blob, 0 },
|
||||
{ "sqlite3_snapshot_cmp_blob", test_snapshot_cmp_blob, 0 },
|
||||
#endif
|
||||
{ "sqlite3_delete_database", test_delete_database, 0 },
|
||||
};
|
||||
|
@ -26,413 +26,448 @@ if {[permutation]=="inmemory_journal"} {
|
||||
return
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Check some error conditions in snapshot_get(). It is an error if:
|
||||
#
|
||||
# 1) snapshot_get() is called on a non-WAL database, or
|
||||
# 2) there is an open write transaction on the database.
|
||||
#
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a, b);
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
INSERT INTO t1 VALUES(3, 4);
|
||||
}
|
||||
|
||||
do_test 1.1.1 {
|
||||
execsql { BEGIN; SELECT * FROM t1; }
|
||||
list [catch { sqlite3_snapshot_get db main } msg] $msg
|
||||
} {1 SQLITE_ERROR}
|
||||
do_execsql_test 1.1.2 COMMIT
|
||||
|
||||
do_test 1.2.1 {
|
||||
execsql {
|
||||
PRAGMA journal_mode = WAL;
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES(5, 6);
|
||||
INSERT INTO t1 VALUES(7, 8);
|
||||
foreach {tn tcl} {
|
||||
1 {
|
||||
proc snapshot_get {DB DBNAME} {
|
||||
uplevel [list sqlite3_snapshot_get $DB $DBNAME]
|
||||
}
|
||||
proc snapshot_open {DB DBNAME SNAPSHOT} {
|
||||
uplevel [list sqlite3_snapshot_open $DB $DBNAME $SNAPSHOT]
|
||||
}
|
||||
proc snapshot_free {SNAPSHOT} {
|
||||
uplevel [list sqlite3_snapshot_free $SNAPSHOT]
|
||||
}
|
||||
proc snapshot_cmp {SNAPSHOT1 SNAPSHOT2} {
|
||||
uplevel [list sqlite3_snapshot_cmp $SNAPSHOT1 $SNAPSHOT2]
|
||||
}
|
||||
}
|
||||
list [catch { sqlite3_snapshot_get db main } msg] $msg
|
||||
} {1 SQLITE_ERROR}
|
||||
do_execsql_test 1.3.2 COMMIT
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Check that a simple case works. Reuse the database created by the
|
||||
# block of tests above.
|
||||
#
|
||||
do_execsql_test 2.1.0 {
|
||||
BEGIN;
|
||||
SELECT * FROM t1;
|
||||
} {1 2 3 4 5 6 7 8}
|
||||
|
||||
do_test 2.1.1 {
|
||||
set snapshot [sqlite3_snapshot_get db main]
|
||||
execsql {
|
||||
COMMIT;
|
||||
INSERT INTO t1 VALUES(9, 10);
|
||||
SELECT * FROM t1;
|
||||
2 {
|
||||
proc snapshot_get {DB DBNAME} {
|
||||
uplevel [list sqlite3_snapshot_get_blob $DB $DBNAME]
|
||||
}
|
||||
proc snapshot_open {DB DBNAME SNAPSHOT} {
|
||||
uplevel [list sqlite3_snapshot_open_blob $DB $DBNAME $SNAPSHOT]
|
||||
}
|
||||
proc snapshot_free {SNAPSHOT} {
|
||||
}
|
||||
proc snapshot_cmp {SNAPSHOT1 SNAPSHOT2} {
|
||||
uplevel [list sqlite3_snapshot_cmp_blob $SNAPSHOT1 $SNAPSHOT2]
|
||||
}
|
||||
}
|
||||
} {1 2 3 4 5 6 7 8 9 10}
|
||||
} {
|
||||
|
||||
do_test 2.1.2 {
|
||||
execsql BEGIN
|
||||
sqlite3_snapshot_open db main $snapshot
|
||||
execsql {
|
||||
SELECT * FROM t1;
|
||||
reset_db
|
||||
eval $tcl
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Check some error conditions in snapshot_get(). It is an error if:
|
||||
#
|
||||
# 1) snapshot_get() is called on a non-WAL database, or
|
||||
# 2) there is an open write transaction on the database.
|
||||
#
|
||||
do_execsql_test $tn.1.0 {
|
||||
CREATE TABLE t1(a, b);
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
INSERT INTO t1 VALUES(3, 4);
|
||||
}
|
||||
} {1 2 3 4 5 6 7 8}
|
||||
|
||||
do_test 2.1.3 {
|
||||
sqlite3_snapshot_free $snapshot
|
||||
execsql COMMIT
|
||||
} {}
|
||||
do_test $tn.1.1.1 {
|
||||
execsql { BEGIN; SELECT * FROM t1; }
|
||||
list [catch { snapshot_get db main } msg] $msg
|
||||
} {1 SQLITE_ERROR}
|
||||
do_execsql_test 1.1.2 COMMIT
|
||||
|
||||
do_test 2.2.0 {
|
||||
sqlite3 db2 test.db
|
||||
execsql {
|
||||
do_test $tn.1.2.1 {
|
||||
execsql {
|
||||
PRAGMA journal_mode = WAL;
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES(5, 6);
|
||||
INSERT INTO t1 VALUES(7, 8);
|
||||
}
|
||||
list [catch { snapshot_get db main } msg] $msg
|
||||
} {1 SQLITE_ERROR}
|
||||
do_execsql_test $tn.1.3.2 COMMIT
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Check that a simple case works. Reuse the database created by the
|
||||
# block of tests above.
|
||||
#
|
||||
do_execsql_test $tn.2.1.0 {
|
||||
BEGIN;
|
||||
SELECT * FROM t1;
|
||||
} db2
|
||||
} {1 2 3 4 5 6 7 8 9 10}
|
||||
} {1 2 3 4 5 6 7 8}
|
||||
|
||||
do_test 2.2.1 {
|
||||
set snapshot [sqlite3_snapshot_get db2 main]
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(11, 12);
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {1 2 3 4 5 6 7 8 9 10 11 12}
|
||||
do_test $tn.2.1.1 {
|
||||
set snapshot [snapshot_get db main]
|
||||
execsql {
|
||||
COMMIT;
|
||||
INSERT INTO t1 VALUES(9, 10);
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {1 2 3 4 5 6 7 8 9 10}
|
||||
|
||||
do_test 2.2.2 {
|
||||
execsql BEGIN
|
||||
sqlite3_snapshot_open db main $snapshot
|
||||
execsql {
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {1 2 3 4 5 6 7 8 9 10}
|
||||
do_test $tn.2.1.2 {
|
||||
execsql BEGIN
|
||||
snapshot_open db main $snapshot
|
||||
execsql {
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {1 2 3 4 5 6 7 8}
|
||||
|
||||
do_test 2.2.3 {
|
||||
sqlite3_snapshot_free $snapshot
|
||||
execsql COMMIT
|
||||
execsql COMMIT db2
|
||||
db2 close
|
||||
} {}
|
||||
do_test $tn.2.1.3 {
|
||||
snapshot_free $snapshot
|
||||
execsql COMMIT
|
||||
} {}
|
||||
|
||||
do_test 2.3.1 {
|
||||
execsql { DELETE FROM t1 WHERE a>6 }
|
||||
set snapshot [sqlite3_snapshot_get db main]
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES('a', 'b');
|
||||
INSERT INTO t1 VALUES('c', 'd');
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {1 2 3 4 5 6 a b c d}
|
||||
do_test 2.3.2 {
|
||||
execsql BEGIN
|
||||
sqlite3_snapshot_open db main $snapshot
|
||||
execsql { SELECT * FROM t1 }
|
||||
} {1 2 3 4 5 6}
|
||||
do_test $tn.2.2.0 {
|
||||
sqlite3 db2 test.db
|
||||
execsql {
|
||||
BEGIN;
|
||||
SELECT * FROM t1;
|
||||
} db2
|
||||
} {1 2 3 4 5 6 7 8 9 10}
|
||||
|
||||
do_test 2.3.3 {
|
||||
catchsql {
|
||||
INSERT INTO t1 VALUES('x','y')
|
||||
}
|
||||
} {1 {database is locked}}
|
||||
do_test 2.3.4 {
|
||||
execsql COMMIT
|
||||
sqlite3_snapshot_free $snapshot
|
||||
} {}
|
||||
do_test $tn.2.2.1 {
|
||||
set snapshot [snapshot_get db2 main]
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(11, 12);
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {1 2 3 4 5 6 7 8 9 10 11 12}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Check some errors in sqlite3_snapshot_open(). It is an error if:
|
||||
#
|
||||
# 1) the db is in auto-commit mode,
|
||||
# 2) the db has an open (read or write) transaction,
|
||||
# 3) the db is not a wal database,
|
||||
#
|
||||
# Reuse the database created by earlier tests.
|
||||
#
|
||||
do_execsql_test 3.0.0 {
|
||||
CREATE TABLE t2(x, y);
|
||||
INSERT INTO t2 VALUES('a', 'b');
|
||||
INSERT INTO t2 VALUES('c', 'd');
|
||||
BEGIN;
|
||||
SELECT * FROM t2;
|
||||
} {a b c d}
|
||||
do_test 3.0.1 {
|
||||
set snapshot [sqlite3_snapshot_get db main]
|
||||
execsql { COMMIT }
|
||||
execsql { INSERT INTO t2 VALUES('e', 'f'); }
|
||||
} {}
|
||||
do_test $tn.2.2.2 {
|
||||
execsql BEGIN
|
||||
snapshot_open db main $snapshot
|
||||
execsql {
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {1 2 3 4 5 6 7 8 9 10}
|
||||
|
||||
do_test 3.1 {
|
||||
list [catch {sqlite3_snapshot_open db main $snapshot } msg] $msg
|
||||
} {1 SQLITE_ERROR}
|
||||
do_test $tn.2.2.3 {
|
||||
snapshot_free $snapshot
|
||||
execsql COMMIT
|
||||
execsql COMMIT db2
|
||||
db2 close
|
||||
} {}
|
||||
|
||||
do_test 3.2.1 {
|
||||
execsql {
|
||||
do_test $tn.2.3.1 {
|
||||
execsql { DELETE FROM t1 WHERE a>6 }
|
||||
set snapshot [snapshot_get db main]
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES('a', 'b');
|
||||
INSERT INTO t1 VALUES('c', 'd');
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {1 2 3 4 5 6 a b c d}
|
||||
do_test $tn.2.3.2 {
|
||||
execsql BEGIN
|
||||
snapshot_open db main $snapshot
|
||||
execsql { SELECT * FROM t1 }
|
||||
} {1 2 3 4 5 6}
|
||||
|
||||
do_test $tn.2.3.3 {
|
||||
catchsql {
|
||||
INSERT INTO t1 VALUES('x','y')
|
||||
}
|
||||
} {1 {database is locked}}
|
||||
do_test $tn.2.3.4 {
|
||||
execsql COMMIT
|
||||
snapshot_free $snapshot
|
||||
} {}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Check some errors in snapshot_open(). It is an error if:
|
||||
#
|
||||
# 1) the db is in auto-commit mode,
|
||||
# 2) the db has an open (read or write) transaction,
|
||||
# 3) the db is not a wal database,
|
||||
#
|
||||
# Reuse the database created by earlier tests.
|
||||
#
|
||||
do_execsql_test $tn.3.0.0 {
|
||||
CREATE TABLE t2(x, y);
|
||||
INSERT INTO t2 VALUES('a', 'b');
|
||||
INSERT INTO t2 VALUES('c', 'd');
|
||||
BEGIN;
|
||||
SELECT * FROM t2;
|
||||
}
|
||||
} {a b c d e f}
|
||||
do_test 3.2.2 {
|
||||
list [catch {sqlite3_snapshot_open db main $snapshot } msg] $msg
|
||||
} {1 SQLITE_ERROR}
|
||||
} {a b c d}
|
||||
do_test $tn.3.0.1 {
|
||||
set snapshot [snapshot_get db main]
|
||||
execsql { COMMIT }
|
||||
execsql { INSERT INTO t2 VALUES('e', 'f'); }
|
||||
} {}
|
||||
|
||||
do_test 3.2.3 {
|
||||
execsql {
|
||||
COMMIT;
|
||||
BEGIN;
|
||||
INSERT INTO t2 VALUES('g', 'h');
|
||||
}
|
||||
list [catch {sqlite3_snapshot_open db main $snapshot } msg] $msg
|
||||
} {1 SQLITE_ERROR}
|
||||
do_execsql_test 3.2.4 COMMIT
|
||||
do_test $tn.3.1 {
|
||||
list [catch {snapshot_open db main $snapshot } msg] $msg
|
||||
} {1 SQLITE_ERROR}
|
||||
|
||||
do_test 3.3.1 {
|
||||
execsql { PRAGMA journal_mode = DELETE }
|
||||
execsql { BEGIN }
|
||||
list [catch {sqlite3_snapshot_open db main $snapshot } msg] $msg
|
||||
} {1 SQLITE_ERROR}
|
||||
do_test $tn.3.2.1 {
|
||||
execsql {
|
||||
BEGIN;
|
||||
SELECT * FROM t2;
|
||||
}
|
||||
} {a b c d e f}
|
||||
do_test $tn.3.2.2 {
|
||||
list [catch {snapshot_open db main $snapshot } msg] $msg
|
||||
} {1 SQLITE_ERROR}
|
||||
|
||||
do_test 3.3.2 {
|
||||
sqlite3_snapshot_free $snapshot
|
||||
execsql COMMIT
|
||||
} {}
|
||||
do_test $tn.3.2.3 {
|
||||
execsql {
|
||||
COMMIT;
|
||||
BEGIN;
|
||||
INSERT INTO t2 VALUES('g', 'h');
|
||||
}
|
||||
list [catch {snapshot_open db main $snapshot } msg] $msg
|
||||
} {1 SQLITE_ERROR}
|
||||
do_execsql_test 3.2.4 COMMIT
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Check that SQLITE_BUSY_SNAPSHOT is returned if the specified snapshot
|
||||
# no longer exists because the wal file has been checkpointed.
|
||||
#
|
||||
# 1. Reading a snapshot from the middle of a wal file is not possible
|
||||
# after the wal file has been checkpointed.
|
||||
#
|
||||
# 2. That a snapshot from the end of a wal file can not be read once
|
||||
# the wal file has been wrapped.
|
||||
#
|
||||
do_execsql_test 4.1.0 {
|
||||
PRAGMA journal_mode = wal;
|
||||
CREATE TABLE t3(i, j);
|
||||
INSERT INTO t3 VALUES('o', 't');
|
||||
INSERT INTO t3 VALUES('t', 'f');
|
||||
BEGIN;
|
||||
SELECT * FROM t3;
|
||||
} {wal o t t f}
|
||||
do_test $tn.3.3.1 {
|
||||
execsql { PRAGMA journal_mode = DELETE }
|
||||
execsql { BEGIN }
|
||||
list [catch {snapshot_open db main $snapshot } msg] $msg
|
||||
} {1 SQLITE_ERROR}
|
||||
|
||||
do_test 4.1.1 {
|
||||
set snapshot [sqlite3_snapshot_get db main]
|
||||
execsql COMMIT
|
||||
} {}
|
||||
do_test 4.1.2 {
|
||||
execsql {
|
||||
INSERT INTO t3 VALUES('f', 's');
|
||||
BEGIN;
|
||||
}
|
||||
sqlite3_snapshot_open db main $snapshot
|
||||
execsql { SELECT * FROM t3 }
|
||||
} {o t t f}
|
||||
do_test $tn.$tn.3.3.2 {
|
||||
snapshot_free $snapshot
|
||||
execsql COMMIT
|
||||
} {}
|
||||
|
||||
do_test 4.1.3 {
|
||||
execsql {
|
||||
COMMIT;
|
||||
PRAGMA wal_checkpoint;
|
||||
BEGIN;
|
||||
}
|
||||
list [catch {sqlite3_snapshot_open db main $snapshot} msg] $msg
|
||||
} {1 SQLITE_BUSY_SNAPSHOT}
|
||||
do_test 4.1.4 {
|
||||
sqlite3_snapshot_free $snapshot
|
||||
execsql COMMIT
|
||||
} {}
|
||||
|
||||
do_test 4.2.1 {
|
||||
execsql {
|
||||
INSERT INTO t3 VALUES('s', 'e');
|
||||
INSERT INTO t3 VALUES('n', 't');
|
||||
#-------------------------------------------------------------------------
|
||||
# Check that SQLITE_BUSY_SNAPSHOT is returned if the specified snapshot
|
||||
# no longer exists because the wal file has been checkpointed.
|
||||
#
|
||||
# 1. Reading a snapshot from the middle of a wal file is not possible
|
||||
# after the wal file has been checkpointed.
|
||||
#
|
||||
# 2. That a snapshot from the end of a wal file can not be read once
|
||||
# the wal file has been wrapped.
|
||||
#
|
||||
do_execsql_test $tn.4.1.0 {
|
||||
PRAGMA journal_mode = wal;
|
||||
CREATE TABLE t3(i, j);
|
||||
INSERT INTO t3 VALUES('o', 't');
|
||||
INSERT INTO t3 VALUES('t', 'f');
|
||||
BEGIN;
|
||||
SELECT * FROM t3;
|
||||
}
|
||||
} {o t t f f s s e n t}
|
||||
do_test 4.2.2 {
|
||||
set snapshot [sqlite3_snapshot_get db main]
|
||||
execsql {
|
||||
COMMIT;
|
||||
PRAGMA wal_checkpoint;
|
||||
} {wal o t t f}
|
||||
|
||||
do_test $tn.4.1.1 {
|
||||
set snapshot [snapshot_get db main]
|
||||
execsql COMMIT
|
||||
} {}
|
||||
do_test $tn.4.1.2 {
|
||||
execsql {
|
||||
INSERT INTO t3 VALUES('f', 's');
|
||||
BEGIN;
|
||||
}
|
||||
snapshot_open db main $snapshot
|
||||
execsql { SELECT * FROM t3 }
|
||||
} {o t t f}
|
||||
|
||||
do_test $tn.4.1.3 {
|
||||
execsql {
|
||||
COMMIT;
|
||||
PRAGMA wal_checkpoint;
|
||||
BEGIN;
|
||||
}
|
||||
list [catch {snapshot_open db main $snapshot} msg] $msg
|
||||
} {1 SQLITE_BUSY_SNAPSHOT}
|
||||
do_test $tn.4.1.4 {
|
||||
snapshot_free $snapshot
|
||||
execsql COMMIT
|
||||
} {}
|
||||
|
||||
do_test $tn.4.2.1 {
|
||||
execsql {
|
||||
INSERT INTO t3 VALUES('s', 'e');
|
||||
INSERT INTO t3 VALUES('n', 't');
|
||||
BEGIN;
|
||||
SELECT * FROM t3;
|
||||
}
|
||||
} {o t t f f s s e n t}
|
||||
do_test $tn.4.2.2 {
|
||||
set snapshot [snapshot_get db main]
|
||||
execsql {
|
||||
COMMIT;
|
||||
PRAGMA wal_checkpoint;
|
||||
BEGIN;
|
||||
}
|
||||
snapshot_open db main $snapshot
|
||||
execsql { SELECT * FROM t3 }
|
||||
} {o t t f f s s e n t}
|
||||
do_test $tn.4.2.3 {
|
||||
execsql {
|
||||
COMMIT;
|
||||
INSERT INTO t3 VALUES('e', 't');
|
||||
BEGIN;
|
||||
}
|
||||
list [catch {snapshot_open db main $snapshot} msg] $msg
|
||||
} {1 SQLITE_BUSY_SNAPSHOT}
|
||||
do_test $tn.4.2.4 {
|
||||
snapshot_free $snapshot
|
||||
} {}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Check that SQLITE_BUSY is returned if a checkpoint is running when
|
||||
# sqlite3_snapshot_open() is called.
|
||||
#
|
||||
reset_db
|
||||
db close
|
||||
testvfs tvfs
|
||||
sqlite3 db test.db -vfs tvfs
|
||||
|
||||
do_execsql_test $tn.5.1 {
|
||||
PRAGMA journal_mode = wal;
|
||||
CREATE TABLE x1(x, xx, xxx);
|
||||
INSERT INTO x1 VALUES('z', 'zz', 'zzz');
|
||||
BEGIN;
|
||||
SELECT * FROM x1;
|
||||
} {wal z zz zzz}
|
||||
|
||||
do_test $tn.5.2 {
|
||||
set ::snapshot [snapshot_get db main]
|
||||
sqlite3 db2 test.db -vfs tvfs
|
||||
execsql {
|
||||
INSERT INTO x1 VALUES('a', 'aa', 'aaa');
|
||||
COMMIT;
|
||||
}
|
||||
} {}
|
||||
|
||||
set t53 0
|
||||
proc write_callback {args} {
|
||||
do_test $tn.5.3.[incr ::t53] {
|
||||
execsql BEGIN
|
||||
list [catch { snapshot_open db main $::snapshot } msg] $msg
|
||||
} {1 SQLITE_BUSY}
|
||||
catchsql COMMIT
|
||||
}
|
||||
sqlite3_snapshot_open db main $snapshot
|
||||
execsql { SELECT * FROM t3 }
|
||||
} {o t t f f s s e n t}
|
||||
do_test 4.2.3 {
|
||||
execsql {
|
||||
COMMIT;
|
||||
INSERT INTO t3 VALUES('e', 't');
|
||||
BEGIN;
|
||||
}
|
||||
list [catch {sqlite3_snapshot_open db main $snapshot} msg] $msg
|
||||
} {1 SQLITE_BUSY_SNAPSHOT}
|
||||
do_test 4.2.4 {
|
||||
sqlite3_snapshot_free $snapshot
|
||||
} {}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Check that SQLITE_BUSY is returned if a checkpoint is running when
|
||||
# sqlite3_snapshot_open() is called.
|
||||
#
|
||||
reset_db
|
||||
db close
|
||||
testvfs tvfs
|
||||
sqlite3 db test.db -vfs tvfs
|
||||
|
||||
do_execsql_test 5.1 {
|
||||
PRAGMA journal_mode = wal;
|
||||
CREATE TABLE x1(x, xx, xxx);
|
||||
INSERT INTO x1 VALUES('z', 'zz', 'zzz');
|
||||
BEGIN;
|
||||
SELECT * FROM x1;
|
||||
} {wal z zz zzz}
|
||||
|
||||
do_test 5.2 {
|
||||
set ::snapshot [sqlite3_snapshot_get db main]
|
||||
sqlite3 db2 test.db -vfs tvfs
|
||||
execsql {
|
||||
INSERT INTO x1 VALUES('a', 'aa', 'aaa');
|
||||
COMMIT;
|
||||
}
|
||||
} {}
|
||||
|
||||
set t53 0
|
||||
proc write_callback {args} {
|
||||
do_test 5.3.[incr ::t53] {
|
||||
execsql BEGIN
|
||||
list [catch { sqlite3_snapshot_open db main $::snapshot } msg] $msg
|
||||
} {1 SQLITE_BUSY}
|
||||
catchsql COMMIT
|
||||
}
|
||||
|
||||
tvfs filter xWrite
|
||||
tvfs script write_callback
|
||||
db2 eval { PRAGMA wal_checkpoint }
|
||||
db close
|
||||
db2 close
|
||||
tvfs delete
|
||||
sqlite3_snapshot_free $snapshot
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that sqlite3_snapshot_get() may be called immediately after
|
||||
# "BEGIN; PRAGMA user_version;". And that sqlite3_snapshot_open() may
|
||||
# be called after opening the db handle and running the script
|
||||
# "PRAGMA user_version; BEGIN".
|
||||
reset_db
|
||||
do_execsql_test 6.1 {
|
||||
PRAGMA journal_mode = wal;
|
||||
CREATE TABLE x1(x, xx, xxx);
|
||||
INSERT INTO x1 VALUES('z', 'zz', 'zzz');
|
||||
BEGIN;
|
||||
PRAGMA user_version;
|
||||
} {wal 0}
|
||||
do_test 6.2 {
|
||||
set ::snapshot [sqlite3_snapshot_get db main]
|
||||
execsql {
|
||||
INSERT INTO x1 VALUES('a', 'aa', 'aaa');
|
||||
COMMIT;
|
||||
}
|
||||
} {}
|
||||
do_test 6.3 {
|
||||
sqlite3 db2 test.db
|
||||
db2 eval "PRAGMA user_version ; BEGIN"
|
||||
sqlite3_snapshot_open db2 main $::snapshot
|
||||
db2 eval { SELECT * FROM x1 }
|
||||
} {z zz zzz}
|
||||
do_test 6.4 {
|
||||
tvfs filter xWrite
|
||||
tvfs script write_callback
|
||||
db2 eval { PRAGMA wal_checkpoint }
|
||||
db close
|
||||
db2 close
|
||||
sqlite3 db2 test.db
|
||||
db2 eval "PRAGMA application_id"
|
||||
db2 eval "BEGIN"
|
||||
sqlite3_snapshot_open db2 main $::snapshot
|
||||
db2 eval { SELECT * FROM x1 }
|
||||
} {z zz zzz}
|
||||
tvfs delete
|
||||
snapshot_free $snapshot
|
||||
|
||||
do_test 6.5 {
|
||||
db2 close
|
||||
sqlite3 db2 test.db
|
||||
db2 eval "BEGIN"
|
||||
list [catch {sqlite3_snapshot_open db2 main $::snapshot} msg] $msg
|
||||
} {1 SQLITE_ERROR}
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that sqlite3_snapshot_get() may be called immediately after
|
||||
# "BEGIN; PRAGMA user_version;". And that sqlite3_snapshot_open() may
|
||||
# be called after opening the db handle and running the script
|
||||
# "PRAGMA user_version; BEGIN".
|
||||
reset_db
|
||||
do_execsql_test $tn.6.1 {
|
||||
PRAGMA journal_mode = wal;
|
||||
CREATE TABLE x1(x, xx, xxx);
|
||||
INSERT INTO x1 VALUES('z', 'zz', 'zzz');
|
||||
BEGIN;
|
||||
PRAGMA user_version;
|
||||
} {wal 0}
|
||||
do_test $tn.6.2 {
|
||||
set ::snapshot [snapshot_get db main]
|
||||
execsql {
|
||||
INSERT INTO x1 VALUES('a', 'aa', 'aaa');
|
||||
COMMIT;
|
||||
}
|
||||
} {}
|
||||
do_test $tn.6.3 {
|
||||
sqlite3 db2 test.db
|
||||
db2 eval "PRAGMA user_version ; BEGIN"
|
||||
snapshot_open db2 main $::snapshot
|
||||
db2 eval { SELECT * FROM x1 }
|
||||
} {z zz zzz}
|
||||
do_test $tn.6.4 {
|
||||
db2 close
|
||||
sqlite3 db2 test.db
|
||||
db2 eval "PRAGMA application_id"
|
||||
db2 eval "BEGIN"
|
||||
snapshot_open db2 main $::snapshot
|
||||
db2 eval { SELECT * FROM x1 }
|
||||
} {z zz zzz}
|
||||
|
||||
sqlite3_snapshot_free $snapshot
|
||||
do_test $tn.6.5 {
|
||||
db2 close
|
||||
sqlite3 db2 test.db
|
||||
db2 eval "BEGIN"
|
||||
list [catch {snapshot_open db2 main $::snapshot} msg] $msg
|
||||
} {1 SQLITE_ERROR}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# The following tests investigate the sqlite3_snapshot_cmp() API.
|
||||
#
|
||||
snapshot_free $snapshot
|
||||
|
||||
# Compare snapshots $p1 and $p2, checking that the result is $r.
|
||||
#
|
||||
proc do_snapshot_cmp_test {tn p1 p2 r} {
|
||||
uplevel [list do_test $tn.1 [list sqlite3_snapshot_cmp $p1 $p2] $r]
|
||||
uplevel [list do_test $tn.2 [list sqlite3_snapshot_cmp $p2 $p1] [expr $r*-1]]
|
||||
uplevel [list do_test $tn.3 [list sqlite3_snapshot_cmp $p1 $p1] 0]
|
||||
uplevel [list do_test $tn.4 [list sqlite3_snapshot_cmp $p2 $p2] 0]
|
||||
#-------------------------------------------------------------------------
|
||||
# The following tests investigate the sqlite3_snapshot_cmp() API.
|
||||
#
|
||||
|
||||
# Compare snapshots $p1 and $p2, checking that the result is $r.
|
||||
#
|
||||
proc do_snapshot_cmp_test {tn p1 p2 r} {
|
||||
uplevel [list do_test $tn.1 [list snapshot_cmp $p1 $p2] $r]
|
||||
uplevel [list do_test $tn.2 [list snapshot_cmp $p2 $p1] [expr $r*-1]]
|
||||
uplevel [list do_test $tn.3 [list snapshot_cmp $p1 $p1] 0]
|
||||
uplevel [list do_test $tn.4 [list snapshot_cmp $p2 $p2] 0]
|
||||
}
|
||||
|
||||
catch { db2 close }
|
||||
reset_db
|
||||
|
||||
do_execsql_test $tn.7.1 {
|
||||
PRAGMA journal_mode = wal;
|
||||
CREATE TABLE t1(x);
|
||||
} wal
|
||||
|
||||
do_test $tn.7.1.2 {
|
||||
execsql { BEGIN ; PRAGMA application_id }
|
||||
set p1 [snapshot_get db main]
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(10);
|
||||
COMMIT;
|
||||
}
|
||||
execsql { BEGIN ; PRAGMA application_id }
|
||||
set p2 [snapshot_get db main]
|
||||
execsql COMMIT
|
||||
} {}
|
||||
|
||||
do_snapshot_cmp_test $tn.7.1.3 $p1 $p2 -1
|
||||
snapshot_free $p1
|
||||
snapshot_free $p2
|
||||
|
||||
do_execsql_test $tn.7.2.1 {
|
||||
INSERT INTO t1 VALUES(11);
|
||||
INSERT INTO t1 VALUES(12);
|
||||
INSERT INTO t1 VALUES(13);
|
||||
BEGIN;
|
||||
PRAGMA application_id;
|
||||
} {0}
|
||||
do_test $tn.7.2.2 {
|
||||
set p1 [snapshot_get db main]
|
||||
execsql {
|
||||
COMMIT;
|
||||
INSERT INTO t1 VALUES(14);
|
||||
PRAGMA wal_checkpoint;
|
||||
BEGIN;
|
||||
PRAGMA application_id;
|
||||
}
|
||||
set p2 [snapshot_get db main]
|
||||
execsql COMMIT
|
||||
} {}
|
||||
|
||||
do_snapshot_cmp_test $tn.7.2.3 $p1 $p2 -1
|
||||
snapshot_free $p2
|
||||
|
||||
do_test $tn.7.3.1 {
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(14);
|
||||
BEGIN;
|
||||
PRAGMA application_id;
|
||||
}
|
||||
set p2 [snapshot_get db main]
|
||||
execsql COMMIT
|
||||
} {}
|
||||
|
||||
do_snapshot_cmp_test $tn.7.3.2 $p1 $p2 -1
|
||||
snapshot_free $p1
|
||||
snapshot_free $p2
|
||||
}
|
||||
|
||||
catch { db2 close }
|
||||
reset_db
|
||||
|
||||
do_execsql_test 7.1 {
|
||||
PRAGMA journal_mode = wal;
|
||||
CREATE TABLE t1(x);
|
||||
} wal
|
||||
|
||||
do_test 7.1.2 {
|
||||
execsql { BEGIN ; PRAGMA application_id }
|
||||
set p1 [sqlite3_snapshot_get db main]
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(10);
|
||||
COMMIT;
|
||||
}
|
||||
execsql { BEGIN ; PRAGMA application_id }
|
||||
set p2 [sqlite3_snapshot_get db main]
|
||||
execsql COMMIT
|
||||
} {}
|
||||
|
||||
do_snapshot_cmp_test 7.1.3 $p1 $p2 -1
|
||||
sqlite3_snapshot_free $p1
|
||||
sqlite3_snapshot_free $p2
|
||||
|
||||
do_execsql_test 7.2.1 {
|
||||
INSERT INTO t1 VALUES(11);
|
||||
INSERT INTO t1 VALUES(12);
|
||||
INSERT INTO t1 VALUES(13);
|
||||
BEGIN;
|
||||
PRAGMA application_id;
|
||||
} {0}
|
||||
do_test 7.2.2 {
|
||||
set p1 [sqlite3_snapshot_get db main]
|
||||
execsql {
|
||||
COMMIT;
|
||||
INSERT INTO t1 VALUES(14);
|
||||
PRAGMA wal_checkpoint;
|
||||
BEGIN;
|
||||
PRAGMA application_id;
|
||||
}
|
||||
set p2 [sqlite3_snapshot_get db main]
|
||||
execsql COMMIT
|
||||
} {}
|
||||
|
||||
do_snapshot_cmp_test 7.2.3 $p1 $p2 -1
|
||||
sqlite3_snapshot_free $p2
|
||||
|
||||
do_test 7.3.1 {
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(14);
|
||||
BEGIN;
|
||||
PRAGMA application_id;
|
||||
}
|
||||
set p2 [sqlite3_snapshot_get db main]
|
||||
execsql COMMIT
|
||||
} {}
|
||||
|
||||
do_snapshot_cmp_test 7.3.2 $p1 $p2 -1
|
||||
sqlite3_snapshot_free $p1
|
||||
sqlite3_snapshot_free $p2
|
||||
|
||||
finish_test
|
||||
|
Loading…
Reference in New Issue
Block a user