1# 2011 March 24
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 the session module. More
12# specifically, it focuses on testing the session modules response to
13# database schema modifications and mismatches.
14#
15
16if {![info exists testdir]} {
17  set testdir [file join [file dirname [info script]] .. .. test]
18}
19source [file join [file dirname [info script]] session_common.tcl]
20source $testdir/tester.tcl
21ifcapable !session {finish_test; return}
22
23set testprefix session3
24
25#-------------------------------------------------------------------------
26# These tests - session3-1.* - verify that the session module behaves
27# correctly when confronted with a schema mismatch when applying a
28# changeset (in function sqlite3changeset_apply()).
29#
30#   session3-1.1.*: Table does not exist in target db.
31#   session3-1.2.*: Table has wrong number of columns in target db.
32#   session3-1.3.*: Table has wrong PK columns in target db.
33#
34db close
35sqlite3_shutdown
36test_sqlite3_log log
37sqlite3 db test.db
38
39proc log {code msg} { lappend ::log $code $msg }
40
41forcedelete test.db2
42sqlite3 db2 test.db2
43
44do_execsql_test 1.0 {
45  CREATE TABLE t1(a PRIMARY KEY, b);
46}
47do_test 1.1 {
48  set ::log {}
49  do_then_apply_sql {
50    INSERT INTO t1 VALUES(1, 2);
51    INSERT INTO t1 VALUES(3, 4);
52  }
53  set ::log
54} {SQLITE_SCHEMA {sqlite3changeset_apply(): no such table: t1}}
55
56do_test 1.2.0 {
57  execsql { CREATE TABLE t1(a PRIMARY KEY, b, c) } db2
58} {}
59do_test 1.2.1 {
60  set ::log {}
61  do_then_apply_sql {
62    INSERT INTO t1 VALUES(5, 6);
63    INSERT INTO t1 VALUES(7, 8);
64  }
65  set ::log
66} {}
67do_test 1.2.2 {
68  db2 eval { SELECT * FROM t1 }
69} {5 6 {} 7 8 {}}
70
71do_test 1.3.0 {
72  execsql {
73    DROP TABLE t1;
74    CREATE TABLE t1(a, b PRIMARY KEY);
75  } db2
76} {}
77do_test 1.3.1 {
78  set ::log {}
79  do_then_apply_sql {
80    INSERT INTO t1 VALUES(9, 10);
81    INSERT INTO t1 VALUES(11, 12);
82  }
83  set ::log
84} {SQLITE_SCHEMA {sqlite3changeset_apply(): primary key mismatch for table t1}}
85
86#-------------------------------------------------------------------------
87# These tests - session3-2.* - verify that the session module behaves
88# correctly when the schema of an attached table is modified during the
89# session.
90#
91#   session3-2.1.*: Table is dropped midway through the session.
92#   session3-2.2.*: Table is dropped and recreated with a different # cols.
93#   session3-2.3.*: Table is dropped and recreated with a different PK.
94#
95# In all of these scenarios, the call to sqlite3session_changeset() will
96# return SQLITE_SCHEMA. Also:
97#
98#   session3-2.4.*: Table is dropped and recreated with an identical schema.
99#                   In this case sqlite3session_changeset() returns SQLITE_OK.
100#
101
102do_test 2.1 {
103  execsql { CREATE TABLE t2(a, b PRIMARY KEY) }
104  sqlite3session S db main
105  S attach t2
106  execsql {
107    INSERT INTO t2 VALUES(1, 2);
108    DROP TABLE t2;
109  }
110  list [catch { S changeset } msg] $msg
111} {1 SQLITE_SCHEMA}
112
113do_test 2.2.1 {
114  S delete
115  sqlite3session S db main
116  execsql { CREATE TABLE t2(a, b PRIMARY KEY, c) }
117  S attach t2
118  execsql {
119    INSERT INTO t2 VALUES(1, 2, 3);
120    DROP TABLE t2;
121    CREATE TABLE t2(a, b PRIMARY KEY);
122  }
123  list [catch { S changeset } msg] $msg
124} {1 SQLITE_SCHEMA}
125do_test 2.2.2 {
126  S delete
127  sqlite3session S db main
128  execsql {
129    DROP TABLE t2;
130    CREATE TABLE t2(a, b PRIMARY KEY, c);
131  }
132  S attach t2
133  execsql {
134    INSERT INTO t2 VALUES(1, 2, 3);
135    DROP TABLE t2;
136    CREATE TABLE t2(a, b PRIMARY KEY, c, d);
137  }
138  list [catch { S changeset } msg] $msg
139} {1 SQLITE_SCHEMA}
140do_test 2.2.3 {
141  S delete
142  sqlite3session S db main
143  execsql {
144    DROP TABLE t2;
145    CREATE TABLE t2(a, b PRIMARY KEY, c);
146  }
147  S attach t2
148  execsql {
149    INSERT INTO t2 VALUES(1, 2, 3);
150    DROP TABLE t2;
151    CREATE TABLE t2(a, b PRIMARY KEY);
152    INSERT INTO t2 VALUES(4, 5);
153  }
154  list [catch { S changeset } msg] $msg
155} {1 SQLITE_SCHEMA}
156do_test 2.2.4 {
157  S delete
158  sqlite3session S db main
159  execsql {
160    DROP TABLE t2;
161    CREATE TABLE t2(a, b PRIMARY KEY, c);
162  }
163  S attach t2
164  execsql {
165    INSERT INTO t2 VALUES(1, 2, 3);
166    DROP TABLE t2;
167    CREATE TABLE t2(a, b PRIMARY KEY, c, d);
168    INSERT INTO t2 VALUES(4, 5, 6, 7);
169  }
170  list [catch { S changeset } msg] $msg
171} {1 SQLITE_SCHEMA}
172
173do_test 2.3 {
174  S delete
175  sqlite3session S db main
176  execsql {
177    DROP TABLE t2;
178    CREATE TABLE t2(a, b PRIMARY KEY);
179  }
180  S attach t2
181  execsql {
182    INSERT INTO t2 VALUES(1, 2);
183    DROP TABLE t2;
184    CREATE TABLE t2(a PRIMARY KEY, b);
185  }
186  list [catch { S changeset } msg] $msg
187} {1 SQLITE_SCHEMA}
188
189do_test 2.4 {
190  S delete
191  sqlite3session S db main
192  execsql {
193    DROP TABLE t2;
194    CREATE TABLE t2(a, b PRIMARY KEY);
195  }
196  S attach t2
197  execsql {
198    INSERT INTO t2 VALUES(1, 2);
199    DROP TABLE t2;
200    CREATE TABLE t2(a, b PRIMARY KEY);
201  }
202  list [catch { S changeset } msg] $msg
203} {0 {}}
204
205S delete
206
207
208catch { db close }
209catch { db2 close }
210sqlite3_shutdown
211test_sqlite3_log
212sqlite3_initialize
213
214finish_test
215