0
0
mirror of https://github.com/tursodatabase/libsql.git synced 2024-11-23 12:06:16 +00:00
libsql/libsql-sqlite3/test/memdb1.test
2023-10-16 13:58:16 +02:00

271 lines
6.4 KiB
Plaintext

# 2018-01-02
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. The
# focus of this file is the "memdb" VFS
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix memdb1
do_not_use_codec
ifcapable !deserialize {
finish_test
return
}
# Create a MEMDB and populate it with some dummy data.
# Then extract the database into the $::db1 variable.
# Verify that the size of $::db1 is the same as the size of
# the database.
#
unset -nocomplain db1
unset -nocomplain sz1
unset -nocomplain pgsz
do_test 100 {
db eval {
CREATE TABLE t1(a,b);
INSERT INTO t1 VALUES(1,2);
}
set ::pgsz [db one {PRAGMA page_size}]
set ::sz1 [expr {$::pgsz*[db one {PRAGMA page_count}]}]
set ::db1 [db serialize]
expr {[string length $::db1]==$::sz1}
} 1
set fd [open db1.db wb]
puts -nonewline $fd $db1
close $fd
# Create a new MEMDB and initialize it to the content of $::db1
# Verify that the content is the same.
#
db close
sqlite3 db
db deserialize $db1
do_execsql_test 110 {
SELECT * FROM t1;
} {1 2}
# What happens when we try to VACUUM a MEMDB database?
#
do_execsql_test 120 {
PRAGMA auto_vacuum = off;
VACUUM;
} {}
do_execsql_test 130 {
CREATE TABLE t2(x, y);
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100)
INSERT INTO t2(x, y) SELECT x, randomblob(1000) FROM c;
DROP TABLE t2;
PRAGMA page_count;
} {116}
do_execsql_test 140 {
VACUUM;
PRAGMA page_count;
} {2}
do_test 150 {
catch {db deserialize -unknown 1 $db1} msg
set msg
} {unknown option: -unknown}
do_test 151 {
db deserialize -readonly 1 $db1
db eval {SELECT * FROM t1}
} {1 2}
do_test 152 {
catchsql {INSERT INTO t1 VALUES(3,4);}
} {1 {attempt to write a readonly database}}
breakpoint
do_test 160 {
db deserialize -maxsize 32768 $db1
db eval {SELECT * FROM t1}
} {1 2}
do_test 161 {
db eval {INSERT INTO t1 VALUES(3,4); SELECT * FROM t1}
} {1 2 3 4}
do_test 162 {
catchsql {INSERT INTO t1 VALUES(5,randomblob(100000))}
} {1 {database or disk is full}}
# Build a largish on-disk database and serialize it. Verify that the
# serialization works.
#
db close
forcedelete test.db
sqlite3 db test.db
do_execsql_test 200 {
CREATE TABLE t3(x, y);
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<400)
INSERT INTO t3(x, y) SELECT x, randomblob(1000) FROM c;
PRAGMA quick_check;
} {ok}
set fd [open test.db rb]
unset -nocomplain direct
set direct [read $fd]
close $fd
do_test 210 {
string length [db serialize]
} [string length $direct]
do_test 220 {
db eval {ATTACH ':memory:' AS aux1}
db deserialize aux1 $::direct
db eval {
SELECT x, y FROM main.t3 EXCEPT SELECT x, y FROM aux1.t3;
}
} {}
unset -nocomplain direct
# Do the same with a :memory: database.
#
db close
sqlite3 db :memory:
do_execsql_test 300 {
CREATE TABLE t3(x, y);
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<400)
INSERT INTO t3(x, y) SELECT x, randomblob(1000) FROM c;
PRAGMA quick_check;
} {ok}
do_test 310 {
db eval {ATTACH ':memory:' AS aux1}
db deserialize aux1 [db serialize main]
db eval {
SELECT x, y FROM main.t3 EXCEPT SELECT x, y FROM aux1.t3;
}
} {}
# Deserialize an empty database
#
db close
sqlite3 db
db deserialize {}
do_execsql_test 400 {
PRAGMA integrity_check;
} {ok}
do_execsql_test 410 {
CREATE TABLE t4(a,b);
INSERT INTO t4 VALUES('hello','world!');
PRAGMA integrity_check;
SELECT * FROM t4;
} {ok hello world!}
do_execsql_test 420 {
PRAGMA journal_mode=TRUNCATE;
PRAGMA journal_mode=OFF;
PRAGMA journal_mode=DELETE;
PRAGMA journal_mode=WAL;
PRAGMA journal_mode=PERSIST;
PRAGMA journal_mode=MEMORY;
PRAGMA journal_mode=OFF;
PRAGMA journal_mode=DELETE;
} {truncate off delete delete persist memory off delete}
# Deserialize something that is not a database.
#
db close
sqlite3 db
do_test 500 {
set rc [catch {db deserialize not-a-database} msg]
lappend rc $msg
} {0 {}}
do_catchsql_test 510 {
PRAGMA integrity_check;
} {1 {file is not a database}}
# Abuse the serialize and deserialize commands. Make sure errors are caught.
#
do_test 600 {
set rc [catch {db deserialize} msg]
lappend rc $msg
} {1 {wrong # args: should be "db deserialize ?DATABASE? VALUE"}}
do_test 610 {
set rc [catch {db deserialize a b c} msg]
lappend rc $msg
} {1 {unknown option: a}}
do_test 620 {
set rc [catch {db serialize a b} msg]
lappend rc $msg
} {1 {wrong # args: should be "db serialize ?DATABASE?"}}
# 2021-07-19 https://sqlite.org/forum/forumpost/e1cbb5f450b98aa6
# The TEMP database cannot participate in serialization or
# deserialization.
#
reset_db
do_test 650 {
db eval {
CREATE TEMP TABLE t0(a);
CREATE TABLE t1(x);
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<1000)
INSERT INTO t1(x) SELECT random() FROM c;
}
set rc [catch {db deserialize temp [db serialize main]} err]
lappend rc err
} {1 err}
#-------------------------------------------------------------------------
ifcapable vtab {
reset_db
do_execsql_test 700 {
CREATE TABLE t1(a, b);
PRAGMA schema_version = 0;
}
do_test 710 {
set ser [db serialize main]
db close
sqlite3 db
db deserialize main $ser
catchsql {
CREATE VIRTUAL TABLE t1 USING rtree(id, a, b, c, d);
}
} {1 {table t1 already exists}}
}
#-------------------------------------------------------------------------
# dbsqlfuzz 0a13dfb474d4f2f11a48a2ea57075c96fb456dd7
#
if {[wal_is_capable]} {
reset_db
do_execsql_test 800 {
PRAGMA auto_vacuum = 0;
PRAGMA page_size = 8192;
PRAGMA journal_mode = wal;
CREATE TABLE t1(x, y);
INSERT INTO t1 VALUES(1, 2);
CREATE TABLE t2(x, y);
} {wal}
db close
set fd [open test.db]
fconfigure $fd -translation binary -encoding binary
set data [read $fd [expr 20*1024]]
sqlite3 db ""
db deserialize $data
do_execsql_test 810 {
PRAGMA locking_mode = exclusive;
SELECT * FROM t1
} {exclusive 1 2}
do_execsql_test 820 {
INSERT INTO t1 VALUES(3, 4);
SELECT * FROM t1;
} {1 2 3 4}
do_catchsql_test 830 {
PRAGMA wal_checkpoint;
} {1 {database disk image is malformed}}
}
finish_test