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

     1  # 2014 December 04
     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  
    13  set testdir [file dirname $argv0]
    14  source $testdir/tester.tcl
    15  source $testdir/wal_common.tcl
    16  set testprefix e_walauto
    17  
    18  # Do not run this test on OpenBSD, as it depends on read() and mmap both
    19  # accessing the same coherent view of the "test.db-shm" file. This doesn't
    20  # work on OpenBSD.
    21  #
    22  if {$tcl_platform(os) == "OpenBSD"} {
    23    finish_test
    24    return
    25  }
    26  
    27  # This module uses hard-coded offsets which do not work if the reserved_bytes
    28  # value is nonzero.
    29  if {[nonzero_reserved_bytes]} {finish_test; return;}
    30  
    31  
    32  proc read_nbackfill {} {
    33    seek $::shmfd 96
    34    binary scan [read $::shmfd 4] n nBackfill
    35    set nBackfill
    36  }
    37  proc read_mxframe {} {
    38    seek $::shmfd 16
    39    binary scan [read $::shmfd 4] n mxFrame
    40    set mxFrame
    41  }
    42  
    43  # Assuming that the main db for database handle
    44  #
    45  proc do_autocommit_threshold_test {tn value} {
    46  
    47    set nBackfillSaved [read_nbackfill]
    48    while {1} {
    49      db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
    50      if {[read_mxframe] >= $value} break
    51    }
    52    
    53    set nBackfillNew [read_nbackfill]
    54    uplevel [list do_test $tn "expr $nBackfillNew > $nBackfillSaved" 1]
    55  }
    56  
    57  # EVIDENCE-OF: R-30135-06439 The wal_autocheckpoint pragma can be used
    58  # to invoke this interface from SQL.
    59  #
    60  #   All tests in this file are run twice - once using the
    61  #   sqlite3_wal_autocheckpoint() API, and once using "PRAGMA
    62  #   wal_autocheckpoint".
    63  #
    64  foreach {tn code} {
    65    1 {
    66      proc autocheckpoint {db value} {
    67        uplevel [list $db eval "PRAGMA wal_autocheckpoint = $value"]
    68      }
    69    }
    70  
    71    2 {
    72      proc autocheckpoint {db value} {
    73        uplevel [list sqlite3_wal_autocheckpoint $db $value]
    74        return $value
    75      }
    76    }
    77  } {
    78  
    79    eval $code
    80  
    81    reset_db
    82    execsql { PRAGMA auto_vacuum = 0 }
    83    do_execsql_test 1.$tn.0 { PRAGMA journal_mode = WAL } {wal}
    84    do_execsql_test 1.$tn.1 { CREATE TABLE t1(a, b) }
    85    set shmfd [open "test.db-shm" rb]
    86  
    87    # EVIDENCE-OF: R-41531-51083 Every new database connection defaults to
    88    # having the auto-checkpoint enabled with a threshold of 1000 or
    89    # SQLITE_DEFAULT_WAL_AUTOCHECKPOINT pages.
    90    #
    91    do_autocommit_threshold_test 1.$tn.2 1000
    92    db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
    93    do_autocommit_threshold_test 1.$tn.3 1000
    94  
    95    # EVIDENCE-OF: R-38128-34102 The sqlite3_wal_autocheckpoint(D,N) is a
    96    # wrapper around sqlite3_wal_hook() that causes any database on database
    97    # connection D to automatically checkpoint after committing a
    98    # transaction if there are N or more frames in the write-ahead log file.
    99    #
   100    do_test 1.$tn.4 {
   101      db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
   102      autocheckpoint db 100
   103    } {100}
   104    do_autocommit_threshold_test 1.$tn.5 100
   105  
   106    do_test 1.$tn.6 {
   107      db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
   108      autocheckpoint db 500
   109    } {500}
   110    do_autocommit_threshold_test 1.$tn.7 500
   111  
   112    # EVIDENCE-OF: R-26993-43540 Passing zero or a negative value as the
   113    # nFrame parameter disables automatic checkpoints entirely.
   114    #
   115    do_test 1.$tn.7 {
   116      autocheckpoint db 0    ;# Set to zero
   117      for {set i 0} {$i < 10000} {incr i} {
   118        db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
   119      }
   120      expr {[file size test.db-wal] > (5 * 1024 * 1024)}
   121    } 1
   122    do_test 1.$tn.8 {
   123      sqlite3_wal_checkpoint_v2 db truncate
   124      file size test.db-wal
   125    } 0
   126    do_test 1.$tn.9 {
   127      autocheckpoint db -4    ;# Set to a negative value
   128      for {set i 0} {$i < 10000} {incr i} {
   129        db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
   130      }
   131      expr {[file size test.db-wal] > (5 * 1024 * 1024)}
   132    } 1
   133  
   134    # EVIDENCE-OF: R-10203-42688 The callback registered by this function
   135    # replaces any existing callback registered using sqlite3_wal_hook().
   136    #
   137    set ::wal_hook_callback 0
   138    proc wal_hook_callback {args} { incr ::wal_hook_callback ; return 0 }
   139    do_test 1.$tn.10.1 {
   140      db wal_hook wal_hook_callback
   141      db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
   142      db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
   143      set ::wal_hook_callback
   144    } 2
   145    do_test 1.$tn.10.2 {
   146      autocheckpoint db 100
   147      db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
   148      db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
   149      set ::wal_hook_callback
   150    } 2
   151  
   152    # EVIDENCE-OF: R-17497-43474 Likewise, registering a callback using
   153    # sqlite3_wal_hook() disables the automatic checkpoint mechanism
   154    # configured by this function.
   155    do_test 1.$tn.11.1 {
   156      sqlite3_wal_checkpoint_v2 db truncate
   157      file size test.db-wal
   158    } 0
   159    do_test 1.$tn.11.2 {
   160      autocheckpoint db 100 
   161      for {set i 0} {$i < 1000} {incr i} {
   162        db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
   163      }
   164      expr {[file size test.db-wal] < (1 * 1024 * 1024)}
   165    } 1
   166    do_test 1.$tn.11.3 {
   167      db wal_hook wal_hook_callback
   168      for {set i 0} {$i < 1000} {incr i} {
   169        db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
   170      }
   171      expr {[file size test.db-wal] < (1 * 1024 * 1024)}
   172    } 0
   173  
   174    # EVIDENCE-OF: R-33080-59193 Checkpoints initiated by this mechanism 
   175    # are PASSIVE.
   176    #
   177    set ::busy_callback_count 0
   178    proc busy_callback {args} {
   179      incr ::busy_callback_count
   180      return 0
   181    }
   182    do_test 1.$tn.12.1 {
   183      sqlite3_wal_checkpoint_v2 db truncate
   184      autocheckpoint db 100 
   185      db busy busy_callback
   186      db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
   187      db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
   188    } {}
   189    do_test 1.$tn.12.2 {
   190      sqlite3 db2 test.db
   191      db2 eval { BEGIN; SELECT * FROM t1 LIMIT 10; }
   192      read_nbackfill
   193    } {0}
   194    do_test 1.$tn.12.3 {
   195      for {set i 0} {$i < 1000} {incr i} {
   196        db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
   197      }
   198      read_nbackfill
   199    } {2}
   200    do_test 1.$tn.12.4 {
   201      set ::busy_callback_count
   202    } {0}
   203    db2 close
   204  
   205    do_test 1.$tn.12.5 {
   206      db eval { INSERT INTO t1 VALUES(randomblob(100), randomblob(100)) }
   207      read_nbackfill
   208    } {1559}
   209  
   210    db close
   211    close $shmfd
   212  }
   213  
   214  finish_test