blob: 5616a7afdaab725ee43822df27cd853a53674c7a [file] [log] [blame]
danielk1977348bb5d2003-10-18 09:37:26 +00001# 2001 September 15
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
12# focus of this file is testing the 'progress callback'.
13#
drhf8888bb2006-05-26 19:57:19 +000014# $Id: progress.test,v 1.6 2006/05/26 19:57:20 drh Exp $
danielk1977348bb5d2003-10-18 09:37:26 +000015
16set testdir [file dirname $argv0]
17source $testdir/tester.tcl
18
danielk19774489f9b2005-01-20 02:17:01 +000019# If the progress callback is not available in this build, skip this
20# whole file.
21ifcapable !progress {
22 finish_test
23 return
24}
25
danielk1977348bb5d2003-10-18 09:37:26 +000026# Build some test data
27#
28execsql {
29 BEGIN;
30 CREATE TABLE t1(a);
31 INSERT INTO t1 VALUES(1);
32 INSERT INTO t1 VALUES(2);
33 INSERT INTO t1 VALUES(3);
34 INSERT INTO t1 VALUES(4);
35 INSERT INTO t1 VALUES(5);
36 INSERT INTO t1 VALUES(6);
37 INSERT INTO t1 VALUES(7);
38 INSERT INTO t1 VALUES(8);
39 INSERT INTO t1 VALUES(9);
40 INSERT INTO t1 VALUES(10);
41 COMMIT;
42}
43
44
45# Test that the progress callback is invoked.
46do_test progress-1.0 {
47 set counter 0
48 db progress 1 "[namespace code {incr counter}] ; expr 0"
49 execsql {
50 SELECT * FROM t1
51 }
52 expr $counter > 1
53} 1
drh0f14e2e2004-06-29 12:39:08 +000054do_test progress-1.0.1 {
55 db progress
56} {::namespace inscope :: {incr counter} ; expr 0}
57do_test progress-1.0.2 {
58 set v [catch {db progress xyz bogus} msg]
59 lappend v $msg
60} {1 {expected integer but got "xyz"}}
danielk1977348bb5d2003-10-18 09:37:26 +000061
62# Test that the query is abandoned when the progress callback returns non-zero
drhb45bb9f2004-10-18 21:34:46 +000063do_test progress-1.1 {
danielk1977348bb5d2003-10-18 09:37:26 +000064 set counter 0
65 db progress 1 "[namespace code {incr counter}] ; expr 1"
danielk19771d850a72004-05-31 08:26:49 +000066 set rc [catch {execsql {
danielk1977348bb5d2003-10-18 09:37:26 +000067 SELECT * FROM t1
danielk19771d850a72004-05-31 08:26:49 +000068 }}]
69 list $counter $rc
70} {1 1}
danielk1977348bb5d2003-10-18 09:37:26 +000071
72# Test that the query is rolled back when the progress callback returns
73# non-zero.
drhb45bb9f2004-10-18 21:34:46 +000074do_test progress-1.2 {
danielk1977348bb5d2003-10-18 09:37:26 +000075
76 # This figures out how many opcodes it takes to copy 5 extra rows into t1.
77 db progress 1 "[namespace code {incr five_rows}] ; expr 0"
78 set five_rows 0
79 execsql {
80 INSERT INTO t1 SELECT a+10 FROM t1 WHERE a < 6
81 }
82 db progress 0 ""
83 execsql {
84 DELETE FROM t1 WHERE a > 10
85 }
86
87 # Now set up the progress callback to abandon the query after the number of
88 # opcodes to copy 5 rows. That way, when we try to copy 6 rows, we know
89 # some data will have been inserted into the table by the time the progress
90 # callback abandons the query.
91 db progress $five_rows "expr 1"
danielk19771d850a72004-05-31 08:26:49 +000092 catchsql {
93 INSERT INTO t1 SELECT a+10 FROM t1 WHERE a < 9
danielk1977348bb5d2003-10-18 09:37:26 +000094 }
95 execsql {
96 SELECT count(*) FROM t1
97 }
98} 10
99
100# Test that an active transaction remains active and not rolled back after the
101# progress query abandons a query.
drhb45bb9f2004-10-18 21:34:46 +0000102do_test progress-1.3 {
danielk1977348bb5d2003-10-18 09:37:26 +0000103
104 db progress 0 ""
105 execsql BEGIN
106 execsql {
107 INSERT INTO t1 VALUES(11)
108 }
109 db progress 1 "expr 1"
danielk19771d850a72004-05-31 08:26:49 +0000110 catchsql {
danielk1977348bb5d2003-10-18 09:37:26 +0000111 INSERT INTO t1 VALUES(12)
112 }
113 db progress 0 ""
114 execsql COMMIT
115 execsql {
116 SELECT count(*) FROM t1
117 }
118} 11
119
120# Check that a value of 0 for N means no progress callback
drhb45bb9f2004-10-18 21:34:46 +0000121do_test progress-1.4 {
danielk1977348bb5d2003-10-18 09:37:26 +0000122 set counter 0
123 db progress 0 "[namespace code {incr counter}] ; expr 0"
124 execsql {
125 SELECT * FROM t1;
126 }
127 set counter
128} 0
129
130db progress 0 ""
131
drhf8888bb2006-05-26 19:57:19 +0000132# Make sure other queries can be run from within the progress
133# handler. Ticket #1827
134#
135do_test progress-1.5 {
136 set rx 0
137 proc set_rx {args} {
138 db progress 0 {}
139 set ::rx [db eval {SELECT count(*) FROM t1}]
140 return [expr 0]
141 }
142 db progress 10 set_rx
143 db eval {
144 SELECT sum(a) FROM t1
145 }
146} {66}
147do_test progress-1.6 {
148 set ::rx
149} {11}
150
danielk1977348bb5d2003-10-18 09:37:26 +0000151finish_test