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
|
# 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
|