xref: /sqlite-3.40.0/test/jrnlmode3.test (revision fda06bef)
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
18set testdir [file dirname $argv0]
19source $testdir/tester.tcl
20
21ifcapable {!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#
32do_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}
41do_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
50db close
51forcedelete test.db test.db-journal
52sqlite3 db test.db
53
54do_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}
63do_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#
76set all_journal_modes {delete persist truncate memory off}
77set cnt 0
78foreach 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    forcedelete 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
149finish_test
150