1 # 2009 April 20 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 # Test cases inspired by ticket #3811. Tests to make sure that 13 # the journal_mode can only be changed at appropriate times and that 14 # all reported changes are effective. 15 # 16 # $Id: jrnlmode3.test,v 1.5 2009/04/20 17:43:03 drh Exp $ 17 18 set testdir [file dirname $argv0] 19 source $testdir/tester.tcl 20 21 ifcapable {!pager_pragmas} { 22 finish_test 23 return 24 } 25 26 # 27 # Verify that journal_mode=OFF works as long as it occurs before the first 28 # transaction, even if locking_mode=EXCLUSIVE is enabled. The behavior if 29 # journal_mode is changed after the first transaction is undefined and hence 30 # untested. 31 # 32 do_test jrnlmode3-1.1 { 33 db eval { 34 PRAGMA journal_mode=OFF; 35 PRAGMA locking_mode=EXCLUSIVE; 36 CREATE TABLE t1(x); 37 INSERT INTO t1 VALUES(1); 38 SELECT * FROM t1; 39 } 40 } {off exclusive 1} 41 do_test jrnlmode3-1.2 { 42 db eval { 43 BEGIN; 44 INSERT INTO t1 VALUES(2); 45 ROLLBACK; 46 SELECT * FROM t1; 47 } 48 } {1} 49 50 db close 51 file delete -force test.db test.db-journal 52 sqlite3 db test.db 53 54 do_test jrnlmode3-2.1 { 55 db eval { 56 PRAGMA locking_mode=EXCLUSIVE; 57 PRAGMA journal_mode=OFF; 58 CREATE TABLE t1(x); 59 INSERT INTO t1 VALUES(1); 60 SELECT * FROM t1; 61 } 62 } {exclusive off 1} 63 do_test jrnlmode3-2.2 { 64 db eval { 65 BEGIN; 66 INSERT INTO t1 VALUES(2); 67 ROLLBACK; 68 SELECT * FROM t1; 69 } 70 } {1} 71 72 # Test cases to verify that we can move from any journal_mode 73 # to any other, as long as we are not in a transaction. Verify 74 # that we cannot change journal_mode while a transaction is active. 75 # 76 set all_journal_modes {delete persist truncate memory off} 77 set cnt 0 78 foreach fromjmode $all_journal_modes { 79 foreach tojmode $all_journal_modes { 80 81 # Skip the no-change cases 82 if {$fromjmode==$tojmode} continue 83 incr cnt 84 85 # Start with a fresh database connection an empty database file. 86 # 87 db close 88 file delete -force test.db test.db-journal 89 sqlite3 db test.db 90 91 # Initialize the journal mode. 92 # 93 do_test jrnlmode3-3.$cnt.1-($fromjmode-to-$tojmode) { 94 db eval "PRAGMA journal_mode = $fromjmode;" 95 } $fromjmode 96 97 # Verify that the initial journal mode takes. 98 # 99 do_test jrnlmode3-3.$cnt.2 { 100 db eval {PRAGMA main.journal_mode} 101 } $fromjmode 102 103 # Start a transaction and try to change the journal mode within 104 # the transaction. This should fail. 105 # 106 do_test jrnlmode3-3.$cnt.3 { 107 db eval { 108 CREATE TABLE t1(x); 109 BEGIN; 110 INSERT INTO t1 VALUES($cnt); 111 } 112 db eval "PRAGMA journal_mode=$tojmode" 113 } $fromjmode 114 115 # Rollback the transaction. 116 # 117 do_test jrnlmode3-3.$cnt.4 { 118 db eval { 119 ROLLBACK; 120 SELECT * FROM t1; 121 } 122 } {} 123 124 # Now change the journal mode again. This time the new mode 125 # should take. 126 # 127 do_test jrnlmode3-3.$cnt.5 { 128 db eval "PRAGMA journal_mode=$tojmode" 129 } $tojmode 130 131 # Do a the transaction. Verify that the rollback occurred 132 # if journal_mode!=OFF. 133 # 134 do_test jrnlmode3-3.$cnt.6 { 135 db eval { 136 DROP TABLE IF EXISTS t1; 137 CREATE TABLE t1(x); 138 BEGIN; 139 INSERT INTO t1 VALUES(1); 140 } 141 db eval ROLLBACK 142 db eval { 143 SELECT * FROM t1; 144 } 145 } {} 146 } 147 } 148 149 finish_test 150