diff options
Diffstat (limited to 'libraries/sqlite/unix/sqlite-3.5.1/test/btree5.test')
-rw-r--r-- | libraries/sqlite/unix/sqlite-3.5.1/test/btree5.test | 292 |
1 files changed, 292 insertions, 0 deletions
diff --git a/libraries/sqlite/unix/sqlite-3.5.1/test/btree5.test b/libraries/sqlite/unix/sqlite-3.5.1/test/btree5.test new file mode 100644 index 0000000..2afcd84 --- /dev/null +++ b/libraries/sqlite/unix/sqlite-3.5.1/test/btree5.test | |||
@@ -0,0 +1,292 @@ | |||
1 | # 2004 May 10 | ||
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 | # This file implements regression tests for SQLite library. The | ||
12 | # focus of this script is btree database backend | ||
13 | # | ||
14 | # $Id: btree5.test,v 1.5 2004/05/14 12:17:46 drh Exp $ | ||
15 | |||
16 | |||
17 | set testdir [file dirname $argv0] | ||
18 | source $testdir/tester.tcl | ||
19 | |||
20 | # Attempting to read table 1 of an empty file gives an SQLITE_EMPTY | ||
21 | # error. | ||
22 | # | ||
23 | do_test btree5-1.1 { | ||
24 | file delete -force test1.bt | ||
25 | file delete -force test1.bt-journal | ||
26 | set rc [catch {btree_open test1.bt 2000 0} ::b1] | ||
27 | } {0} | ||
28 | do_test btree5-1.2 { | ||
29 | set rc [catch {btree_cursor $::b1 1 0} ::c1] | ||
30 | } {1} | ||
31 | do_test btree5-1.3 { | ||
32 | set ::c1 | ||
33 | } {SQLITE_EMPTY} | ||
34 | do_test btree5-1.4 { | ||
35 | set rc [catch {btree_cursor $::b1 1 1} ::c1] | ||
36 | } {1} | ||
37 | do_test btree5-1.5 { | ||
38 | set ::c1 | ||
39 | } {SQLITE_EMPTY} | ||
40 | |||
41 | # Starting a transaction initializes the first page of the database | ||
42 | # and the error goes away. | ||
43 | # | ||
44 | do_test btree5-1.6 { | ||
45 | btree_begin_transaction $b1 | ||
46 | set rc [catch {btree_cursor $b1 1 0} c1] | ||
47 | } {0} | ||
48 | do_test btree5-1.7 { | ||
49 | btree_first $c1 | ||
50 | } {1} | ||
51 | do_test btree5-1.8 { | ||
52 | btree_close_cursor $c1 | ||
53 | btree_rollback $b1 | ||
54 | set rc [catch {btree_cursor $b1 1 0} c1] | ||
55 | } {1} | ||
56 | do_test btree5-1.9 { | ||
57 | set c1 | ||
58 | } {SQLITE_EMPTY} | ||
59 | do_test btree5-1.10 { | ||
60 | btree_begin_transaction $b1 | ||
61 | set rc [catch {btree_cursor $b1 1 0} c1] | ||
62 | } {0} | ||
63 | do_test btree5-1.11 { | ||
64 | btree_first $c1 | ||
65 | } {1} | ||
66 | do_test btree5-1.12 { | ||
67 | btree_close_cursor $c1 | ||
68 | btree_commit $b1 | ||
69 | set rc [catch {btree_cursor $b1 1 0} c1] | ||
70 | } {0} | ||
71 | do_test btree5-1.13 { | ||
72 | btree_first $c1 | ||
73 | } {1} | ||
74 | do_test btree5-1.14 { | ||
75 | btree_close_cursor $c1 | ||
76 | btree_integrity_check $b1 1 | ||
77 | } {} | ||
78 | |||
79 | # Insert many entries into table 1. This is designed to test the | ||
80 | # virtual-root logic that comes into play for page one. It is also | ||
81 | # a good test of INTKEY tables. | ||
82 | # | ||
83 | # Stagger the inserts. After the inserts complete, go back and do | ||
84 | # deletes. Stagger the deletes too. Repeat this several times. | ||
85 | # | ||
86 | |||
87 | # Do N inserts into table 1 using random keys between 0 and 1000000 | ||
88 | # | ||
89 | proc random_inserts {N} { | ||
90 | global c1 | ||
91 | while {$N>0} { | ||
92 | set k [expr {int(rand()*1000000)}] | ||
93 | if {[btree_move_to $c1 $k]==0} continue; # entry already exists | ||
94 | btree_insert $c1 $k data-for-$k | ||
95 | incr N -1 | ||
96 | } | ||
97 | } | ||
98 | |||
99 | # Do N delete from table 1 | ||
100 | # | ||
101 | proc random_deletes {N} { | ||
102 | global c1 | ||
103 | while {$N>0} { | ||
104 | set k [expr {int(rand()*1000000)}] | ||
105 | btree_move_to $c1 $k | ||
106 | btree_delete $c1 | ||
107 | incr N -1 | ||
108 | } | ||
109 | } | ||
110 | |||
111 | # Make sure the table has exactly N entries. Make sure the data for | ||
112 | # each entry agrees with its key. | ||
113 | # | ||
114 | proc check_table {N} { | ||
115 | global c1 | ||
116 | btree_first $c1 | ||
117 | set cnt 0 | ||
118 | while {![btree_eof $c1]} { | ||
119 | if {[set data [btree_data $c1]] ne "data-for-[btree_key $c1]"} { | ||
120 | return "wrong data for entry $cnt" | ||
121 | } | ||
122 | set n [string length $data] | ||
123 | set fdata1 [btree_fetch_data $c1 $n] | ||
124 | set fdata2 [btree_fetch_data $c1 -1] | ||
125 | if {$fdata1 ne "" && $fdata1 ne $data} { | ||
126 | return "DataFetch returned the wrong value with amt=$n" | ||
127 | } | ||
128 | if {$fdata1 ne $fdata2} { | ||
129 | return "DataFetch returned the wrong value when amt=-1" | ||
130 | } | ||
131 | if {$n>10} { | ||
132 | set fdata3 [btree_fetch_data $c1 10] | ||
133 | if {$fdata3 ne [string range $data 0 9]} { | ||
134 | return "DataFetch returned the wrong value when amt=10" | ||
135 | } | ||
136 | } | ||
137 | incr cnt | ||
138 | btree_next $c1 | ||
139 | } | ||
140 | if {$cnt!=$N} { | ||
141 | return "wrong number of entries" | ||
142 | } | ||
143 | return {} | ||
144 | } | ||
145 | |||
146 | # Initialize the database | ||
147 | # | ||
148 | btree_begin_transaction $b1 | ||
149 | set c1 [btree_cursor $b1 1 1] | ||
150 | set btree_trace 0 | ||
151 | |||
152 | # Do the tests. | ||
153 | # | ||
154 | set cnt 0 | ||
155 | for {set i 1} {$i<=100} {incr i} { | ||
156 | do_test btree5-2.$i.1 { | ||
157 | random_inserts 200 | ||
158 | incr cnt 200 | ||
159 | check_table $cnt | ||
160 | } {} | ||
161 | do_test btree5-2.$i.2 { | ||
162 | btree_integrity_check $b1 1 | ||
163 | } {} | ||
164 | do_test btree5-2.$i.3 { | ||
165 | random_deletes 190 | ||
166 | incr cnt -190 | ||
167 | check_table $cnt | ||
168 | } {} | ||
169 | do_test btree5-2.$i.4 { | ||
170 | btree_integrity_check $b1 1 | ||
171 | } {} | ||
172 | } | ||
173 | |||
174 | #btree_tree_dump $b1 1 | ||
175 | btree_close_cursor $c1 | ||
176 | btree_commit $b1 | ||
177 | btree_begin_transaction $b1 | ||
178 | |||
179 | # This procedure converts an integer into a variable-length text key. | ||
180 | # The conversion is reversible. | ||
181 | # | ||
182 | # The first two characters of the string are alphabetics derived from | ||
183 | # the least significant bits of the number. Because they are derived | ||
184 | # from least significant bits, the sort order of the resulting string | ||
185 | # is different from numeric order. After the alphabetic prefix comes | ||
186 | # the original number. A variable-length suffix follows. The length | ||
187 | # of the suffix is based on a hash of the original number. | ||
188 | # | ||
189 | proc num_to_key {n} { | ||
190 | global charset ncharset suffix | ||
191 | set c1 [string index $charset [expr {$n%$ncharset}]] | ||
192 | set c2 [string index $charset [expr {($n/$ncharset)%$ncharset}]] | ||
193 | set nsuf [expr {($n*211)%593}] | ||
194 | return $c1$c2-$n-[string range $suffix 0 $nsuf] | ||
195 | } | ||
196 | set charset {abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ} | ||
197 | set ncharset [string length $charset] | ||
198 | set suffix $charset$charset | ||
199 | while {[string length $suffix]<1000} {append suffix $suffix} | ||
200 | |||
201 | # This procedures extracts the original integer used to create | ||
202 | # a key by num_to_key | ||
203 | # | ||
204 | proc key_to_num {key} { | ||
205 | regexp {^..-([0-9]+)} $key all n | ||
206 | return $n | ||
207 | } | ||
208 | |||
209 | # Insert into table $tab keys corresponding to all values between | ||
210 | # $start and $end, inclusive. | ||
211 | # | ||
212 | proc insert_range {tab start end} { | ||
213 | for {set i $start} {$i<=$end} {incr i} { | ||
214 | btree_insert $tab [num_to_key $i] {} | ||
215 | } | ||
216 | } | ||
217 | |||
218 | # Delete from table $tab keys corresponding to all values between | ||
219 | # $start and $end, inclusive. | ||
220 | # | ||
221 | proc delete_range {tab start end} { | ||
222 | for {set i $start} {$i<=$end} {incr i} { | ||
223 | if {[btree_move_to $tab [num_to_key $i]]==0} { | ||
224 | btree_delete $tab | ||
225 | } | ||
226 | } | ||
227 | } | ||
228 | |||
229 | # Make sure table $tab contains exactly those keys corresponding | ||
230 | # to values between $start and $end | ||
231 | # | ||
232 | proc check_range {tab start end} { | ||
233 | btree_first $tab | ||
234 | while {![btree_eof $tab]} { | ||
235 | set key [btree_key $tab] | ||
236 | set i [key_to_num $key] | ||
237 | if {[num_to_key $i] ne $key} { | ||
238 | return "malformed key: $key" | ||
239 | } | ||
240 | set got($i) 1 | ||
241 | btree_next $tab | ||
242 | } | ||
243 | set all [lsort -integer [array names got]] | ||
244 | if {[llength $all]!=$end+1-$start} { | ||
245 | return "table contains wrong number of values" | ||
246 | } | ||
247 | if {[lindex $all 0]!=$start} { | ||
248 | return "wrong starting value" | ||
249 | } | ||
250 | if {[lindex $all end]!=$end} { | ||
251 | return "wrong ending value" | ||
252 | } | ||
253 | return {} | ||
254 | } | ||
255 | |||
256 | # Create a zero-data table and test it out. | ||
257 | # | ||
258 | do_test btree5-3.1 { | ||
259 | set rc [catch {btree_create_table $b1 2} t2] | ||
260 | } {0} | ||
261 | do_test btree5-3.2 { | ||
262 | set rc [catch {btree_cursor $b1 $t2 1} c2] | ||
263 | } {0} | ||
264 | set start 1 | ||
265 | set end 100 | ||
266 | for {set i 1} {$i<=100} {incr i} { | ||
267 | do_test btree5-3.3.$i.1 { | ||
268 | insert_range $c2 $start $end | ||
269 | btree_integrity_check $b1 1 $t2 | ||
270 | } {} | ||
271 | do_test btree5-3.3.$i.2 { | ||
272 | check_range $c2 $start $end | ||
273 | } {} | ||
274 | set nstart $start | ||
275 | incr nstart 89 | ||
276 | do_test btree5-3.3.$i.3 { | ||
277 | delete_range $c2 $start $nstart | ||
278 | btree_integrity_check $b1 1 $t2 | ||
279 | } {} | ||
280 | incr start 90 | ||
281 | do_test btree5-3.3.$i.4 { | ||
282 | check_range $c2 $start $end | ||
283 | } {} | ||
284 | incr end 100 | ||
285 | } | ||
286 | |||
287 | |||
288 | btree_close_cursor $c2 | ||
289 | btree_commit $b1 | ||
290 | btree_close $b1 | ||
291 | |||
292 | finish_test | ||