1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/sqlite3api/TEST/TclScript/vtab7.test Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,207 @@
1.4 +# 2006 July 25
1.5 +#
1.6 +# The author disclaims copyright to this source code. In place of
1.7 +# a legal notice, here is a blessing:
1.8 +#
1.9 +# May you do good and not evil.
1.10 +# May you find forgiveness for yourself and forgive others.
1.11 +# May you share freely, never taking more than you give.
1.12 +#
1.13 +#***********************************************************************
1.14 +# This file implements regression tests for SQLite library. The focus
1.15 +# of this test is reading and writing to the database from within a
1.16 +# virtual table xSync() callback.
1.17 +#
1.18 +# $Id: vtab7.test,v 1.4 2007/12/04 16:54:53 drh Exp $
1.19 +
1.20 +set testdir [file dirname $argv0]
1.21 +source $testdir/tester.tcl
1.22 +
1.23 +ifcapable !vtab {
1.24 + finish_test
1.25 + return
1.26 +}
1.27 +
1.28 +# Register the echo module. Code inside the echo module appends elements
1.29 +# to the global tcl list variable ::echo_module whenever SQLite invokes
1.30 +# certain module callbacks. This includes the xSync(), xCommit() and
1.31 +# xRollback() callbacks. For each of these callback, two elements are
1.32 +# appended to ::echo_module, as follows:
1.33 +#
1.34 +# Module method Elements appended to ::echo_module
1.35 +# -------------------------------------------------------
1.36 +# xSync() xSync echo($tablename)
1.37 +# xCommit() xCommit echo($tablename)
1.38 +# xRollback() xRollback echo($tablename)
1.39 +# -------------------------------------------------------
1.40 +#
1.41 +# In each case, $tablename is replaced by the name of the real table (not
1.42 +# the echo table). By setting up a tcl trace on the ::echo_module variable,
1.43 +# code in this file arranges for a Tcl script to be executed from within
1.44 +# the echo module xSync() callback.
1.45 +#
1.46 +register_echo_module [sqlite3_connection_pointer db]
1.47 +trace add variable ::echo_module write echo_module_trace
1.48 +
1.49 +# This Tcl proc is invoked whenever the ::echo_module variable is written.
1.50 +#
1.51 +proc echo_module_trace {args} {
1.52 + # Filter out writes to ::echo_module that are not xSync, xCommit or
1.53 + # xRollback callbacks.
1.54 + if {[llength $::echo_module] < 2} return
1.55 + set x [lindex $::echo_module end-1]
1.56 + if {$x ne "xSync" && $x ne "xCommit" && $x ne "xRollback"} return
1.57 +
1.58 + regexp {^echo.(.*).$} [lindex $::echo_module end] dummy tablename
1.59 + # puts "Ladies and gentlemen, an $x on $tablename!"
1.60 +
1.61 + if {[info exists ::callbacks($x,$tablename)]} {
1.62 + eval $::callbacks($x,$tablename)
1.63 + }
1.64 +}
1.65 +
1.66 +# The following tests, vtab7-1.*, test that the trace callback on
1.67 +# ::echo_module is providing the expected tcl callbacks.
1.68 +do_test vtab7-1.1 {
1.69 + execsql {
1.70 + CREATE TABLE abc(a, b, c);
1.71 + CREATE VIRTUAL TABLE abc2 USING echo(abc);
1.72 + }
1.73 +} {}
1.74 +
1.75 +do_test vtab7-1.2 {
1.76 + set ::callbacks(xSync,abc) {incr ::counter}
1.77 + set ::counter 0
1.78 + execsql {
1.79 + INSERT INTO abc2 VALUES(1, 2, 3);
1.80 + }
1.81 + set ::counter
1.82 +} {1}
1.83 +
1.84 +# Write to an existing database table from within an xSync callback.
1.85 +do_test vtab7-2.1 {
1.86 + set ::callbacks(xSync,abc) {
1.87 + execsql {INSERT INTO log VALUES('xSync');}
1.88 + }
1.89 + execsql {
1.90 + CREATE TABLE log(msg);
1.91 + INSERT INTO abc2 VALUES(4, 5, 6);
1.92 + SELECT * FROM log;
1.93 + }
1.94 +} {xSync}
1.95 +do_test vtab7-2.3 {
1.96 + execsql {
1.97 + INSERT INTO abc2 VALUES(4, 5, 6);
1.98 + SELECT * FROM log;
1.99 + }
1.100 +} {xSync xSync}
1.101 +do_test vtab7-2.4 {
1.102 + execsql {
1.103 + INSERT INTO abc2 VALUES(4, 5, 6);
1.104 + SELECT * FROM log;
1.105 + }
1.106 +} {xSync xSync xSync}
1.107 +
1.108 +# Create a database table from within xSync callback.
1.109 +do_test vtab7-2.5 {
1.110 + set ::callbacks(xSync,abc) {
1.111 + execsql { CREATE TABLE newtab(d, e, f); }
1.112 + }
1.113 + execsql {
1.114 + INSERT INTO abc2 VALUES(1, 2, 3);
1.115 + SELECT name FROM sqlite_master ORDER BY name;
1.116 + }
1.117 +} {abc abc2 log newtab}
1.118 +
1.119 +# Drop a database table from within xSync callback.
1.120 +# This is not allowed. Tables cannot be dropped while
1.121 +# any other statement is active.
1.122 +#
1.123 +do_test vtab7-2.6 {
1.124 + set ::callbacks(xSync,abc) {
1.125 + set ::rc [catchsql { DROP TABLE newtab }]
1.126 + }
1.127 + execsql {
1.128 + INSERT INTO abc2 VALUES(1, 2, 3);
1.129 + SELECT name FROM sqlite_master ORDER BY name;
1.130 + }
1.131 +} {abc abc2 log newtab}
1.132 +do_test vtab7-2.6.1 {
1.133 + set ::rc
1.134 +} {1 {database table is locked}}
1.135 +execsql {DROP TABLE newtab}
1.136 +
1.137 +# Write to an attached database from xSync().
1.138 +ifcapable attach {
1.139 + do_test vtab7-3.1 {
1.140 + file delete -force test2.db
1.141 + file delete -force test2.db-journal
1.142 + execsql {
1.143 + ATTACH 'test2.db' AS db2;
1.144 + CREATE TABLE db2.stuff(description, shape, color);
1.145 + }
1.146 + set ::callbacks(xSync,abc) {
1.147 + execsql { INSERT INTO db2.stuff VALUES('abc', 'square', 'green'); }
1.148 + }
1.149 + execsql {
1.150 + INSERT INTO abc2 VALUES(1, 2, 3);
1.151 + SELECT * from stuff;
1.152 + }
1.153 + } {abc square green}
1.154 +}
1.155 +
1.156 +# UPDATE: The next test passes, but leaks memory. So leave it out.
1.157 +#
1.158 +# The following tests test that writing to the database from within
1.159 +# the xCommit callback causes a misuse error.
1.160 +# do_test vtab7-4.1 {
1.161 +# unset -nocomplain ::callbacks(xSync,abc)
1.162 +# set ::callbacks(xCommit,abc) {
1.163 +# execsql { INSERT INTO log VALUES('hello') }
1.164 +# }
1.165 +# catchsql {
1.166 +# INSERT INTO abc2 VALUES(1, 2, 3);
1.167 +# }
1.168 +# } {1 {library routine called out of sequence}}
1.169 +
1.170 +# These tests, vtab7-4.*, test that an SQLITE_LOCKED error is returned
1.171 +# if an attempt to write to a virtual module table or create a new
1.172 +# virtual table from within an xSync() callback.
1.173 +do_test vtab7-4.1 {
1.174 + execsql {
1.175 + CREATE TABLE def(d, e, f);
1.176 + CREATE VIRTUAL TABLE def2 USING echo(def);
1.177 + }
1.178 + set ::callbacks(xSync,abc) {
1.179 + set ::error [catchsql { INSERT INTO def2 VALUES(1, 2, 3) }]
1.180 + }
1.181 + execsql {
1.182 + INSERT INTO abc2 VALUES(1, 2, 3);
1.183 + }
1.184 + set ::error
1.185 +} {1 {database table is locked}}
1.186 +do_test vtab7-4.2 {
1.187 + set ::callbacks(xSync,abc) {
1.188 + set ::error [catchsql { CREATE VIRTUAL TABLE def3 USING echo(def) }]
1.189 + }
1.190 + execsql {
1.191 + INSERT INTO abc2 VALUES(1, 2, 3);
1.192 + }
1.193 + set ::error
1.194 +} {1 {database table is locked}}
1.195 +
1.196 +do_test vtab7-4.3 {
1.197 + set ::callbacks(xSync,abc) {
1.198 + set ::error [catchsql { DROP TABLE def2 }]
1.199 + }
1.200 + execsql {
1.201 + INSERT INTO abc2 VALUES(1, 2, 3);
1.202 + SELECT name FROM sqlite_master ORDER BY name;
1.203 + }
1.204 + set ::error
1.205 +} {1 {database table is locked}}
1.206 +
1.207 +trace remove variable ::echo_module write echo_module_trace
1.208 +unset -nocomplain ::callbacks
1.209 +
1.210 +finish_test