Annotation of embedaddon/sqlite3/test/vtab7.test, revision 1.1.1.1
1.1 misho 1: # 2006 July 25
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 SQLite library. The focus
12: # of this test is reading and writing to the database from within a
13: # virtual table xSync() callback.
14: #
15: # $Id: vtab7.test,v 1.4 2007/12/04 16:54:53 drh Exp $
16:
17: set testdir [file dirname $argv0]
18: source $testdir/tester.tcl
19:
20: ifcapable !vtab {
21: finish_test
22: return
23: }
24:
25: # Register the echo module. Code inside the echo module appends elements
26: # to the global tcl list variable ::echo_module whenever SQLite invokes
27: # certain module callbacks. This includes the xSync(), xCommit() and
28: # xRollback() callbacks. For each of these callback, two elements are
29: # appended to ::echo_module, as follows:
30: #
31: # Module method Elements appended to ::echo_module
32: # -------------------------------------------------------
33: # xSync() xSync echo($tablename)
34: # xCommit() xCommit echo($tablename)
35: # xRollback() xRollback echo($tablename)
36: # -------------------------------------------------------
37: #
38: # In each case, $tablename is replaced by the name of the real table (not
39: # the echo table). By setting up a tcl trace on the ::echo_module variable,
40: # code in this file arranges for a Tcl script to be executed from within
41: # the echo module xSync() callback.
42: #
43: register_echo_module [sqlite3_connection_pointer db]
44: trace add variable ::echo_module write echo_module_trace
45:
46: # This Tcl proc is invoked whenever the ::echo_module variable is written.
47: #
48: proc echo_module_trace {args} {
49: # Filter out writes to ::echo_module that are not xSync, xCommit or
50: # xRollback callbacks.
51: if {[llength $::echo_module] < 2} return
52: set x [lindex $::echo_module end-1]
53: if {$x ne "xSync" && $x ne "xCommit" && $x ne "xRollback"} return
54:
55: regexp {^echo.(.*).$} [lindex $::echo_module end] dummy tablename
56: # puts "Ladies and gentlemen, an $x on $tablename!"
57:
58: if {[info exists ::callbacks($x,$tablename)]} {
59: eval $::callbacks($x,$tablename)
60: }
61: }
62:
63: # The following tests, vtab7-1.*, test that the trace callback on
64: # ::echo_module is providing the expected tcl callbacks.
65: do_test vtab7-1.1 {
66: execsql {
67: CREATE TABLE abc(a, b, c);
68: CREATE VIRTUAL TABLE abc2 USING echo(abc);
69: }
70: } {}
71:
72: do_test vtab7-1.2 {
73: set ::callbacks(xSync,abc) {incr ::counter}
74: set ::counter 0
75: execsql {
76: INSERT INTO abc2 VALUES(1, 2, 3);
77: }
78: set ::counter
79: } {1}
80:
81: # Write to an existing database table from within an xSync callback.
82: do_test vtab7-2.1 {
83: set ::callbacks(xSync,abc) {
84: execsql {INSERT INTO log VALUES('xSync');}
85: }
86: execsql {
87: CREATE TABLE log(msg);
88: INSERT INTO abc2 VALUES(4, 5, 6);
89: SELECT * FROM log;
90: }
91: } {xSync}
92: do_test vtab7-2.3 {
93: execsql {
94: INSERT INTO abc2 VALUES(4, 5, 6);
95: SELECT * FROM log;
96: }
97: } {xSync xSync}
98: do_test vtab7-2.4 {
99: execsql {
100: INSERT INTO abc2 VALUES(4, 5, 6);
101: SELECT * FROM log;
102: }
103: } {xSync xSync xSync}
104:
105: # Create a database table from within xSync callback.
106: do_test vtab7-2.5 {
107: set ::callbacks(xSync,abc) {
108: execsql { CREATE TABLE newtab(d, e, f); }
109: }
110: execsql {
111: INSERT INTO abc2 VALUES(1, 2, 3);
112: SELECT name FROM sqlite_master ORDER BY name;
113: }
114: } {abc abc2 log newtab}
115:
116: # Drop a database table from within xSync callback.
117: # This is not allowed. Tables cannot be dropped while
118: # any other statement is active.
119: #
120: do_test vtab7-2.6 {
121: set ::callbacks(xSync,abc) {
122: set ::rc [catchsql { DROP TABLE newtab }]
123: }
124: execsql {
125: INSERT INTO abc2 VALUES(1, 2, 3);
126: SELECT name FROM sqlite_master ORDER BY name;
127: }
128: } {abc abc2 log newtab}
129: do_test vtab7-2.6.1 {
130: set ::rc
131: } {1 {database table is locked}}
132: execsql {DROP TABLE newtab}
133:
134: # Write to an attached database from xSync().
135: ifcapable attach {
136: do_test vtab7-3.1 {
137: forcedelete test2.db
138: forcedelete test2.db-journal
139: execsql {
140: ATTACH 'test2.db' AS db2;
141: CREATE TABLE db2.stuff(description, shape, color);
142: }
143: set ::callbacks(xSync,abc) {
144: execsql { INSERT INTO db2.stuff VALUES('abc', 'square', 'green'); }
145: }
146: execsql {
147: INSERT INTO abc2 VALUES(1, 2, 3);
148: SELECT * from stuff;
149: }
150: } {abc square green}
151: }
152:
153: # UPDATE: The next test passes, but leaks memory. So leave it out.
154: #
155: # The following tests test that writing to the database from within
156: # the xCommit callback causes a misuse error.
157: # do_test vtab7-4.1 {
158: # unset -nocomplain ::callbacks(xSync,abc)
159: # set ::callbacks(xCommit,abc) {
160: # execsql { INSERT INTO log VALUES('hello') }
161: # }
162: # catchsql {
163: # INSERT INTO abc2 VALUES(1, 2, 3);
164: # }
165: # } {1 {library routine called out of sequence}}
166:
167: # These tests, vtab7-4.*, test that an SQLITE_LOCKED error is returned
168: # if an attempt to write to a virtual module table or create a new
169: # virtual table from within an xSync() callback.
170: do_test vtab7-4.1 {
171: execsql {
172: CREATE TABLE def(d, e, f);
173: CREATE VIRTUAL TABLE def2 USING echo(def);
174: }
175: set ::callbacks(xSync,abc) {
176: set ::error [catchsql { INSERT INTO def2 VALUES(1, 2, 3) }]
177: }
178: execsql {
179: INSERT INTO abc2 VALUES(1, 2, 3);
180: }
181: set ::error
182: } {1 {database table is locked}}
183: do_test vtab7-4.2 {
184: set ::callbacks(xSync,abc) {
185: set ::error [catchsql { CREATE VIRTUAL TABLE def3 USING echo(def) }]
186: }
187: execsql {
188: INSERT INTO abc2 VALUES(1, 2, 3);
189: }
190: set ::error
191: } {1 {database table is locked}}
192:
193: do_test vtab7-4.3 {
194: set ::callbacks(xSync,abc) {
195: set ::error [catchsql { DROP TABLE def2 }]
196: }
197: execsql {
198: INSERT INTO abc2 VALUES(1, 2, 3);
199: SELECT name FROM sqlite_master ORDER BY name;
200: }
201: set ::error
202: } {1 {database table is locked}}
203:
204: trace remove variable ::echo_module write echo_module_trace
205: unset -nocomplain ::callbacks
206:
207: finish_test
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>