github.com/jdgcs/sqlite3@v1.12.1-0.20210908114423-bc5f96e4dd51/testdata/tcl/walmode.test (about)

     1  # 2010 April 19
     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 SQLite library.  The
    12  # focus of this file is testing the operation of the library in
    13  # "PRAGMA journal_mode=WAL" mode.
    14  #
    15  
    16  set testdir [file dirname $argv0]
    17  source $testdir/tester.tcl
    18  source $testdir/malloc_common.tcl
    19  
    20  # If the library was compiled without WAL support, check that the 
    21  # "PRAGMA journal_mode=WAL" treats "WAL" as an unrecognized mode.
    22  #
    23  ifcapable !wal {
    24  
    25    do_test walmode-0.1 {
    26      execsql { PRAGMA journal_mode = wal }
    27    } {delete}
    28    do_test walmode-0.2 {
    29      execsql { PRAGMA main.journal_mode = wal }
    30    } {delete}
    31    do_test walmode-0.3 {
    32      execsql { PRAGMA main.journal_mode }
    33    } {delete}
    34  
    35    finish_test
    36    return
    37  }
    38  
    39  do_test walmode-1.1 {
    40    set sqlite_sync_count 0
    41    execsql { PRAGMA page_size = 1024 }
    42    execsql { PRAGMA journal_mode = wal }
    43  } {wal}
    44  do_test walmode-1.2 {
    45    file size test.db
    46  } {1024}
    47  
    48  if {[atomic_batch_write test.db]==0} {
    49    set expected_sync_count 3
    50    if {$::tcl_platform(platform)!="windows"} {
    51      ifcapable dirsync {
    52        incr expected_sync_count
    53      }
    54    }
    55    do_test walmode-1.3 {
    56      set sqlite_sync_count
    57    } $expected_sync_count
    58  }
    59  
    60  do_test walmode-1.4 {
    61    file exists test.db-wal
    62  } {0}
    63  do_test walmode-1.5 {
    64    execsql { CREATE TABLE t1(a, b) }
    65    file size test.db
    66  } {1024}
    67  do_test walmode-1.6 {
    68    file exists test.db-wal
    69  } {1}
    70  do_test walmode-1.7 {
    71    db close
    72    file exists test.db-wal
    73  } {0}
    74  
    75  # There is now a database file with the read and write versions set to 2
    76  # in the file system. This file should default to WAL mode.
    77  #
    78  do_test walmode-2.1 {
    79    sqlite3 db test.db
    80    file exists test.db-wal
    81  } {0}
    82  do_test walmode-2.2 {
    83    execsql { SELECT * FROM sqlite_master }
    84    file exists test.db-wal
    85  } {1}
    86  do_test walmode-2.3 {
    87    db close
    88    file exists test.db-wal
    89  } {0}
    90  
    91  # If the first statement executed is "PRAGMA journal_mode = wal", and
    92  # the file is already configured for WAL (read and write versions set
    93  # to 2), then there should be no need to write the database. The 
    94  # statement should cause the client to connect to the log file.
    95  #
    96  set sqlite_sync_count 0
    97  do_test walmode-3.1 {
    98    sqlite3 db test.db
    99    execsql { PRAGMA journal_mode = wal }
   100  } {wal}
   101  do_test walmode-3.2 {
   102    list $sqlite_sync_count [file exists test.db-wal] [file size test.db-wal]
   103  } {0 1 0}
   104  
   105  # Test that changing back to journal_mode=persist works.
   106  #
   107  do_test walmode-4.1 {
   108    execsql { INSERT INTO t1 VALUES(1, 2) }
   109    execsql { PRAGMA journal_mode = persist }
   110  } {persist}
   111  if {[atomic_batch_write test.db]==0} {
   112    do_test walmode-4.2 {
   113      list [file exists test.db-journal] [file exists test.db-wal]
   114    } {1 0}
   115  }
   116  do_test walmode-4.3 {
   117    execsql { SELECT * FROM t1 }
   118  } {1 2}
   119  do_test walmode-4.4 {
   120    db close
   121    sqlite3 db test.db
   122    execsql { SELECT * FROM t1 }
   123  } {1 2}
   124  if {[atomic_batch_write test.db]==0} {
   125    do_test walmode-4.5 {
   126      list [file exists test.db-journal] [file exists test.db-wal]
   127    } {1 0}
   128  }
   129  
   130  # Test that nothing goes wrong if a connection is prevented from changing
   131  # from WAL to rollback mode because a second connection has the database
   132  # open. Or from rollback to WAL.
   133  #
   134  do_test walmode-4.6 {
   135    sqlite3 db2 test.db
   136    execsql { PRAGMA main.journal_mode } db2
   137  } {delete}
   138  do_test walmode-4.7 {
   139    execsql { PRAGMA main.journal_mode = wal } db
   140  } {wal}
   141  do_test walmode-4.8 {
   142    execsql { SELECT * FROM t1 } db2
   143  } {1 2}
   144  do_test walmode-4.9 {
   145    catchsql { PRAGMA journal_mode = delete } db
   146  } {1 {database is locked}}
   147  do_test walmode-4.10 {
   148    execsql { PRAGMA main.journal_mode } db
   149  } {wal}
   150  
   151  do_test walmode-4.11 {
   152    db2 close
   153    execsql { PRAGMA journal_mode = delete } db
   154  } {delete}
   155  do_test walmode-4.12 {
   156    execsql { PRAGMA main.journal_mode } db
   157  } {delete}
   158  do_test walmode-4.13 {
   159    list [file exists test.db-journal] [file exists test.db-wal]
   160  } {0 0}
   161  do_test walmode-4.14 {
   162    sqlite3 db2 test.db
   163    execsql {
   164      BEGIN;
   165        SELECT * FROM t1;
   166    } db2
   167  } {1 2}
   168  
   169  do_test walmode-4.16 { execsql { PRAGMA main.journal_mode } db  } {delete}
   170  do_test walmode-4.17 { execsql { PRAGMA main.journal_mode } db2 } {delete}
   171  
   172  do_test walmode-4.17 {
   173    catchsql { PRAGMA main.journal_mode = wal } db
   174  } {1 {database is locked}}
   175  do_test walmode-4.18 {
   176    execsql { PRAGMA main.journal_mode } db
   177  } {delete}
   178  catch { db close }
   179  catch { db2 close }
   180  
   181  # Test that it is not possible to change a temporary or in-memory database
   182  # to WAL mode. WAL mode is for persistent file-backed databases only.
   183  #
   184  #   walmode-5.1.*: Try to set journal_mode=WAL on [sqlite3 db :memory:] database.
   185  #   walmode-5.2.*: Try to set journal_mode=WAL on [sqlite3 db ""] database.
   186  #   walmode-5.3.*: Try to set temp.journal_mode=WAL.
   187  #
   188  do_test walmode-5.1.1 {
   189    sqlite3 db :memory:
   190    execsql { PRAGMA main.journal_mode }
   191  } {memory}
   192  do_test walmode-5.1.2 {
   193    execsql { PRAGMA main.journal_mode = wal }
   194  } {memory}
   195  do_test walmode-5.1.3 {
   196    execsql {
   197      BEGIN;
   198        CREATE TABLE t1(a, b);
   199        INSERT INTO t1 VALUES(1, 2);
   200      COMMIT;
   201      SELECT * FROM t1;
   202      PRAGMA main.journal_mode;
   203    }
   204  } {1 2 memory}
   205  do_test walmode-5.1.4 {
   206    execsql { PRAGMA main.journal_mode = wal }
   207  } {memory}
   208  do_test walmode-5.1.5 {
   209    execsql { 
   210      INSERT INTO t1 VALUES(3, 4);
   211      SELECT * FROM t1;
   212      PRAGMA main.journal_mode;
   213    }
   214  } {1 2 3 4 memory}
   215  
   216  if {$TEMP_STORE>=2} {
   217    set tempJrnlMode memory
   218  } else {
   219    set tempJrnlMode delete
   220  }
   221  do_test walmode-5.2.1 {
   222    sqlite3 db ""
   223    execsql { PRAGMA main.journal_mode }
   224  } $tempJrnlMode
   225  do_test walmode-5.2.2 {
   226    execsql { PRAGMA main.journal_mode = wal }
   227  } $tempJrnlMode
   228  do_test walmode-5.2.3 {
   229    execsql {
   230      BEGIN;
   231        CREATE TABLE t1(a, b);
   232        INSERT INTO t1 VALUES(1, 2);
   233      COMMIT;
   234      SELECT * FROM t1;
   235      PRAGMA main.journal_mode;
   236    }
   237  } [list 1 2 $tempJrnlMode]
   238  do_test walmode-5.2.4 {
   239    execsql { PRAGMA main.journal_mode = wal }
   240  } $tempJrnlMode
   241  do_test walmode-5.2.5 {
   242    execsql { 
   243      INSERT INTO t1 VALUES(3, 4);
   244      SELECT * FROM t1;
   245      PRAGMA main.journal_mode;
   246    }
   247  } [list 1 2 3 4 $tempJrnlMode]
   248  
   249  do_test walmode-5.3.1 {
   250    sqlite3 db test.db
   251    execsql { PRAGMA temp.journal_mode }
   252  } $tempJrnlMode
   253  do_test walmode-5.3.2 {
   254    execsql { PRAGMA temp.journal_mode = wal }
   255  } $tempJrnlMode
   256  do_test walmode-5.3.3 {
   257    execsql {
   258      BEGIN;
   259        CREATE TEMP TABLE t1(a, b);
   260        INSERT INTO t1 VALUES(1, 2);
   261      COMMIT;
   262      SELECT * FROM t1;
   263      PRAGMA temp.journal_mode;
   264    }
   265  } [list 1 2 $tempJrnlMode]
   266  do_test walmode-5.3.4 {
   267    execsql { PRAGMA temp.journal_mode = wal }
   268  } $tempJrnlMode
   269  do_test walmode-5.3.5 {
   270    execsql { 
   271      INSERT INTO t1 VALUES(3, 4);
   272      SELECT * FROM t1;
   273      PRAGMA temp.journal_mode;
   274    }
   275  } [list 1 2 3 4 $tempJrnlMode]
   276  
   277  
   278  #-------------------------------------------------------------------------
   279  # Test changing to WAL mode from journal_mode=off or journal_mode=memory
   280  #
   281  foreach {tn mode} {
   282    1 off
   283    2 memory
   284    3 persist
   285    4 delete
   286    5 truncate
   287  } {
   288    do_test walmode-6.$tn {
   289      faultsim_delete_and_reopen
   290      execsql "
   291        PRAGMA journal_mode = $mode;
   292        PRAGMA journal_mode = wal;
   293      "
   294    } [list $mode wal]
   295  }
   296  db close
   297  
   298  #-------------------------------------------------------------------------
   299  # Test the effect of a "PRAGMA journal_mode" command being the first 
   300  # thing executed by a new connection. This means that the schema is not
   301  # loaded when sqlite3_prepare_v2() is called to compile the statement.
   302  #
   303  do_test walmode-7.0 {
   304    forcedelete test.db
   305    sqlite3 db test.db
   306    execsql {
   307      PRAGMA journal_mode = WAL;
   308      CREATE TABLE t1(a, b);
   309    }
   310  } {wal}
   311  foreach {tn sql result} {
   312    1  "PRAGMA journal_mode"                wal
   313    2  "PRAGMA main.journal_mode"           wal
   314    3  "PRAGMA journal_mode = delete"       delete
   315    4  "PRAGMA journal_mode"                delete
   316    5  "PRAGMA main.journal_mode"           delete
   317    6  "PRAGMA journal_mode = wal"          wal
   318    7  "PRAGMA journal_mode"                wal
   319    8  "PRAGMA main.journal_mode"           wal
   320  
   321    9  "PRAGMA journal_mode"                wal
   322   10  "PRAGMA main.journal_mode"           wal
   323   11  "PRAGMA main.journal_mode = delete"  delete
   324   12  "PRAGMA journal_mode"                delete
   325   13  "PRAGMA main.journal_mode"           delete
   326   14  "PRAGMA main.journal_mode = wal"     wal
   327   15  "PRAGMA journal_mode"                wal
   328   16  "PRAGMA main.journal_mode"           wal
   329  } {
   330    do_test walmode-7.$tn { 
   331      db close
   332      sqlite3 db test.db
   333      execsql $sql
   334    } $result
   335  }
   336  db close
   337  
   338  #-------------------------------------------------------------------------
   339  # Test the effect of a "PRAGMA journal_mode" command on an attached 
   340  # database.
   341  #
   342  faultsim_delete_and_reopen
   343  do_execsql_test walmode-8.1 {
   344    CREATE TABLE t1(a, b);
   345    PRAGMA journal_mode = WAL;
   346    ATTACH 'test.db2' AS two;
   347    CREATE TABLE two.t2(a, b);
   348  } {wal}
   349  do_execsql_test walmode-8.2 { PRAGMA main.journal_mode }         {wal}
   350  do_execsql_test walmode-8.3 { PRAGMA two.journal_mode  }         {delete}
   351  do_execsql_test walmode-8.4 { PRAGMA two.journal_mode = DELETE } {delete}
   352  
   353  db close
   354  sqlite3 db test.db
   355  do_execsql_test walmode-8.5  { ATTACH 'test.db2' AS two }          {}
   356  do_execsql_test walmode-8.6  { PRAGMA main.journal_mode }          {wal}
   357  do_execsql_test walmode-8.7  { PRAGMA two.journal_mode  }          {delete}
   358  do_execsql_test walmode-8.8  { INSERT INTO two.t2 DEFAULT VALUES } {}
   359  do_execsql_test walmode-8.9  { PRAGMA two.journal_mode  }          {delete}
   360  do_execsql_test walmode-8.10 { INSERT INTO t1 DEFAULT VALUES } {}
   361  do_execsql_test walmode-8.11 { PRAGMA main.journal_mode  }         {wal}
   362  do_execsql_test walmode-8.12 { PRAGMA journal_mode  }              {wal}
   363  
   364  # Change to WAL mode on test2.db and make sure (in the tests that follow)
   365  # that this mode change persists. 
   366  do_test walmode-8.x1 {
   367    execsql {
   368       PRAGMA two.journal_mode=WAL;
   369       PRAGMA two.journal_mode;
   370    }
   371  } {wal wal}
   372  
   373  db close
   374  sqlite3 db test.db
   375  do_execsql_test walmode-8.13 { PRAGMA journal_mode = WAL }         {wal}
   376  do_execsql_test walmode-8.14 { ATTACH 'test.db2' AS two  }         {}
   377  do_execsql_test walmode-8.15 { PRAGMA main.journal_mode  }         {wal}
   378  do_execsql_test walmode-8.16 { PRAGMA two.journal_mode   }         {wal}
   379  do_execsql_test walmode-8.17 { INSERT INTO two.t2 DEFAULT VALUES } {}
   380  do_execsql_test walmode-8.18 { PRAGMA two.journal_mode   }         {wal}
   381   
   382  sqlite3 db2 test.db2
   383  do_test walmode-8.19 { execsql { PRAGMA main.journal_mode } db2 }  {wal}
   384  db2 close
   385  
   386  do_execsql_test walmode-8.20 { PRAGMA journal_mode = DELETE } {delete}
   387  do_execsql_test walmode-8.21 { PRAGMA main.journal_mode }     {delete}
   388  do_execsql_test walmode-8.22 { PRAGMA two.journal_mode }      {delete}
   389  do_execsql_test walmode-8.21 { PRAGMA journal_mode = WAL }    {wal}
   390  do_execsql_test walmode-8.21 { PRAGMA main.journal_mode }     {wal}
   391  do_execsql_test walmode-8.22 { PRAGMA two.journal_mode }      {wal}
   392  
   393  finish_test