AryaWu/sqlite
0
1# 2018-01-022#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# This file implements regression tests for SQLite library. The12# focus of this file is the "memdb" VFS13#14 15set testdir [file dirname $argv0]16source $testdir/tester.tcl17set testprefix memdb118do_not_use_codec19 20ifcapable !deserialize {21 finish_test22 return23}24 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 of28# the database.29#30unset -nocomplain db131unset -nocomplain sz132unset -nocomplain pgsz33do_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} 143set fd [open db1.db wb]44puts -nonewline $fd $db145close $fd46 47# Create a new MEMDB and initialize it to the content of $::db148# Verify that the content is the same.49#50db close51sqlite3 db52db deserialize $db153do_execsql_test 110 {54 SELECT * FROM t1;55} {1 2}56 57# What happens when we try to VACUUM a MEMDB database?58#59do_execsql_test 120 {60 PRAGMA auto_vacuum = off;61 VACUUM;62} {}63do_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}70do_execsql_test 140 {71 VACUUM;72 PRAGMA page_count;73} {2}74 75do_test 150 {76 catch {db deserialize -unknown 1 $db1} msg77 set msg78} {unknown option: -unknown}79do_test 151 {80 db deserialize -readonly 1 $db181 db eval {SELECT * FROM t1}82} {1 2}83do_test 152 {84 catchsql {INSERT INTO t1 VALUES(3,4);}85} {1 {attempt to write a readonly database}}86 87do_test 160 {88 db deserialize -maxsize 32768 $db189 db eval {SELECT * FROM t1}90} {1 2}91do_test 161 {92 db eval {INSERT INTO t1 VALUES(3,4); SELECT * FROM t1}93} {1 2 3 4}94do_test 162 {95 catchsql {INSERT INTO t1 VALUES(5,randomblob(100000))}96} {1 {database or disk is full}}97 98 99# Build a largish on-disk database and serialize it. Verify that the100# serialization works.101#102db close103forcedelete test.db104sqlite3 db test.db105do_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}111set fd [open test.db rb]112unset -nocomplain direct113set direct [read $fd]114close $fd115do_test 210 {116 string length [db serialize]117} [string length $direct]118do_test 220 {119 db eval {ATTACH ':memory:' AS aux1}120 db deserialize aux1 $::direct121 db eval {122 SELECT x, y FROM main.t3 EXCEPT SELECT x, y FROM aux1.t3;123 }124} {}125unset -nocomplain direct126 127# Do the same with a :memory: database.128#129db close130sqlite3 db :memory:131do_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}137do_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} {}144 145# Deserialize an empty database146#147db close148sqlite3 db149db deserialize {}150do_execsql_test 400 {151 PRAGMA integrity_check;152} {ok}153do_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!}159do_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}169 170# Deserialize something that is not a database.171#172db close173sqlite3 db174do_test 500 {175 set rc [catch {db deserialize not-a-database} msg]176 lappend rc $msg177} {0 {}}178do_catchsql_test 510 {179 PRAGMA integrity_check;180} {1 {file is not a database}}181 182# Abuse the serialize and deserialize commands. Make sure errors are caught.183#184do_test 600 {185 set rc [catch {db deserialize} msg]186 lappend rc $msg187} {1 {wrong # args: should be "db deserialize ?DATABASE? VALUE"}}188do_test 610 {189 set rc [catch {db deserialize a b c} msg]190 lappend rc $msg191} {1 {unknown option: a}}192do_test 620 {193 set rc [catch {db serialize a b} msg]194 lappend rc $msg195} {1 {wrong # args: should be "db serialize ?DATABASE?"}}196 197# 2021-07-19 https://sqlite.org/forum/forumpost/e1cbb5f450b98aa6198# The TEMP database cannot participate in serialization or199# deserialization.200#201reset_db202do_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 err211} {1 err}212 213#-------------------------------------------------------------------------214ifcapable vtab {215 reset_db216 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 close223 sqlite3 db224 db deserialize main $ser225 catchsql {226 CREATE VIRTUAL TABLE t1 USING rtree(id, a, b, c, d);227 }228 } {1 {table t1 already exists}}229}230 231 232#-------------------------------------------------------------------------233# dbsqlfuzz 0a13dfb474d4f2f11a48a2ea57075c96fb456dd7234#235if {[wal_is_capable]} {236 reset_db237 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 close246 247 set fd [open test.db]248 fconfigure $fd -translation binary249 set data [read $fd [expr 20*1024]]250 close $fd251 252 sqlite3 db ""253 db deserialize $data254 255 do_execsql_test 810 {256 PRAGMA locking_mode = exclusive;257 SELECT * FROM t1258 } {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}}268}269 270# 2024-01-20271# https://sqlite.org/forum/forumpost/498777780e16880a272#273# Make sure a database is initialized before serializing it.274#275reset_db276sqlite3 dbempty :memory:277do_test 900 {278 set len [string length [dbempty serialize]]279 expr {$len>0}280} 1281dbempty close282 283finish_test284 