1# 2008 December 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# 12# $Id: savepoint2.test,v 1.3 2008/12/20 18:33:59 danielk1977 Exp $ 13 14set testdir [file dirname $argv0] 15source $testdir/tester.tcl 16 17# Tests in this file are quite similar to those run by trans.test and 18# avtrans.test. 19# 20 21db close 22register_jt_vfs -default "" 23sqlite3 db test.db -vfs jt 24 25proc signature {} { 26 return [db eval {SELECT count(*), md5sum(x) FROM t3}] 27} 28 29do_test savepoint2-1 { 30 execsql { 31 PRAGMA cache_size=10; 32 BEGIN; 33 CREATE TABLE t3(x TEXT); 34 INSERT INTO t3 VALUES(randstr(10,400)); 35 INSERT INTO t3 VALUES(randstr(10,400)); 36 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 37 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 38 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 39 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 40 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 41 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 42 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 43 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 44 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 45 COMMIT; 46 SELECT count(*) FROM t3; 47 } 48} {1024} 49 50unset -nocomplain ::sig 51unset -nocomplain SQL 52 53set iterations 20 54 55set SQL(1) { 56 DELETE FROM t3 WHERE random()%10!=0; 57 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3; 58 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3; 59} 60set SQL(2) { 61 DELETE FROM t3 WHERE random()%10!=0; 62 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3; 63 DELETE FROM t3 WHERE random()%10!=0; 64 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3; 65} 66set SQL(3) { 67 UPDATE t3 SET x = randstr(10, 400) WHERE random()%10; 68 INSERT INTO t3 SELECT x FROM t3 WHERE random()%10; 69 DELETE FROM t3 WHERE random()%10; 70} 71set SQL(4) { 72 INSERT INTO t3 SELECT randstr(10,400) FROM t3 WHERE (random()%10 == 0); 73} 74 75 76 77for {set ii 2} {$ii < ($iterations+2)} {incr ii} { 78 79 # Record the database signature. Optionally (every second run) open a 80 # transaction. In all cases open savepoint "one", which may or may 81 # not be a transaction savepoint, depending on whether or not a real 82 # transaction has been opened. 83 # 84 do_test savepoint2-$ii.1 { 85 if {$ii % 2} { execsql BEGIN } 86 set ::sig(one) [signature] 87 execsql "SAVEPOINT one" 88 } {} 89 90 # Execute some SQL on the database. Then rollback to savepoint "one". 91 # Check that the database signature is as it was when "one" was opened. 92 # 93 do_test savepoint2-$ii.2 { 94 execsql $SQL(1) 95 execsql "ROLLBACK to one" 96 signature 97 } $::sig(one) 98 integrity_check savepoint2-$ii.2.1 99 100 # Execute some SQL. Then open savepoint "two". Savepoint "two" is therefore 101 # nested in savepoint "one". 102 # 103 do_test savepoint2-$ii.3 { 104 execsql $SQL(1) 105 set ::sig(two) [signature] 106 execsql "SAVEPOINT two" 107 } {} 108 109 # More SQL changes. The rollback to savepoint "two". Check that the 110 # signature is as it was when savepoint "two" was opened. 111 # 112 do_test savepoint2-$ii.4 { 113 execsql $SQL(2) 114 execsql "ROLLBACK to two" 115 signature 116 } $::sig(two) 117 integrity_check savepoint2-$ii.4.1 118 119 # More SQL changes. The rollback to savepoint "two". Check that the 120 # signature is as it was when savepoint "two" was opened. 121 # 122 do_test savepoint2-$ii.5 { 123 execsql $SQL(2) 124 execsql "SAVEPOINT three" 125 execsql $SQL(3) 126 execsql "RELEASE three" 127 execsql "ROLLBACK to one" 128 signature 129 } $::sig(one) 130 131 # By this point the database is in the same state as it was at the 132 # top of the for{} loop (everything having been rolled back by the 133 # "ROLLBACK TO one" command above). So make a few changes to the 134 # database and COMMIT the open transaction, so that the next iteration 135 # of the for{} loop works on a different dataset. 136 # 137 # The transaction being committed here may have been opened normally using 138 # "BEGIN", or may have been opened using a transaction savepoint created 139 # by the "SAVEPOINT one" statement. 140 # 141 do_test savepoint2-$ii.6 { 142 execsql $SQL(4) 143 execsql COMMIT 144 sqlite3_get_autocommit db 145 } {1} 146 integrity_check savepoint2-$ii.6.1 147} 148 149unset -nocomplain ::sig 150unset -nocomplain SQL 151 152unregister_jt_vfs 153 154finish_test 155 156