Files
sqlite/ext/session/session2.test
T
dan d7fb7d24c6 Fix a problem involving session objects and attached databases.
FossilOrigin-Name: ad91d30073a8faa7eb064dd2e1cc4d2297d7b3f8
2011-03-19 19:19:26 +00:00

268 lines
7.2 KiB
Plaintext

# 2011 Mar 16
#
# 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.
#
#***********************************************************************
#
# The focus of this file is testing the session module.
#
if {![info exists testdir]} {
set testdir [file join [file dirname [info script]] .. .. test]
}
source [file join [file dirname [info script]] session_common.tcl]
source $testdir/tester.tcl
set testprefix session2
proc test_reset {} {
catch { db close }
catch { db2 close }
forcedelete test.db test.db2
sqlite3 db test.db
sqlite3 db2 test.db2
}
proc do_common_sql {sql} {
execsql $sql db
execsql $sql db2
}
proc xConflict args { return "OMIT" }
proc do_then_apply_sql {sql {dbname main}} {
sqlite3session S db $dbname
db eval "SELECT name FROM $dbname.sqlite_master WHERE type = 'table'" {
S attach $name
}
db eval $sql
sqlite3changeset_apply db2 [S changeset] xConflict
S delete
}
proc do_iterator_test {tn tbl_list sql res} {
sqlite3session S db main
foreach t $tbl_list {S attach $t}
execsql $sql
set r [list]
foreach v $res { lappend r $v }
set x [list]
sqlite3session_foreach c [S changeset] { lappend x $c }
uplevel do_test $tn [list [list set {} $x]] [list $r]
S delete
}
# Compare the contents of all tables in [db1] and [db2]. Throw an error if
# they are not identical, or return an empty string if they are.
#
proc compare_db {db1 db2} {
set sql {SELECT name FROM sqlite_master WHERE type = 'table' ORDER BY name}
set lot1 [$db1 eval $sql]
set lot2 [$db2 eval $sql]
if {$lot1 != $lot2} { error "databases contain different tables" }
foreach tbl $lot1 {
set col1 [list]
set col2 [list]
$db1 eval "PRAGMA table_info = $tbl" { lappend col1 $name }
$db2 eval "PRAGMA table_info = $tbl" { lappend col2 $name }
if {$col1 != $col2} { error "table $tbl schema mismatch" }
set sql "SELECT * FROM $tbl ORDER BY [join $col1 ,]"
set data1 [$db1 eval $sql]
set data2 [$db2 eval $sql]
if {$data1 != $data2} { error "table $tbl data mismatch" }
}
return ""
}
##########################################################################
# End of proc definitions. Start of tests.
##########################################################################
test_reset
do_execsql_test 1.0 {
CREATE TABLE t1(a PRIMARY KEY, b);
INSERT INTO t1 VALUES('i', 'one');
}
do_iterator_test 1.1 t1 {
DELETE FROM t1 WHERE a = 'i';
INSERT INTO t1 VALUES('ii', 'two');
} {
{DELETE t1 {t i t one} {}}
{INSERT t1 {} {t ii t two}}
}
test_reset
do_common_sql {
CREATE TABLE t1(a PRIMARY KEY, b);
CREATE TABLE t2(a, b INTEGER PRIMARY KEY);
CREATE TABLE t3(a, b, c, PRIMARY KEY(a, b));
}
# Execute each of the following blocks of SQL on database [db1]. Collect
# changes using a session object. Apply the resulting changeset to
# database [db2]. Then check that the contents of the two databases are
# identical.
#
foreach {tn sql} {
1 { INSERT INTO t1 VALUES(1, 2) }
2 {
INSERT INTO t2 VALUES(1, NULL);
INSERT INTO t2 VALUES(2, NULL);
INSERT INTO t2 VALUES(3, NULL);
DELETE FROM t2 WHERE a = 2;
INSERT INTO t2 VALUES(4, NULL);
UPDATE t2 SET b=0 WHERE b=1;
}
3 { INSERT INTO t3 SELECT *, NULL FROM t2 }
4 {
INSERT INTO t3 SELECT a||a, b||b, NULL FROM t3;
DELETE FROM t3 WHERE rowid%2;
}
5 { UPDATE t3 SET c = a||b }
6 { UPDATE t1 SET a = 32 }
7 {
INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 2
INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 4
INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 8
INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 16
INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 32
INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 64
INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 128
INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 256
INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 512
INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 1024
INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 2048
DELETE FROM t1 WHERE (rowid%3)==0;
}
8 {
BEGIN;
INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1;
ROLLBACK;
}
9 {
BEGIN;
UPDATE t1 SET b = 'xxx';
ROLLBACK;
}
10 {
BEGIN;
DELETE FROM t1 WHERE 1;
ROLLBACK;
}
} {
do_then_apply_sql $sql
do_test 1.$tn { compare_db db db2 } {}
}
# The following block of tests is similar to the last, except that the
# session object is recording changes made to an attached database. The
# main database contains a table of the same name as the table being
# modified within the attached db.
#
test_reset
forcedelete test.db3
sqlite3 db3 test.db3
do_test 2.0 {
execsql {
ATTACH 'test.db3' AS 'aux';
CREATE TABLE t1(a, b PRIMARY KEY);
CREATE TABLE t2(x, y, z);
CREATE TABLE t3(a);
CREATE TABLE aux.t1(a PRIMARY KEY, b);
CREATE TABLE aux.t2(a, b INTEGER PRIMARY KEY);
CREATE TABLE aux.t3(a, b, c, PRIMARY KEY(a, b));
}
execsql {
CREATE TABLE t1(a PRIMARY KEY, b);
CREATE TABLE t2(a, b INTEGER PRIMARY KEY);
CREATE TABLE t3(a, b, c, PRIMARY KEY(a, b));
} db2
} {}
foreach {tn sql} {
1 { INSERT INTO aux.t1 VALUES(1, 2) }
2 {
INSERT INTO aux.t2 VALUES(1, NULL);
INSERT INTO aux.t2 VALUES(2, NULL);
INSERT INTO aux.t2 VALUES(3, NULL);
DELETE FROM aux.t2 WHERE a = 2;
INSERT INTO aux.t2 VALUES(4, NULL);
UPDATE aux.t2 SET b=0 WHERE b=1;
}
3 { INSERT INTO aux.t3 SELECT *, NULL FROM aux.t2 }
4 {
INSERT INTO aux.t3 SELECT a||a, b||b, NULL FROM aux.t3;
DELETE FROM aux.t3 WHERE rowid%2;
}
5 { UPDATE aux.t3 SET c = a||b }
6 { UPDATE aux.t1 SET a = 32 }
7 {
INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1;
INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1;
INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1;
INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1;
INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1;
INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1;
INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1;
INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1;
INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1;
INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1;
INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1;
DELETE FROM aux.t1 WHERE (rowid%3)==0;
}
8 {
BEGIN;
INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1;
ROLLBACK;
}
9 {
BEGIN;
UPDATE aux.t1 SET b = 'xxx';
ROLLBACK;
}
10 {
BEGIN;
DELETE FROM aux.t1 WHERE 1;
ROLLBACK;
}
} {
do_then_apply_sql $sql aux
do_test 2.$tn { compare_db db3 db2 } {}
}
catch {db3 close}
finish_test