blob: 7060366bdec2c795bbef2d166057e08ae3413306 [file] [log] [blame]
drhaa940ea2004-01-15 02:44:03 +00001# 2004 Jan 14
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 TCL interface to the
12# SQLite library.
13#
14# The focus of the tests in this file is the following interface:
15#
16# sqlite_commit_hook
danielk197794eb6a12005-12-15 15:22:08 +000017# sqlite_update_hook (tests hook-4 onwards)
drhaa940ea2004-01-15 02:44:03 +000018#
danielk197794eb6a12005-12-15 15:22:08 +000019# $Id: hook.test,v 1.6 2005/12/15 15:22:10 danielk1977 Exp $
drhaa940ea2004-01-15 02:44:03 +000020
21set testdir [file dirname $argv0]
22source $testdir/tester.tcl
23
24do_test hook-1.2 {
25 db commit_hook
26} {}
27
28
29do_test hook-3.1 {
30 set commit_cnt 0
31 proc commit_hook {} {
32 incr ::commit_cnt
33 return 0
34 }
35 db commit_hook ::commit_hook
36 db commit_hook
37} {::commit_hook}
38do_test hook-3.2 {
39 set commit_cnt
40} {0}
41do_test hook-3.3 {
42 execsql {
43 CREATE TABLE t2(a,b);
44 }
45 set commit_cnt
46} {1}
47do_test hook-3.4 {
48 execsql {
49 INSERT INTO t2 VALUES(1,2);
50 INSERT INTO t2 SELECT a+1, b+1 FROM t2;
51 INSERT INTO t2 SELECT a+2, b+2 FROM t2;
52 }
53 set commit_cnt
54} {4}
55do_test hook-3.5 {
56 set commit_cnt {}
57 proc commit_hook {} {
58 set ::commit_cnt [execsql {SELECT * FROM t2}]
59 return 0
60 }
61 execsql {
62 INSERT INTO t2 VALUES(5,6);
63 }
64 set commit_cnt
65} {1 2 2 3 3 4 4 5 5 6}
66do_test hook-3.6 {
67 set commit_cnt {}
68 proc commit_hook {} {
danielk19771d850a72004-05-31 08:26:49 +000069 set ::commit_cnt [execsql {SELECT * FROM t2}]
drhaa940ea2004-01-15 02:44:03 +000070 return 1
71 }
72 catchsql {
73 INSERT INTO t2 VALUES(6,7);
74 }
75} {1 {constraint failed}}
76do_test hook-3.7 {
danielk19771d850a72004-05-31 08:26:49 +000077 set ::commit_cnt
drhaa940ea2004-01-15 02:44:03 +000078} {1 2 2 3 3 4 4 5 5 6 6 7}
79do_test hook-3.8 {
80 execsql {SELECT * FROM t2}
81} {1 2 2 3 3 4 4 5 5 6}
82
drh0f14e2e2004-06-29 12:39:08 +000083# Test turnning off the commit hook
84#
85do_test hook-3.9 {
86 db commit_hook {}
87 set ::commit_cnt {}
88 execsql {
89 INSERT INTO t2 VALUES(7,8);
90 }
91 set ::commit_cnt
92} {}
drhaa940ea2004-01-15 02:44:03 +000093
danielk197794eb6a12005-12-15 15:22:08 +000094# Very simple tests. Test that the update hook is invoked correctly for INSERT,
95# DELETE and UPDATE statements, including DELETE statements with no WHERE
96# clause.
97#
98do_test hook-4.1 {
99 catchsql {
100 DROP TABLE t1;
101 }
102 execsql {
103 CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
104 INSERT INTO t1 VALUES(1, 'one');
105 INSERT INTO t1 VALUES(2, 'two');
106 INSERT INTO t1 VALUES(3, 'three');
107 }
108 db update_hook [list lappend ::update_hook]
109} {}
110do_test hook-4.2 {
111 execsql {
112 INSERT INTO t1 VALUES(4, 'four');
113 DELETE FROM t1 WHERE b = 'two';
114 UPDATE t1 SET b = '' WHERE a = 1 OR a = 3;
115 DELETE FROM t1;
116 }
117 set ::update_hook
118} [list \
119 INSERT main t1 4 \
120 DELETE main t1 2 \
121 UPDATE main t1 1 \
122 UPDATE main t1 3 \
123 DELETE main t1 1 \
124 DELETE main t1 3 \
125 DELETE main t1 4 \
126]
127
128# Check that the update-hook is invoked for rows modified by trigger
129# bodies.
130#
131set ::update_hook {}
132do_test hook-5.1 {
133 catchsql {
134 DROP TABLE t2;
135 }
136 execsql {
137 CREATE TABLE t2(c INTEGER PRIMARY KEY, d);
138 CREATE TRIGGER t1_trigger AFTER INSERT ON t1 BEGIN
139 INSERT INTO t2 VALUES(new.a, new.b);
140 UPDATE t2 SET d = d || ' via trigger' WHERE new.a = c;
141 DELETE FROM t2 WHERE new.a = c;
142 END;
143 }
144} {}
145do_test hook-5.2 {
146 execsql {
147 INSERT INTO t1 VALUES(1, 'one');
148 INSERT INTO t1 VALUES(2, 'two');
149 }
150 set ::update_hook
151} [list \
152 INSERT main t1 1 \
153 INSERT main t2 1 \
154 UPDATE main t2 1 \
155 DELETE main t2 1 \
156 INSERT main t1 2 \
157 INSERT main t2 2 \
158 UPDATE main t2 2 \
159 DELETE main t2 2 \
160]
161
162set ::update_hook {}
163do_test hook-6.1 {
164 file delete -force test2.db
165 execsql {
166 ATTACH 'test2.db' AS aux;
167 CREATE TABLE aux.t3(a INTEGER PRIMARY KEY, b);
168 INSERT INTO aux.t3 SELECT * FROM t1;
169 UPDATE t3 SET b = 'two or so' WHERE a = 2;
170 DELETE FROM t3;
171 }
172 set ::update_hook
173} [list \
174 INSERT aux t3 1 \
175 INSERT aux t3 2 \
176 UPDATE aux t3 2 \
177 DELETE aux t3 1 \
178 DELETE aux t3 2 \
179]
180
181# Do some sorting, grouping, compound queries, population and depopulation
182# of indices, to make sure the update-hook is not invoked incorrectly.
183#
184set ::update_hook {}
185do_test hook-7.1 {
186 execsql {
187 DROP TRIGGER t1_trigger;
188 CREATE INDEX t1_i ON t1(b);
189 INSERT INTO t1 VALUES(3, 'three');
190 UPDATE t1 SET b = '';
191 DELETE FROM t1 WHERE a > 1;
192 }
193 set ::update_hook
194} [list \
195 INSERT main t1 3 \
196 UPDATE main t1 1 \
197 UPDATE main t1 2 \
198 UPDATE main t1 3 \
199 DELETE main t1 2 \
200 DELETE main t1 3 \
201]
202set ::update_hook {}
203do_test hook-7.2 {
204 execsql {
205 SELECT * FROM t1 UNION SELECT * FROM t3;
206 SELECT * FROM t1 UNION ALL SELECT * FROM t3;
207 SELECT * FROM t1 INTERSECT SELECT * FROM t3;
208 SELECT * FROM t1 EXCEPT SELECT * FROM t3;
209 SELECT * FROM t1 ORDER BY b;
210 SELECT * FROM t1 GROUP BY b;
211 }
212 set ::update_hook
213} [list]
214
drhaa940ea2004-01-15 02:44:03 +0000215finish_test
danielk197794eb6a12005-12-15 15:22:08 +0000216