AryaWu/sqlite
0
1# 2014 December 042#3# The author disclaims copyright to this source code. In place of4# 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.tcl15source $testdir/wal_common.tcl16set testprefix e_walauto17 18# Do not run this test on OpenBSD, as it depends on read() and mmap both19# accessing the same coherent view of the "test.db-shm" file. This doesn't20# work on OpenBSD.21#22if {$tcl_platform(os) == "OpenBSD"} {23 finish_test24 return25}26 27# This module uses hard-coded offsets which do not work if the reserved_bytes28# value is nonzero.29if {[nonzero_reserved_bytes]} {finish_test; return;}30 31 32proc read_nbackfill {} {33 seek $::shmfd 9634 binary scan [read $::shmfd 4] n nBackfill35 set nBackfill36}37proc read_mxframe {} {38 seek $::shmfd 1639 binary scan [read $::shmfd 4] n mxFrame40 set mxFrame41}42 43# Assuming that the main db for database handle44#45proc do_autocommit_threshold_test {tn value} {46 47 set nBackfillSaved [read_nbackfill]48 while {1} {49 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }50 if {[read_mxframe] >= $value} break51 }52 53 set nBackfillNew [read_nbackfill]54 uplevel [list do_test $tn "expr $nBackfillNew > $nBackfillSaved" 1]55}56 57# EVIDENCE-OF: R-30135-06439 The wal_autocheckpoint pragma can be used58# to invoke this interface from SQL.59#60# All tests in this file are run twice - once using the61# sqlite3_wal_autocheckpoint() API, and once using "PRAGMA62# wal_autocheckpoint".63#64foreach {tn code} {65 1 {66 proc autocheckpoint {db value} {67 uplevel [list $db eval "PRAGMA wal_autocheckpoint = $value"]68 }69 }70 71 2 {72 proc autocheckpoint {db value} {73 uplevel [list sqlite3_wal_autocheckpoint $db $value]74 return $value75 }76 }77} {78 79 eval $code80 81 reset_db82 execsql { PRAGMA auto_vacuum = 0 }83 do_execsql_test 1.$tn.0 { PRAGMA journal_mode = WAL } {wal}84 do_execsql_test 1.$tn.1 { CREATE TABLE t1(a, b) }85 set shmfd [open "test.db-shm" rb]86 87 # EVIDENCE-OF: R-41531-51083 Every new database connection defaults to88 # having the auto-checkpoint enabled with a threshold of 1000 or89 # SQLITE_DEFAULT_WAL_AUTOCHECKPOINT pages.90 #91 do_autocommit_threshold_test 1.$tn.2 100092 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }93 do_autocommit_threshold_test 1.$tn.3 100094 95 # EVIDENCE-OF: R-38128-34102 The sqlite3_wal_autocheckpoint(D,N) is a96 # wrapper around sqlite3_wal_hook() that causes any database on database97 # connection D to automatically checkpoint after committing a98 # transaction if there are N or more frames in the write-ahead log file.99 #100 do_test 1.$tn.4 {101 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }102 autocheckpoint db 100103 } {100}104 do_autocommit_threshold_test 1.$tn.5 100105 106 do_test 1.$tn.6 {107 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }108 autocheckpoint db 500109 } {500}110 do_autocommit_threshold_test 1.$tn.7 500111 112 # EVIDENCE-OF: R-26993-43540 Passing zero or a negative value as the113 # nFrame parameter disables automatic checkpoints entirely.114 #115 do_test 1.$tn.7 {116 autocheckpoint db 0 ;# Set to zero117 for {set i 0} {$i < 10000} {incr i} {118 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }119 }120 expr {[file size test.db-wal] > (5 * 1024 * 1024)}121 } 1122 do_test 1.$tn.8 {123 sqlite3_wal_checkpoint_v2 db truncate124 file size test.db-wal125 } 0126 do_test 1.$tn.9 {127 autocheckpoint db -4 ;# Set to a negative value128 for {set i 0} {$i < 10000} {incr i} {129 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }130 }131 expr {[file size test.db-wal] > (5 * 1024 * 1024)}132 } 1133 134 # EVIDENCE-OF: R-10203-42688 The callback registered by this function135 # replaces any existing callback registered using sqlite3_wal_hook().136 #137 set ::wal_hook_callback 0138 proc wal_hook_callback {args} { incr ::wal_hook_callback ; return 0 }139 do_test 1.$tn.10.1 {140 db wal_hook wal_hook_callback141 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }142 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }143 set ::wal_hook_callback144 } 2145 do_test 1.$tn.10.2 {146 autocheckpoint db 100147 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }148 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }149 set ::wal_hook_callback150 } 2151 152 # EVIDENCE-OF: R-17497-43474 Likewise, registering a callback using153 # sqlite3_wal_hook() disables the automatic checkpoint mechanism154 # configured by this function.155 do_test 1.$tn.11.1 {156 sqlite3_wal_checkpoint_v2 db truncate157 file size test.db-wal158 } 0159 do_test 1.$tn.11.2 {160 autocheckpoint db 100 161 for {set i 0} {$i < 1000} {incr i} {162 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }163 }164 expr {[file size test.db-wal] < (1 * 1024 * 1024)}165 } 1166 do_test 1.$tn.11.3 {167 db wal_hook wal_hook_callback168 for {set i 0} {$i < 1000} {incr i} {169 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }170 }171 expr {[file size test.db-wal] < (1 * 1024 * 1024)}172 } 0173 174 # EVIDENCE-OF: R-33080-59193 Checkpoints initiated by this mechanism 175 # are PASSIVE.176 #177 set ::busy_callback_count 0178 proc busy_callback {args} {179 incr ::busy_callback_count180 return 0181 }182 do_test 1.$tn.12.1 {183 sqlite3_wal_checkpoint_v2 db truncate184 autocheckpoint db 100 185 db busy busy_callback186 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }187 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }188 } {}189 do_test 1.$tn.12.2 {190 sqlite3 db2 test.db191 db2 eval { BEGIN; SELECT * FROM t1 LIMIT 10; }192 read_nbackfill193 } {0}194 do_test 1.$tn.12.3 {195 for {set i 0} {$i < 1000} {incr i} {196 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }197 }198 read_nbackfill199 } {2}200 do_test 1.$tn.12.4 {201 set ::busy_callback_count202 } {0}203 db2 close204 205 do_test 1.$tn.12.5 {206 db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }207 read_nbackfill208 } {1559}209 210 db close211 close $shmfd212}213 214finish_test215 