17fee0bfaSdan# 2018 July 4 27fee0bfaSdan# 37fee0bfaSdan# The author disclaims copyright to this source code. In place of 47fee0bfaSdan# a legal notice, here is a blessing: 57fee0bfaSdan# 67fee0bfaSdan# May you do good and not evil. 77fee0bfaSdan# May you find forgiveness for yourself and forgive others. 87fee0bfaSdan# May you share freely, never taking more than you give. 97fee0bfaSdan# 107fee0bfaSdan#*********************************************************************** 117fee0bfaSdan# 127fee0bfaSdan 137fee0bfaSdanset testdir [file dirname $argv0] 147fee0bfaSdansource $testdir/tester.tcl 157fee0bfaSdansource $testdir/lock_common.tcl 167fee0bfaSdansource $testdir/wal_common.tcl 177fee0bfaSdanifcapable !wal {finish_test ; return } 187fee0bfaSdan 197fee0bfaSdanset testprefix walprotocol2 207fee0bfaSdan 217fee0bfaSdan#------------------------------------------------------------------------- 227fee0bfaSdan# When recovering the contents of a WAL file, a process obtains the WRITER 237fee0bfaSdan# lock, then locks all other bytes before commencing recovery. If it fails 247fee0bfaSdan# to lock all other bytes (because some other process is holding a read 257fee0bfaSdan# lock) it should retry up to 100 times. Then return SQLITE_PROTOCOL to the 267fee0bfaSdan# caller. Test this (test case 1.3). 277fee0bfaSdan# 287fee0bfaSdan# Also test the effect of hitting an SQLITE_BUSY while attempting to obtain 297fee0bfaSdan# the WRITER lock (should be the same). Test case 1.4. 307fee0bfaSdan# 317fee0bfaSdando_execsql_test 1.0 { 327fee0bfaSdan PRAGMA journal_mode = wal; 337fee0bfaSdan CREATE TABLE x(y); 347fee0bfaSdan INSERT INTO x VALUES('z'); 357fee0bfaSdan} {wal} 367fee0bfaSdan 377fee0bfaSdandb close 387fee0bfaSdan 397fee0bfaSdanproc lock_callback {method filename handle lock} { 407fee0bfaSdan # puts "$method $filename $handle $lock" 417fee0bfaSdan} 427fee0bfaSdantestvfs T 437fee0bfaSdanT filter xShmLock 447fee0bfaSdanT script lock_callback 457fee0bfaSdan 467fee0bfaSdansqlite3 db test.db -vfs T 477fee0bfaSdansqlite3 db2 test.db -vfs T 487fee0bfaSdan 497fee0bfaSdando_execsql_test 2.0 { 507fee0bfaSdan SELECT * FROM x; 517fee0bfaSdan} {z} 527fee0bfaSdando_execsql_test -db db2 2.1 { 537fee0bfaSdan SELECT * FROM x; 547fee0bfaSdan} {z} 557fee0bfaSdan 567fee0bfaSdan#--------------------------------------------------------------- 577fee0bfaSdan# Attempt a "BEGIN EXCLUSIVE" using connection handle [db]. This 587fee0bfaSdan# causes SQLite to open a read transaction, then a write transaction. 597fee0bfaSdan# Rig the xShmLock() callback so that just before the EXCLUSIVE lock 607fee0bfaSdan# for the write transaction is taken, connection [db2] jumps in and 617fee0bfaSdan# modifies the database. This causes the "BEGIN EXCLUSIVE" to throw 627fee0bfaSdan# an SQLITE_BUSY_SNAPSHOT error. 637fee0bfaSdan# 647fee0bfaSdanproc lock_callback {method filename handle lock} { 657fee0bfaSdan if {$lock=="0 1 lock exclusive"} { 667fee0bfaSdan proc lock_callback {method filename handle lock} {} 677fee0bfaSdan db2 eval { INSERT INTO x VALUES('y') } 687fee0bfaSdan } 697fee0bfaSdan} 707fee0bfaSdando_catchsql_test 2.2 { 717fee0bfaSdan BEGIN EXCLUSIVE; 727fee0bfaSdan} {1 {database is locked}} 737fee0bfaSdando_test 2.3 { 747fee0bfaSdan sqlite3_extended_errcode db 75*b07db116Sdan} {SQLITE_BUSY} 767fee0bfaSdan 777fee0bfaSdan#--------------------------------------------------------------- 787fee0bfaSdan# Same again, but with a busy-handler. This time, following the 797fee0bfaSdan# SQLITE_BUSY_SNAPSHOT error the busy-handler is invoked and then the 807fee0bfaSdan# whole thing retried from the beginning. This time it succeeds. 817fee0bfaSdan# 827fee0bfaSdanproc lock_callback {method filename handle lock} { 837fee0bfaSdan if {$lock=="0 1 lock exclusive"} { 847fee0bfaSdan proc lock_callback {method filename handle lock} {} 857fee0bfaSdan db2 eval { INSERT INTO x VALUES('x') } 867fee0bfaSdan } 877fee0bfaSdan} 887fee0bfaSdandb timeout 10 897fee0bfaSdando_catchsql_test 2.4 { 907fee0bfaSdan BEGIN EXCLUSIVE; 917fee0bfaSdan} {0 {}} 927fee0bfaSdando_execsql_test 2.5 { 937fee0bfaSdan SELECT * FROM x; 947fee0bfaSdan COMMIT; 957fee0bfaSdan} {z y x} 967fee0bfaSdan 977fee0bfaSdanfinish_test 98