Annotation of embedaddon/sqlite3/test/vtab7.test, revision 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>