version bump to 4.6.1
[sqlcipher.git] / test / memdb1.test
blob3a31c8e2845a9029f1d5acf419042bf8e7a1ca81
1 # 2018-01-02
3 # The author disclaims copyright to this source code.  In place of
4 # a legal notice, here is a blessing:
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.
10 #***********************************************************************
11 # This file implements regression tests for SQLite library.  The
12 # focus of this file is the "memdb" VFS
15 set testdir [file dirname $argv0]
16 source $testdir/tester.tcl
17 set testprefix memdb1
18 do_not_use_codec
20 ifcapable !deserialize {
21   finish_test
22   return
25 # Create a MEMDB and populate it with some dummy data.
26 # Then extract the database into the $::db1 variable.
27 # Verify that the size of $::db1 is the same as the size of
28 # the database.
30 unset -nocomplain db1
31 unset -nocomplain sz1
32 unset -nocomplain pgsz
33 do_test 100 {
34   db eval {
35     CREATE TABLE t1(a,b);
36     INSERT INTO t1 VALUES(1,2);
37   }
38   set ::pgsz [db one {PRAGMA page_size}]
39   set ::sz1 [expr {$::pgsz*[db one {PRAGMA page_count}]}]
40   set ::db1 [db serialize]
41   expr {[string length $::db1]==$::sz1}
42 } 1
43 set fd [open db1.db wb]
44 puts -nonewline $fd $db1
45 close $fd
47 # Create a new MEMDB and initialize it to the content of $::db1
48 # Verify that the content is the same.
50 db close
51 sqlite3 db
52 db deserialize $db1
53 do_execsql_test 110 {
54   SELECT * FROM t1;
55 } {1 2}
57 # What happens when we try to VACUUM a MEMDB database?
59 do_execsql_test 120 {
60   PRAGMA auto_vacuum = off;
61   VACUUM;
62 } {}
63 do_execsql_test 130 {
64   CREATE TABLE t2(x, y);
65   WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100)
66    INSERT INTO t2(x, y) SELECT x, randomblob(1000) FROM c;
67   DROP TABLE t2;
68   PRAGMA page_count;
69 } {116}
70 do_execsql_test 140 {
71   VACUUM;
72   PRAGMA page_count;
73 } {2}
75 do_test 150 {
76   catch {db deserialize -unknown 1 $db1} msg
77   set msg
78 } {unknown option: -unknown}
79 do_test 151 {
80   db deserialize -readonly 1 $db1
81   db eval {SELECT * FROM t1}
82 } {1 2}
83 do_test 152 {
84   catchsql {INSERT INTO t1 VALUES(3,4);}
85 } {1 {attempt to write a readonly database}}
87 do_test 160 {
88   db deserialize -maxsize 32768 $db1
89   db eval {SELECT * FROM t1}
90 } {1 2}
91 do_test 161 {
92   db eval {INSERT INTO t1 VALUES(3,4); SELECT * FROM t1}
93 } {1 2 3 4}
94 do_test 162 {
95   catchsql {INSERT INTO t1 VALUES(5,randomblob(100000))}
96 } {1 {database or disk is full}}
99 # Build a largish on-disk database and serialize it.  Verify that the
100 # serialization works.
102 db close
103 forcedelete test.db
104 sqlite3 db test.db
105 do_execsql_test 200 {
106   CREATE TABLE t3(x, y);
107   WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<400)
108    INSERT INTO t3(x, y) SELECT x, randomblob(1000) FROM c;
109   PRAGMA quick_check;
110 } {ok}
111 set fd [open test.db rb]
112 unset -nocomplain direct
113 set direct [read $fd]
114 close $fd
115 do_test 210 {
116   string length [db serialize]
117 } [string length $direct]
118 do_test 220 {
119   db eval {ATTACH ':memory:' AS aux1}
120   db deserialize aux1 $::direct
121   db eval {
122      SELECT x, y FROM main.t3 EXCEPT SELECT x, y FROM aux1.t3;
123   }
124 } {}
125 unset -nocomplain direct
127 # Do the same with a :memory: database.
129 db close
130 sqlite3 db :memory:
131 do_execsql_test 300 {
132   CREATE TABLE t3(x, y);
133   WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<400)
134    INSERT INTO t3(x, y) SELECT x, randomblob(1000) FROM c;
135   PRAGMA quick_check;
136 } {ok}
137 do_test 310 {
138   db eval {ATTACH ':memory:' AS aux1}
139   db deserialize aux1 [db serialize main]
140   db eval {
141      SELECT x, y FROM main.t3 EXCEPT SELECT x, y FROM aux1.t3;
142   }
143 } {}
145 # Deserialize an empty database
147 db close
148 sqlite3 db
149 db deserialize {}
150 do_execsql_test 400 {
151   PRAGMA integrity_check;
152 } {ok}
153 do_execsql_test 410 {
154   CREATE TABLE t4(a,b);
155   INSERT INTO t4 VALUES('hello','world!');
156   PRAGMA integrity_check;
157   SELECT * FROM t4;
158 } {ok hello world!}
159 do_execsql_test 420 {
160   PRAGMA journal_mode=TRUNCATE;
161   PRAGMA journal_mode=OFF;
162   PRAGMA journal_mode=DELETE;
163   PRAGMA journal_mode=WAL;
164   PRAGMA journal_mode=PERSIST;
165   PRAGMA journal_mode=MEMORY;
166   PRAGMA journal_mode=OFF;
167   PRAGMA journal_mode=DELETE;
168 } {truncate off delete delete persist memory off delete}
170 # Deserialize something that is not a database.
172 db close
173 sqlite3 db
174 do_test 500 {
175   set rc [catch {db deserialize not-a-database} msg]
176   lappend rc $msg
177 } {0 {}}
178 do_catchsql_test 510 {
179   PRAGMA integrity_check;
180 } {1 {file is not a database}}
182 # Abuse the serialize and deserialize commands.  Make sure errors are caught.
184 do_test 600 {
185   set rc [catch {db deserialize} msg]
186   lappend rc $msg
187 } {1 {wrong # args: should be "db deserialize ?DATABASE? VALUE"}}
188 do_test 610 {
189   set rc [catch {db deserialize a b c} msg]
190   lappend rc $msg
191 } {1 {unknown option: a}}
192 do_test 620 {
193   set rc [catch {db serialize a b} msg]
194   lappend rc $msg
195 } {1 {wrong # args: should be "db serialize ?DATABASE?"}}
197 # 2021-07-19 https://sqlite.org/forum/forumpost/e1cbb5f450b98aa6
198 # The TEMP database cannot participate in serialization or
199 # deserialization.
201 reset_db
202 do_test 650 {
203   db eval {
204     CREATE TEMP TABLE t0(a);
205     CREATE TABLE t1(x);
206     WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<1000)
207     INSERT INTO t1(x) SELECT random() FROM c;
208   }
209   set rc [catch {db deserialize temp [db serialize main]} err]
210   lappend rc err
211 } {1 err}
213 #-------------------------------------------------------------------------
214 ifcapable vtab {
215   reset_db
216   do_execsql_test 700 {
217     CREATE TABLE t1(a, b);
218     PRAGMA schema_version = 0;
219   }
220   do_test 710 {
221     set ser [db serialize main]
222     db close
223     sqlite3 db
224     db deserialize main $ser
225     catchsql {
226       CREATE VIRTUAL TABLE t1 USING rtree(id, a, b, c, d);
227     }
228   } {1 {table t1 already exists}}
232 #-------------------------------------------------------------------------
233 # dbsqlfuzz  0a13dfb474d4f2f11a48a2ea57075c96fb456dd7
235 if {[wal_is_capable]} {
236   reset_db
237   do_execsql_test 800 {
238     PRAGMA auto_vacuum = 0;
239     PRAGMA page_size = 8192;
240     PRAGMA journal_mode = wal;
241     CREATE TABLE t1(x, y);
242     INSERT INTO t1 VALUES(1, 2);
243     CREATE TABLE t2(x, y);
244   } {wal}
245   db close
246   
247   set fd [open test.db]
248   fconfigure $fd -translation binary -encoding binary
249   set data [read $fd [expr 20*1024]]
250   close $fd
251   
252   sqlite3 db ""
253   db deserialize $data
254   
255   do_execsql_test 810 {
256     PRAGMA locking_mode = exclusive;
257     SELECT * FROM t1
258   } {exclusive 1 2}
259   
260   do_execsql_test 820 {
261     INSERT INTO t1 VALUES(3, 4);
262     SELECT * FROM t1;
263   } {1 2 3 4}
264   
265   do_catchsql_test 830 {
266     PRAGMA wal_checkpoint;
267   } {1 {database disk image is malformed}}
270 # 2024-01-20
271 # https://sqlite.org/forum/forumpost/498777780e16880a
273 # Make sure a database is initialized before serializing it.
275 reset_db
276 sqlite3 dbempty :memory:
277 do_test 900 {
278   set len [string length [dbempty serialize]]
279   expr {$len>0}
280 } 1
281 dbempty close
283 finish_test