Home | History | Annotate | Download | only in test
      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