OLD | NEW |
| (Empty) |
1 # 2007 April 6 | |
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. | |
12 # | |
13 # This file implements tests to verify database file format. | |
14 # | |
15 # $Id: filefmt.test,v 1.3 2009/06/18 11:34:43 drh Exp $ | |
16 | |
17 set testdir [file dirname $argv0] | |
18 source $testdir/tester.tcl | |
19 | |
20 # Do not use a codec for tests in this file, as the database file is | |
21 # manipulated directly using tcl scripts (using the [hexio_write] command). | |
22 # | |
23 do_not_use_codec | |
24 | |
25 db close | |
26 forcedelete test.db test.db-journal | |
27 | |
28 # Database begins with valid 16-byte header string. | |
29 # | |
30 do_test filefmt-1.1 { | |
31 sqlite3 db test.db | |
32 db eval {CREATE TABLE t1(x)} | |
33 db close | |
34 hexio_read test.db 0 16 | |
35 } {53514C69746520666F726D6174203300} | |
36 | |
37 # If the 16-byte header is changed, the file will not open | |
38 # | |
39 do_test filefmt-1.2 { | |
40 hexio_write test.db 0 54 | |
41 set x [catch {sqlite3 db test.db} err] | |
42 lappend x $err | |
43 } {0 {}} | |
44 do_test filefmt-1.3 { | |
45 catchsql { | |
46 SELECT count(*) FROM sqlite_master | |
47 } | |
48 } {1 {file is encrypted or is not a database}} | |
49 do_test filefmt-1.4 { | |
50 db close | |
51 hexio_write test.db 0 53 | |
52 sqlite3 db test.db | |
53 catchsql { | |
54 SELECT count(*) FROM sqlite_master | |
55 } | |
56 } {0 1} | |
57 | |
58 # The page-size is stored at offset 16 | |
59 # | |
60 ifcapable pager_pragmas { | |
61 foreach pagesize {512 1024 2048 4096 8192 16384 32768} { | |
62 if {[info exists SQLITE_MAX_PAGE_SIZE] | |
63 && $pagesize>$SQLITE_MAX_PAGE_SIZE} continue | |
64 do_test filefmt-1.5.$pagesize.1 { | |
65 db close | |
66 forcedelete test.db | |
67 sqlite3 db test.db | |
68 db eval "PRAGMA auto_vacuum=OFF" | |
69 db eval "PRAGMA page_size=$pagesize" | |
70 db eval {CREATE TABLE t1(x)} | |
71 file size test.db | |
72 } [expr $pagesize*2] | |
73 do_test filefmt-1.5.$pagesize.2 { | |
74 hexio_get_int [hexio_read test.db 16 2] | |
75 } $pagesize | |
76 } | |
77 } | |
78 | |
79 # The page-size must be a power of 2 | |
80 # | |
81 do_test filefmt-1.6 { | |
82 db close | |
83 hexio_write test.db 16 [hexio_render_int16 1025] | |
84 sqlite3 db test.db | |
85 catchsql { | |
86 SELECT count(*) FROM sqlite_master | |
87 } | |
88 } {1 {file is encrypted or is not a database}} | |
89 | |
90 | |
91 # The page-size must be at least 512 bytes | |
92 # | |
93 do_test filefmt-1.7 { | |
94 db close | |
95 hexio_write test.db 16 [hexio_render_int16 256] | |
96 sqlite3 db test.db | |
97 catchsql { | |
98 SELECT count(*) FROM sqlite_master | |
99 } | |
100 } {1 {file is encrypted or is not a database}} | |
101 | |
102 # Usable space per page (page-size minus unused space per page) | |
103 # must be at least 480 bytes | |
104 # | |
105 ifcapable pager_pragmas { | |
106 do_test filefmt-1.8 { | |
107 db close | |
108 forcedelete test.db | |
109 sqlite3 db test.db | |
110 db eval {PRAGMA page_size=512; CREATE TABLE t1(x)} | |
111 db close | |
112 hexio_write test.db 20 21 | |
113 sqlite3 db test.db | |
114 catchsql { | |
115 SELECT count(*) FROM sqlite_master | |
116 } | |
117 } {1 {file is encrypted or is not a database}} | |
118 } | |
119 | |
120 #------------------------------------------------------------------------- | |
121 # The following block of tests - filefmt-2.* - test that versions 3.7.0 | |
122 # and later can read and write databases that have been modified or created | |
123 # by 3.6.23.1 and earlier. The difference difference is that 3.7.0 stores | |
124 # the size of the database in the database file header, whereas 3.6.23.1 | |
125 # always derives this from the size of the file. | |
126 # | |
127 db close | |
128 forcedelete test.db | |
129 | |
130 set a_string_counter 1 | |
131 proc a_string {n} { | |
132 incr ::a_string_counter | |
133 string range [string repeat "${::a_string_counter}." $n] 1 $n | |
134 } | |
135 sqlite3 db test.db | |
136 db func a_string a_string | |
137 | |
138 do_execsql_test filefmt-2.1.1 { | |
139 PRAGMA page_size = 1024; | |
140 PRAGMA auto_vacuum = 0; | |
141 CREATE TABLE t1(a); | |
142 CREATE INDEX i1 ON t1(a); | |
143 INSERT INTO t1 VALUES(a_string(3000)); | |
144 CREATE TABLE t2(a); | |
145 INSERT INTO t2 VALUES(1); | |
146 } {} | |
147 do_test filefmt-2.1.2 { | |
148 hexio_read test.db 28 4 | |
149 } {00000009} | |
150 | |
151 do_test filefmt-2.1.3 { | |
152 sql36231 { INSERT INTO t1 VALUES(a_string(3000)) } | |
153 } {} | |
154 | |
155 do_execsql_test filefmt-2.1.4 { INSERT INTO t2 VALUES(2) } {} | |
156 integrity_check filefmt-2.1.5 | |
157 do_test filefmt-2.1.6 { hexio_read test.db 28 4 } {00000010} | |
158 | |
159 db close | |
160 forcedelete test.db | |
161 sqlite3 db test.db | |
162 db func a_string a_string | |
163 | |
164 do_execsql_test filefmt-2.2.1 { | |
165 PRAGMA page_size = 1024; | |
166 PRAGMA auto_vacuum = 0; | |
167 CREATE TABLE t1(a); | |
168 CREATE INDEX i1 ON t1(a); | |
169 INSERT INTO t1 VALUES(a_string(3000)); | |
170 CREATE TABLE t2(a); | |
171 INSERT INTO t2 VALUES(1); | |
172 } {} | |
173 do_test filefmt-2.2.2 { | |
174 hexio_read test.db 28 4 | |
175 } {00000009} | |
176 | |
177 do_test filefmt-2.2.3 { | |
178 sql36231 { INSERT INTO t1 VALUES(a_string(3000)) } | |
179 } {} | |
180 | |
181 do_execsql_test filefmt-2.2.4 { | |
182 PRAGMA integrity_check; | |
183 BEGIN; | |
184 INSERT INTO t2 VALUES(2); | |
185 SAVEPOINT a; | |
186 INSERT INTO t2 VALUES(3); | |
187 ROLLBACK TO a; | |
188 } {ok} | |
189 | |
190 integrity_check filefmt-2.2.5 | |
191 do_execsql_test filefmt-2.2.6 { COMMIT } {} | |
192 db close | |
193 sqlite3 db test.db | |
194 integrity_check filefmt-2.2.7 | |
195 | |
196 #-------------------------------------------------------------------------- | |
197 # Check that ticket 89b8c9ac54 is fixed. Before the fix, the SELECT | |
198 # statement would return SQLITE_CORRUPT. The database file was not actually | |
199 # corrupted, but SQLite was reporting that it was. | |
200 # | |
201 db close | |
202 forcedelete test.db | |
203 sqlite3 db test.db | |
204 do_execsql_test filefmt-3.1 { | |
205 PRAGMA auto_vacuum = 1; | |
206 CREATE TABLE t1(a, b); | |
207 } {} | |
208 do_test filefmt-3.2 { | |
209 sql36231 { DROP TABLE t1 } | |
210 } {} | |
211 do_execsql_test filefmt-3.3 { | |
212 SELECT * FROM sqlite_master; | |
213 PRAGMA integrity_check; | |
214 } {ok} | |
215 | |
216 reset_db | |
217 do_execsql_test filefmt-4.1 { | |
218 PRAGMA auto_vacuum = 1; | |
219 CREATE TABLE t1(x, y); | |
220 CREATE TABLE t2(x, y); | |
221 | |
222 INSERT INTO t1 VALUES(randomblob(100), randomblob(100)); | |
223 INSERT INTO t1 VALUES(randomblob(100), randomblob(100)); | |
224 INSERT INTO t1 VALUES(randomblob(100), randomblob(100)); | |
225 INSERT INTO t1 VALUES(randomblob(100), randomblob(100)); | |
226 INSERT INTO t1 VALUES(randomblob(100), randomblob(100)); | |
227 INSERT INTO t1 VALUES(randomblob(100), randomblob(100)); | |
228 | |
229 INSERT INTO t2 SELECT randomblob(100), randomblob(100) FROM t1; | |
230 INSERT INTO t2 SELECT randomblob(100), randomblob(100) FROM t1; | |
231 INSERT INTO t2 SELECT randomblob(100), randomblob(100) FROM t1; | |
232 INSERT INTO t2 SELECT randomblob(100), randomblob(100) FROM t1; | |
233 } | |
234 | |
235 do_test filefmt-4.2 { | |
236 sql36231 { INSERT INTO t2 SELECT * FROM t1 } | |
237 } {} | |
238 | |
239 do_test filefmt-4.3 { | |
240 forcedelete bak.db | |
241 db backup bak.db | |
242 } {} | |
243 | |
244 do_test filefmt-4.4 { | |
245 sqlite3 db2 bak.db | |
246 db2 eval { PRAGMA integrity_check } | |
247 } {ok} | |
248 db2 close | |
249 | |
250 finish_test | |
OLD | NEW |