wasCSharpSQLite – Blame information for rev 4

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 # 2009 January 3
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 # $Id: savepoint6.test,v 1.4 2009/06/05 17:09:12 drh Exp $
13  
14 set testdir [file dirname $argv0]
15 source $testdir/tester.tcl
16  
17 proc sql {zSql} {
18 uplevel db eval [list $zSql]
19 #puts stderr "$zSql ;"
20 }
21  
22 set DATABASE_SCHEMA {
23 PRAGMA auto_vacuum = incremental;
24 CREATE TABLE t1(x, y);
25 CREATE UNIQUE INDEX i1 ON t1(x);
26 CREATE INDEX i2 ON t1(y);
27 }
28  
29 if {0==[info exists ::G(savepoint6_iterations)]} {
30 set ::G(savepoint6_iterations) 1000
31 }
32  
33 #--------------------------------------------------------------------------
34 # In memory database state.
35 #
36 # ::lSavepoint is a list containing one entry for each active savepoint. The
37 # first entry in the list corresponds to the most recently opened savepoint.
38 # Each entry consists of two elements:
39 #
40 # 1. The savepoint name.
41 #
42 # 2. A serialized Tcl array representing the contents of table t1 at the
43 # start of the savepoint. The keys of the array are the x values. The
44 # values are the y values.
45 #
46 # Array ::aEntry contains the contents of database table t1. Array keys are
47 # x values, the array data values are y values.
48 #
49 set lSavepoint [list]
50 array set aEntry [list]
51  
52 proc x_to_y {x} {
53 set nChar [expr int(rand()*250) + 250]
54 set str " $nChar [string repeat $x. $nChar]"
55 string range $str 1 $nChar
56 }
57 #--------------------------------------------------------------------------
58  
59 #-------------------------------------------------------------------------
60 # Procs to operate on database:
61 #
62 # savepoint NAME
63 # rollback NAME
64 # release NAME
65 #
66 # insert_rows XVALUES
67 # delete_rows XVALUES
68 #
69 proc savepoint {zName} {
70 catch { sql "SAVEPOINT $zName" }
71 lappend ::lSavepoint [list $zName [array get ::aEntry]]
72 }
73  
74 proc rollback {zName} {
75 catch { sql "ROLLBACK TO $zName" }
76 for {set i [expr {[llength $::lSavepoint]-1}]} {$i>=0} {incr i -1} {
77 set zSavepoint [lindex $::lSavepoint $i 0]
78 if {$zSavepoint eq $zName} {
79 unset -nocomplain ::aEntry
80 array set ::aEntry [lindex $::lSavepoint $i 1]
81  
82  
83 if {$i+1 < [llength $::lSavepoint]} {
84 set ::lSavepoint [lreplace $::lSavepoint [expr $i+1] end]
85 }
86 break
87 }
88 }
89 }
90  
91 proc release {zName} {
92 catch { sql "RELEASE $zName" }
93 for {set i [expr {[llength $::lSavepoint]-1}]} {$i>=0} {incr i -1} {
94 set zSavepoint [lindex $::lSavepoint $i 0]
95 if {$zSavepoint eq $zName} {
96 set ::lSavepoint [lreplace $::lSavepoint $i end]
97 break
98 }
99 }
100  
101 if {[llength $::lSavepoint] == 0} {
102 #puts stderr "-- End of transaction!!!!!!!!!!!!!"
103 }
104 }
105  
106 proc insert_rows {lX} {
107 foreach x $lX {
108 set y [x_to_y $x]
109  
110 # Update database [db]
111 sql "INSERT OR REPLACE INTO t1 VALUES($x, '$y')"
112  
113 # Update the Tcl database.
114 set ::aEntry($x) $y
115 }
116 }
117  
118 proc delete_rows {lX} {
119 foreach x $lX {
120 # Update database [db]
121 sql "DELETE FROM t1 WHERE x = $x"
122  
123 # Update the Tcl database.
124 unset -nocomplain ::aEntry($x)
125 }
126 }
127 #-------------------------------------------------------------------------
128  
129 #-------------------------------------------------------------------------
130 # Proc to compare database content with the in-memory representation.
131 #
132 # checkdb
133 #
134 proc checkdb {} {
135 set nEntry [db one {SELECT count(*) FROM t1}]
136 set nEntry2 [array size ::aEntry]
137 if {$nEntry != $nEntry2} {
138 error "$nEntry entries in database, $nEntry2 entries in array"
139 }
140 db eval {SELECT x, y FROM t1} {
141 if {![info exists ::aEntry($x)]} {
142 error "Entry $x exists in database, but not in array"
143 }
144 if {$::aEntry($x) ne $y} {
145 error "Entry $x is set to {$y} in database, {$::aEntry($x)} in array"
146 }
147 }
148  
149 db eval { PRAGMA integrity_check }
150 }
151 #-------------------------------------------------------------------------
152  
153 #-------------------------------------------------------------------------
154 # Proc to return random set of x values.
155 #
156 # random_integers
157 #
158 proc random_integers {nRes nRange} {
159 set ret [list]
160 for {set i 0} {$i<$nRes} {incr i} {
161 lappend ret [expr int(rand()*$nRange)]
162 }
163 return $ret
164 }
165 #-------------------------------------------------------------------------
166  
167 proc database_op {} {
168 set i [expr int(rand()*2)]
169 if {$i==0} {
170 insert_rows [random_integers 10 10]
171 }
172 if {$i==1} {
173 delete_rows [random_integers 10 10]
174 set i [expr int(rand()*3)]
175 if {$i==0} {
176 sql {PRAGMA incremental_vacuum}
177 }
178 }
179 }
180  
181 proc savepoint_op {} {
182 set names {one two three four five}
183 set cmds {savepoint savepoint savepoint savepoint release rollback}
184  
185 set C [lindex $cmds [expr int(rand()*6)]]
186 set N [lindex $names [expr int(rand()*5)]]
187  
188 #puts stderr " $C $N ; "
189 #flush stderr
190  
191 $C $N
192 return ok
193 }
194  
195 expr srand(3)
196  
197 ############################################################################
198 ############################################################################
199 # Start of test cases.
200  
201 do_test savepoint6-1.1 {
202 sql $DATABASE_SCHEMA
203 } {}
204 do_test savepoint6-1.2 {
205 insert_rows {
206 497 166 230 355 779 588 394 317 290 475 362 193 805 851 564
207 763 44 930 389 819 765 760 966 280 538 414 500 18 25 287 320
208 30 382 751 87 283 981 429 630 974 421 270 810 405
209 }
210  
211 savepoint one
212 insert_rows 858
213 delete_rows 930
214 savepoint two
215 execsql {PRAGMA incremental_vacuum}
216 savepoint three
217 insert_rows 144
218 rollback three
219 rollback two
220 release one
221  
222 execsql {SELECT count(*) FROM t1}
223 } {44}
224  
225 foreach zSetup [list {
226 set testname normal
227 sqlite3 db test.db
228 } {
229 if {[wal_is_wal_mode]} continue
230 set testname tempdb
231 sqlite3 db ""
232 } {
233 if {[permutation] eq "journaltest"} {
234 continue
235 }
236 set testname nosync
237 sqlite3 db test.db
238 sql { PRAGMA synchronous = off }
239 } {
240 set testname smallcache
241 sqlite3 db test.db
242 sql { PRAGMA cache_size = 10 }
243 }] {
244  
245 unset -nocomplain ::lSavepoint
246 unset -nocomplain ::aEntry
247  
248 catch { db close }
249 file delete -force test.db test.db-wal test.db-journal
250 eval $zSetup
251 sql $DATABASE_SCHEMA
252  
253 wal_set_journal_mode
254  
255 do_test savepoint6-$testname.setup {
256 savepoint one
257 insert_rows [random_integers 100 1000]
258 release one
259 checkdb
260 } {ok}
261  
262 for {set i 0} {$i < $::G(savepoint6_iterations)} {incr i} {
263 do_test savepoint6-$testname.$i.1 {
264 savepoint_op
265 checkdb
266 } {ok}
267  
268 do_test savepoint6-$testname.$i.2 {
269 database_op
270 database_op
271 checkdb
272 } {ok}
273 }
274  
275 wal_check_journal_mode savepoint6-$testname.walok
276 }
277  
278 unset -nocomplain ::lSavepoint
279 unset -nocomplain ::aEntry
280  
281 finish_test