1# 2018 July 4 2# 3# The author disclaims copyright to this source code. In place of 4# a legal notice, here is a blessing: 5# 6# May you do good and not evil. 7# May you find forgiveness for yourself and forgive others. 8# May you share freely, never taking more than you give. 9# 10#*********************************************************************** 11# 12 13set testdir [file dirname $argv0] 14source $testdir/tester.tcl 15source $testdir/lock_common.tcl 16source $testdir/wal_common.tcl 17ifcapable !wal {finish_test ; return } 18 19set testprefix walprotocol2 20 21#------------------------------------------------------------------------- 22# When recovering the contents of a WAL file, a process obtains the WRITER 23# lock, then locks all other bytes before commencing recovery. If it fails 24# to lock all other bytes (because some other process is holding a read 25# lock) it should retry up to 100 times. Then return SQLITE_PROTOCOL to the 26# caller. Test this (test case 1.3). 27# 28# Also test the effect of hitting an SQLITE_BUSY while attempting to obtain 29# the WRITER lock (should be the same). Test case 1.4. 30# 31do_execsql_test 1.0 { 32 PRAGMA journal_mode = wal; 33 CREATE TABLE x(y); 34 INSERT INTO x VALUES('z'); 35} {wal} 36 37db close 38 39proc lock_callback {method filename handle lock} { 40 # puts "$method $filename $handle $lock" 41} 42testvfs T 43T filter xShmLock 44T script lock_callback 45 46sqlite3 db test.db -vfs T 47sqlite3 db2 test.db -vfs T 48 49do_execsql_test 2.0 { 50 SELECT * FROM x; 51} {z} 52do_execsql_test -db db2 2.1 { 53 SELECT * FROM x; 54} {z} 55 56#--------------------------------------------------------------- 57# Attempt a "BEGIN EXCLUSIVE" using connection handle [db]. This 58# causes SQLite to open a read transaction, then a write transaction. 59# Rig the xShmLock() callback so that just before the EXCLUSIVE lock 60# for the write transaction is taken, connection [db2] jumps in and 61# modifies the database. This causes the "BEGIN EXCLUSIVE" to throw 62# an SQLITE_BUSY_SNAPSHOT error. 63# 64proc lock_callback {method filename handle lock} { 65 if {$lock=="0 1 lock exclusive"} { 66 proc lock_callback {method filename handle lock} {} 67 db2 eval { INSERT INTO x VALUES('y') } 68 } 69} 70do_catchsql_test 2.2 { 71 BEGIN EXCLUSIVE; 72} {1 {database is locked}} 73do_test 2.3 { 74 sqlite3_extended_errcode db 75} {SQLITE_BUSY} 76 77#--------------------------------------------------------------- 78# Same again, but with a busy-handler. This time, following the 79# SQLITE_BUSY_SNAPSHOT error the busy-handler is invoked and then the 80# whole thing retried from the beginning. This time it succeeds. 81# 82proc lock_callback {method filename handle lock} { 83 if {$lock=="0 1 lock exclusive"} { 84 proc lock_callback {method filename handle lock} {} 85 db2 eval { INSERT INTO x VALUES('x') } 86 } 87} 88db timeout 10 89do_catchsql_test 2.4 { 90 BEGIN EXCLUSIVE; 91} {0 {}} 92do_execsql_test 2.5 { 93 SELECT * FROM x; 94 COMMIT; 95} {z y x} 96 97finish_test 98