1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/sqlite3api/TEST/TclScript/progress.test Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,177 @@
1.4 +# 2001 September 15
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
1.15 +# focus of this file is testing the 'progress callback'.
1.16 +#
1.17 +# $Id: progress.test,v 1.8 2007/06/15 14:53:53 danielk1977 Exp $
1.18 +
1.19 +set testdir [file dirname $argv0]
1.20 +source $testdir/tester.tcl
1.21 +
1.22 +# If the progress callback is not available in this build, skip this
1.23 +# whole file.
1.24 +ifcapable !progress {
1.25 + finish_test
1.26 + return
1.27 +}
1.28 +
1.29 +# Build some test data
1.30 +#
1.31 +execsql {
1.32 + BEGIN;
1.33 + CREATE TABLE t1(a);
1.34 + INSERT INTO t1 VALUES(1);
1.35 + INSERT INTO t1 VALUES(2);
1.36 + INSERT INTO t1 VALUES(3);
1.37 + INSERT INTO t1 VALUES(4);
1.38 + INSERT INTO t1 VALUES(5);
1.39 + INSERT INTO t1 VALUES(6);
1.40 + INSERT INTO t1 VALUES(7);
1.41 + INSERT INTO t1 VALUES(8);
1.42 + INSERT INTO t1 VALUES(9);
1.43 + INSERT INTO t1 VALUES(10);
1.44 + COMMIT;
1.45 +}
1.46 +
1.47 +
1.48 +# Test that the progress callback is invoked.
1.49 +do_test progress-1.0 {
1.50 + set counter 0
1.51 + db progress 1 "[namespace code {incr counter}] ; expr 0"
1.52 + execsql {
1.53 + SELECT * FROM t1
1.54 + }
1.55 + expr $counter > 1
1.56 +} 1
1.57 +do_test progress-1.0.1 {
1.58 + db progress
1.59 +} {::namespace inscope :: {incr counter} ; expr 0}
1.60 +do_test progress-1.0.2 {
1.61 + set v [catch {db progress xyz bogus} msg]
1.62 + lappend v $msg
1.63 +} {1 {expected integer but got "xyz"}}
1.64 +
1.65 +# Test that the query is abandoned when the progress callback returns non-zero
1.66 +do_test progress-1.1 {
1.67 + set counter 0
1.68 + db progress 1 "[namespace code {incr counter}] ; expr 1"
1.69 + set rc [catch {execsql {
1.70 + SELECT * FROM t1
1.71 + }}]
1.72 + list $counter $rc
1.73 +} {1 1}
1.74 +
1.75 +# Test that the query is rolled back when the progress callback returns
1.76 +# non-zero.
1.77 +do_test progress-1.2 {
1.78 +
1.79 + # This figures out how many opcodes it takes to copy 5 extra rows into t1.
1.80 + db progress 1 "[namespace code {incr five_rows}] ; expr 0"
1.81 + set five_rows 0
1.82 + execsql {
1.83 + INSERT INTO t1 SELECT a+10 FROM t1 WHERE a < 6
1.84 + }
1.85 + db progress 0 ""
1.86 + execsql {
1.87 + DELETE FROM t1 WHERE a > 10
1.88 + }
1.89 +
1.90 + # Now set up the progress callback to abandon the query after the number of
1.91 + # opcodes to copy 5 rows. That way, when we try to copy 6 rows, we know
1.92 + # some data will have been inserted into the table by the time the progress
1.93 + # callback abandons the query.
1.94 + db progress $five_rows "expr 1"
1.95 + catchsql {
1.96 + INSERT INTO t1 SELECT a+10 FROM t1 WHERE a < 9
1.97 + }
1.98 + execsql {
1.99 + SELECT count(*) FROM t1
1.100 + }
1.101 +} 10
1.102 +
1.103 +# Test that an active transaction remains active and not rolled back
1.104 +# after the progress query abandons a query.
1.105 +#
1.106 +# UPDATE: It is now recognised that this is a sure route to database
1.107 +# corruption. So the transaction is rolled back.
1.108 +do_test progress-1.3 {
1.109 +
1.110 + db progress 0 ""
1.111 + execsql BEGIN
1.112 + execsql {
1.113 + INSERT INTO t1 VALUES(11)
1.114 + }
1.115 + db progress 1 "expr 1"
1.116 + catchsql {
1.117 + INSERT INTO t1 VALUES(12)
1.118 + }
1.119 + db progress 0 ""
1.120 + catchsql COMMIT
1.121 +} {1 {cannot commit - no transaction is active}}
1.122 +do_test progress-1.3.1 {
1.123 + execsql {
1.124 + SELECT count(*) FROM t1
1.125 + }
1.126 +} 10
1.127 +
1.128 +# Check that a value of 0 for N means no progress callback
1.129 +do_test progress-1.4 {
1.130 + set counter 0
1.131 + db progress 0 "[namespace code {incr counter}] ; expr 0"
1.132 + execsql {
1.133 + SELECT * FROM t1;
1.134 + }
1.135 + set counter
1.136 +} 0
1.137 +
1.138 +db progress 0 ""
1.139 +
1.140 +# Make sure other queries can be run from within the progress
1.141 +# handler. Ticket #1827
1.142 +#
1.143 +do_test progress-1.5 {
1.144 + set rx 0
1.145 + proc set_rx {args} {
1.146 + db progress 0 {}
1.147 + set ::rx [db eval {SELECT count(*) FROM t1}]
1.148 + return [expr 0]
1.149 + }
1.150 + db progress 10 set_rx
1.151 + db eval {
1.152 + SELECT sum(a) FROM t1
1.153 + }
1.154 +} {55}
1.155 +do_test progress-1.6 {
1.156 + set ::rx
1.157 +} {10}
1.158 +
1.159 +# Check that abandoning a query using the progress handler does
1.160 +# not cause other queries to abort. Ticket #2415.
1.161 +do_test progress-1.7 {
1.162 + execsql {
1.163 + CREATE TABLE abc(a, b, c);
1.164 + INSERT INTO abc VALUES(1, 2, 3);
1.165 + INSERT INTO abc VALUES(4, 5, 6);
1.166 + INSERT INTO abc VALUES(7, 8, 9);
1.167 + }
1.168 +
1.169 + set ::res [list]
1.170 + db eval {SELECT a, b, c FROM abc} {
1.171 + lappend ::res $a $b $c
1.172 + db progress 10 "expr 1"
1.173 + catch {db eval {SELECT a, b, c FROM abc} { }} msg
1.174 + lappend ::res $msg
1.175 + }
1.176 +
1.177 + set ::res
1.178 +} {1 2 3 interrupted 4 5 6 interrupted 7 8 9 interrupted}
1.179 +
1.180 +finish_test