diff options
Diffstat (limited to '')
-rw-r--r-- | test/tkt2854.test | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/test/tkt2854.test b/test/tkt2854.test new file mode 100644 index 0000000..e5ef2da --- /dev/null +++ b/test/tkt2854.test @@ -0,0 +1,139 @@ +# 2007 December 20 +# +# 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. +# +#*********************************************************************** +# +# $Id: tkt2854.test,v 1.4 2009/03/16 13:19:36 danielk1977 Exp $ + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +db close + +ifcapable !shared_cache { + finish_test + return +} + +set ::enable_shared_cache [sqlite3_enable_shared_cache 1] + +# Open 3 database connections. Connection "db" and "db2" share a cache. +# Connection "db3" has its own cache. +# +do_test tkt2854-1.1 { + sqlite3 db test.db + sqlite3 db2 test.db + sqlite3 db3 "file:test.db?cache=private" -uri 1 + + db eval { + CREATE TABLE abc(a, b, c); + } +} {} + +# Check that an exclusive lock cannot be obtained if some other +# shared-cache connection has a read-lock on a table. +# +do_test tkt2854-1.2 { + execsql { + BEGIN; + SELECT * FROM abc; + } db2 +} {} +do_test tkt2854-1.3 { + catchsql { BEGIN EXCLUSIVE } db +} {1 {database table is locked}} +do_test tkt2854-1.4 { + execsql { SELECT * FROM abc } db3 +} {} +do_test tkt2854-1.5 { + catchsql { INSERT INTO abc VALUES(1, 2, 3) } db3 +} {1 {database is locked}} +do_test tkt2854-1.6 { + execsql { COMMIT } db2 +} {} + +# Check that an exclusive lock prevents other shared-cache users from +# starting a transaction. +# +do_test tkt2854-1.7 { + set ::DB2 [sqlite3_connection_pointer db2] + set ::STMT1 [sqlite3_prepare $DB2 "SELECT * FROM abc" -1 TAIL] + set ::STMT2 [sqlite3_prepare $DB2 "BEGIN EXCLUSIVE" -1 TAIL] + set ::STMT3 [sqlite3_prepare $DB2 "BEGIN IMMEDIATE" -1 TAIL] + set ::STMT4 [sqlite3_prepare $DB2 "BEGIN" -1 TAIL] + set ::STMT5 [sqlite3_prepare $DB2 "COMMIT" -1 TAIL] + execsql { BEGIN EXCLUSIVE } db +} {} +do_test tkt2854-1.8 { + catchsql { BEGIN EXCLUSIVE } db2 +} {1 {database schema is locked: main}} +do_test tkt2854-1.9 { + catchsql { BEGIN IMMEDIATE } db2 +} {1 {database schema is locked: main}} +do_test tkt2854-1.10 { + # This fails because the schema of main cannot be verified. + catchsql { BEGIN } db2 +} {1 {database schema is locked: main}} + +# Check that an exclusive lock prevents other shared-cache users from +# reading the database. Use stored statements so that the error occurs +# at the b-tree level, not the schema level. +# +do_test tkt2854-1.11 { + list [sqlite3_step $::STMT1] [sqlite3_finalize $::STMT1] +} {SQLITE_ERROR SQLITE_LOCKED} +do_test tkt2854-1.12 { + list [sqlite3_step $::STMT2] [sqlite3_finalize $::STMT2] +} {SQLITE_ERROR SQLITE_LOCKED} +do_test tkt2854-1.13 { + list [sqlite3_step $::STMT3] [sqlite3_finalize $::STMT3] +} {SQLITE_ERROR SQLITE_LOCKED} +do_test tkt2854-1.14 { + # A regular "BEGIN" doesn't touch any databases. So it succeeds. + list [sqlite3_step $::STMT4] [sqlite3_finalize $::STMT4] +} {SQLITE_DONE SQLITE_OK} +do_test tkt2854-1.15 { + # As does a COMMIT. + list [sqlite3_step $::STMT5] [sqlite3_finalize $::STMT5] +} {SQLITE_DONE SQLITE_OK} + +# Try to read the database using connection "db3" (which does not share +# a cache with "db"). The database should be locked. +do_test tkt2854-1.16 { + catchsql { SELECT * FROM abc } db3 +} {1 {database is locked}} +do_test tkt2854-1.17 { + execsql { COMMIT } db +} {} +do_test tkt2854-1.18 { + execsql { SELECT * FROM abc } db2 +} {} + +# Check that if an attempt to obtain an exclusive lock fails because an +# attached db cannot be locked, the internal exclusive flag used by +# shared-cache users is correctly cleared. +do_test tkt2854-1.19 { + forcedelete test2.db test2.db-journal + sqlite3 db4 test2.db + execsql { CREATE TABLE def(d, e, f) } db4 + execsql { ATTACH 'test2.db' AS aux } db +} {} +do_test tkt2854-1.20 { + execsql {BEGIN IMMEDIATE} db4 + catchsql {BEGIN EXCLUSIVE} db +} {1 {database table is locked}} +do_test tkt2854-1.21 { + execsql {SELECT * FROM abc} db2 +} {} + +db close +db2 close +db3 close +db4 close +sqlite3_enable_shared_cache $::enable_shared_cache +finish_test |