os/persistentdata/persistentstorage/sqlite3api/TEST/TclScript/exclusive.test
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
# 2007 March 24
sl@0
     2
#
sl@0
     3
# The author disclaims copyright to this source code.  In place of
sl@0
     4
# a legal notice, here is a blessing:
sl@0
     5
#
sl@0
     6
#    May you do good and not evil.
sl@0
     7
#    May you find forgiveness for yourself and forgive others.
sl@0
     8
#    May you share freely, never taking more than you give.
sl@0
     9
#
sl@0
    10
#***********************************************************************
sl@0
    11
# This file implements regression tests for SQLite library. The focus
sl@0
    12
# of these tests is exclusive access mode (i.e. the thing activated by 
sl@0
    13
# "PRAGMA locking_mode = EXCLUSIVE").
sl@0
    14
#
sl@0
    15
# $Id: exclusive.test,v 1.9 2008/09/24 14:03:43 danielk1977 Exp $
sl@0
    16
sl@0
    17
set testdir [file dirname $argv0]
sl@0
    18
source $testdir/tester.tcl
sl@0
    19
sl@0
    20
ifcapable {!pager_pragmas} {
sl@0
    21
  finish_test
sl@0
    22
  return
sl@0
    23
}
sl@0
    24
sl@0
    25
file delete -force test2.db-journal
sl@0
    26
file delete -force test2.db
sl@0
    27
file delete -force test3.db-journal
sl@0
    28
file delete -force test3.db
sl@0
    29
file delete -force test4.db-journal
sl@0
    30
file delete -force test4.db
sl@0
    31
sl@0
    32
# The locking mode for the TEMP table is always "exclusive" for
sl@0
    33
# on-disk tables and "normal" for in-memory tables.
sl@0
    34
#
sl@0
    35
if {[info exists TEMP_STORE] && $TEMP_STORE>=2} {
sl@0
    36
  set temp_mode normal
sl@0
    37
} else {
sl@0
    38
  set temp_mode exclusive
sl@0
    39
}
sl@0
    40
sl@0
    41
#----------------------------------------------------------------------
sl@0
    42
# Test cases exclusive-1.X test the PRAGMA logic.
sl@0
    43
#
sl@0
    44
do_test exclusive-1.0 {
sl@0
    45
  execsql {
sl@0
    46
    pragma locking_mode;
sl@0
    47
    pragma main.locking_mode;
sl@0
    48
    pragma temp.locking_mode;
sl@0
    49
  } 
sl@0
    50
} [list normal normal $temp_mode]
sl@0
    51
do_test exclusive-1.1 {
sl@0
    52
  execsql {
sl@0
    53
    pragma locking_mode = exclusive;
sl@0
    54
  } 
sl@0
    55
} {exclusive}
sl@0
    56
do_test exclusive-1.2 {
sl@0
    57
  execsql {
sl@0
    58
    pragma locking_mode;
sl@0
    59
    pragma main.locking_mode;
sl@0
    60
    pragma temp.locking_mode;
sl@0
    61
  } 
sl@0
    62
} [list exclusive exclusive $temp_mode]
sl@0
    63
do_test exclusive-1.3 {
sl@0
    64
  execsql {
sl@0
    65
    pragma locking_mode = normal;
sl@0
    66
  } 
sl@0
    67
} {normal}
sl@0
    68
do_test exclusive-1.4 {
sl@0
    69
  execsql {
sl@0
    70
    pragma locking_mode;
sl@0
    71
    pragma main.locking_mode;
sl@0
    72
    pragma temp.locking_mode;
sl@0
    73
  } 
sl@0
    74
} [list normal normal $temp_mode]
sl@0
    75
do_test exclusive-1.5 {
sl@0
    76
  execsql {
sl@0
    77
    pragma locking_mode = invalid;
sl@0
    78
  } 
sl@0
    79
} {normal}
sl@0
    80
do_test exclusive-1.6 {
sl@0
    81
  execsql {
sl@0
    82
    pragma locking_mode;
sl@0
    83
    pragma main.locking_mode;
sl@0
    84
    pragma temp.locking_mode;
sl@0
    85
  } 
sl@0
    86
} [list normal normal $temp_mode]
sl@0
    87
ifcapable attach {
sl@0
    88
  do_test exclusive-1.7 {
sl@0
    89
    execsql {
sl@0
    90
      pragma locking_mode = exclusive;
sl@0
    91
      ATTACH 'test2.db' as aux;
sl@0
    92
    }
sl@0
    93
    execsql {
sl@0
    94
      pragma main.locking_mode;
sl@0
    95
      pragma aux.locking_mode;
sl@0
    96
    }
sl@0
    97
  } {exclusive exclusive}
sl@0
    98
  do_test exclusive-1.8 {
sl@0
    99
    execsql {
sl@0
   100
      pragma main.locking_mode = normal;
sl@0
   101
    }
sl@0
   102
    execsql {
sl@0
   103
      pragma main.locking_mode;
sl@0
   104
      pragma temp.locking_mode;
sl@0
   105
      pragma aux.locking_mode;
sl@0
   106
    }
sl@0
   107
  } [list normal $temp_mode exclusive]
sl@0
   108
  do_test exclusive-1.9 {
sl@0
   109
    execsql {
sl@0
   110
      pragma locking_mode;
sl@0
   111
    }
sl@0
   112
  } {exclusive}
sl@0
   113
  do_test exclusive-1.10 {
sl@0
   114
    execsql {
sl@0
   115
      ATTACH 'test3.db' as aux2;
sl@0
   116
    }
sl@0
   117
    execsql {
sl@0
   118
      pragma main.locking_mode;
sl@0
   119
      pragma aux.locking_mode;
sl@0
   120
      pragma aux2.locking_mode;
sl@0
   121
    }
sl@0
   122
  } {normal exclusive exclusive}
sl@0
   123
  do_test exclusive-1.11 {
sl@0
   124
    execsql {
sl@0
   125
      pragma aux.locking_mode = normal;
sl@0
   126
    }
sl@0
   127
    execsql {
sl@0
   128
      pragma main.locking_mode;
sl@0
   129
      pragma aux.locking_mode;
sl@0
   130
      pragma aux2.locking_mode;
sl@0
   131
    }
sl@0
   132
  } {normal normal exclusive}
sl@0
   133
  do_test exclusive-1.12 {
sl@0
   134
    execsql {
sl@0
   135
      pragma locking_mode = normal;
sl@0
   136
    }
sl@0
   137
    execsql {
sl@0
   138
      pragma main.locking_mode;
sl@0
   139
      pragma temp.locking_mode;
sl@0
   140
      pragma aux.locking_mode;
sl@0
   141
      pragma aux2.locking_mode;
sl@0
   142
    }
sl@0
   143
  } [list normal $temp_mode normal normal]
sl@0
   144
  do_test exclusive-1.13 {
sl@0
   145
    execsql {
sl@0
   146
      ATTACH 'test4.db' as aux3;
sl@0
   147
    }
sl@0
   148
    execsql {
sl@0
   149
      pragma main.locking_mode;
sl@0
   150
      pragma temp.locking_mode;
sl@0
   151
      pragma aux.locking_mode;
sl@0
   152
      pragma aux2.locking_mode;
sl@0
   153
      pragma aux3.locking_mode;
sl@0
   154
    }
sl@0
   155
  } [list normal $temp_mode normal normal normal]
sl@0
   156
  
sl@0
   157
  do_test exclusive-1.99 {
sl@0
   158
    execsql {
sl@0
   159
      DETACH aux;
sl@0
   160
      DETACH aux2;
sl@0
   161
      DETACH aux3;
sl@0
   162
    }
sl@0
   163
  } {}
sl@0
   164
}
sl@0
   165
sl@0
   166
#----------------------------------------------------------------------
sl@0
   167
# Test cases exclusive-2.X verify that connections in exclusive 
sl@0
   168
# locking_mode do not relinquish locks.
sl@0
   169
#
sl@0
   170
do_test exclusive-2.0 {
sl@0
   171
  execsql {
sl@0
   172
    CREATE TABLE abc(a, b, c);
sl@0
   173
    INSERT INTO abc VALUES(1, 2, 3);
sl@0
   174
    PRAGMA locking_mode = exclusive;
sl@0
   175
  }
sl@0
   176
} {exclusive}
sl@0
   177
do_test exclusive-2.1 {
sl@0
   178
  sqlite3 db2 test.db
sl@0
   179
  execsql {
sl@0
   180
    INSERT INTO abc VALUES(4, 5, 6);
sl@0
   181
    SELECT * FROM abc;
sl@0
   182
  } db2
sl@0
   183
} {1 2 3 4 5 6}
sl@0
   184
do_test exclusive-2.2 {
sl@0
   185
  # This causes connection 'db' (in exclusive mode) to establish 
sl@0
   186
  # a shared-lock on the db. The other connection should now be
sl@0
   187
  # locked out as a writer.
sl@0
   188
  execsql {
sl@0
   189
    SELECT * FROM abc;
sl@0
   190
  } db
sl@0
   191
} {1 2 3 4 5 6}
sl@0
   192
do_test exclusive-2.4 {
sl@0
   193
  execsql {
sl@0
   194
    SELECT * FROM abc;
sl@0
   195
  } db2
sl@0
   196
} {1 2 3 4 5 6}
sl@0
   197
do_test exclusive-2.5 {
sl@0
   198
  catchsql {
sl@0
   199
    INSERT INTO abc VALUES(7, 8, 9);
sl@0
   200
  } db2
sl@0
   201
} {1 {database is locked}}
sl@0
   202
sqlite3_soft_heap_limit 0
sl@0
   203
do_test exclusive-2.6 {
sl@0
   204
  # Because connection 'db' only has a shared-lock, the other connection
sl@0
   205
  # will be able to get a RESERVED, but will fail to upgrade to EXCLUSIVE.
sl@0
   206
  execsql {
sl@0
   207
    BEGIN;
sl@0
   208
    INSERT INTO abc VALUES(7, 8, 9);
sl@0
   209
  } db2
sl@0
   210
  catchsql {
sl@0
   211
    COMMIT
sl@0
   212
  } db2
sl@0
   213
} {1 {database is locked}}
sl@0
   214
do_test exclusive-2.7 {
sl@0
   215
  catchsql {
sl@0
   216
    COMMIT
sl@0
   217
  } db2
sl@0
   218
} {1 {database is locked}}
sl@0
   219
do_test exclusive-2.8 {
sl@0
   220
  execsql {
sl@0
   221
    ROLLBACK;
sl@0
   222
  } db2
sl@0
   223
} {}
sl@0
   224
sqlite3_soft_heap_limit $soft_limit
sl@0
   225
sl@0
   226
do_test exclusive-2.9 {
sl@0
   227
  # Write the database to establish the exclusive lock with connection 'db.
sl@0
   228
  execsql {
sl@0
   229
    INSERT INTO abc VALUES(7, 8, 9);
sl@0
   230
  } db
sl@0
   231
  catchsql {
sl@0
   232
    SELECT * FROM abc;
sl@0
   233
  } db2
sl@0
   234
} {1 {database is locked}}
sl@0
   235
do_test exclusive-2.10 {
sl@0
   236
  # Changing the locking-mode does not release any locks.
sl@0
   237
  execsql {
sl@0
   238
    PRAGMA locking_mode = normal;
sl@0
   239
  } db
sl@0
   240
  catchsql {
sl@0
   241
    SELECT * FROM abc;
sl@0
   242
  } db2
sl@0
   243
} {1 {database is locked}}
sl@0
   244
do_test exclusive-2.11 {
sl@0
   245
  # After changing the locking mode, accessing the db releases locks.
sl@0
   246
  execsql {
sl@0
   247
    SELECT * FROM abc;
sl@0
   248
  } db
sl@0
   249
  execsql {
sl@0
   250
    SELECT * FROM abc;
sl@0
   251
  } db2
sl@0
   252
} {1 2 3 4 5 6 7 8 9}
sl@0
   253
db2 close
sl@0
   254
sl@0
   255
#----------------------------------------------------------------------
sl@0
   256
# Tests exclusive-3.X - test that a connection in exclusive mode 
sl@0
   257
# truncates instead of deletes the journal file when committing 
sl@0
   258
# a transaction.
sl@0
   259
#
sl@0
   260
# These tests are not run on windows because the windows backend
sl@0
   261
# opens the journal file for exclusive access, preventing its contents 
sl@0
   262
# from being inspected externally.
sl@0
   263
#
sl@0
   264
if {$tcl_platform(platform) != "windows"} {
sl@0
   265
  proc filestate {fname} {
sl@0
   266
    set exists 0
sl@0
   267
    set content 0
sl@0
   268
    if {[file exists $fname]} {
sl@0
   269
      set exists 1
sl@0
   270
      set hdr [hexio_read $fname 0 28]
sl@0
   271
      set content \
sl@0
   272
       [expr {$hdr!="00000000000000000000000000000000000000000000000000000000"}]
sl@0
   273
    }
sl@0
   274
    list $exists $content
sl@0
   275
  }
sl@0
   276
  do_test exclusive-3.0 {
sl@0
   277
    filestate test.db-journal
sl@0
   278
  } {0 0}
sl@0
   279
  do_test exclusive-3.1 {
sl@0
   280
    execsql {
sl@0
   281
      PRAGMA locking_mode = exclusive;
sl@0
   282
      BEGIN;
sl@0
   283
      DELETE FROM abc;
sl@0
   284
    }
sl@0
   285
    filestate test.db-journal
sl@0
   286
  } {1 1}
sl@0
   287
  do_test exclusive-3.2 {
sl@0
   288
    execsql {
sl@0
   289
      COMMIT;
sl@0
   290
    }
sl@0
   291
    filestate test.db-journal
sl@0
   292
  } {1 0}
sl@0
   293
  do_test exclusive-3.3 {
sl@0
   294
    execsql {
sl@0
   295
      INSERT INTO abc VALUES('A', 'B', 'C');
sl@0
   296
      SELECT * FROM abc;
sl@0
   297
    }
sl@0
   298
  } {A B C}
sl@0
   299
  do_test exclusive-3.4 {
sl@0
   300
    execsql {
sl@0
   301
      BEGIN;
sl@0
   302
      UPDATE abc SET a = 1, b = 2, c = 3;
sl@0
   303
      ROLLBACK;
sl@0
   304
      SELECT * FROM abc;
sl@0
   305
    }
sl@0
   306
  } {A B C}
sl@0
   307
  do_test exclusive-3.5 {
sl@0
   308
    filestate test.db-journal
sl@0
   309
  } {1 0}
sl@0
   310
  do_test exclusive-3.6 {
sl@0
   311
    execsql {
sl@0
   312
      PRAGMA locking_mode = normal;
sl@0
   313
      SELECT * FROM abc;
sl@0
   314
    }
sl@0
   315
    filestate test.db-journal
sl@0
   316
  } {0 0}
sl@0
   317
}
sl@0
   318
sl@0
   319
#----------------------------------------------------------------------
sl@0
   320
# Tests exclusive-4.X - test that rollback works correctly when
sl@0
   321
# in exclusive-access mode.
sl@0
   322
#
sl@0
   323
sl@0
   324
# The following procedure computes a "signature" for table "t3".  If
sl@0
   325
# T3 changes in any way, the signature should change.  
sl@0
   326
#
sl@0
   327
# This is used to test ROLLBACK.  We gather a signature for t3, then
sl@0
   328
# make lots of changes to t3, then rollback and take another signature.
sl@0
   329
# The two signatures should be the same.
sl@0
   330
#
sl@0
   331
proc signature {} {
sl@0
   332
  return [db eval {SELECT count(*), md5sum(x) FROM t3}]
sl@0
   333
}
sl@0
   334
sl@0
   335
do_test exclusive-4.0 {
sl@0
   336
  execsql { PRAGMA locking_mode = exclusive; }
sl@0
   337
  execsql { PRAGMA default_cache_size = 10; }
sl@0
   338
  execsql {
sl@0
   339
    BEGIN;
sl@0
   340
    CREATE TABLE t3(x TEXT);
sl@0
   341
    INSERT INTO t3 VALUES(randstr(10,400));
sl@0
   342
    INSERT INTO t3 VALUES(randstr(10,400));
sl@0
   343
    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
sl@0
   344
    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
sl@0
   345
    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
sl@0
   346
    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
sl@0
   347
    COMMIT;
sl@0
   348
  }
sl@0
   349
  execsql {SELECT count(*) FROM t3;}
sl@0
   350
} {32}
sl@0
   351
sl@0
   352
set ::X [signature]
sl@0
   353
do_test exclusive-4.1 {
sl@0
   354
  execsql {
sl@0
   355
    BEGIN;
sl@0
   356
    DELETE FROM t3 WHERE random()%10!=0;
sl@0
   357
    INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
sl@0
   358
    INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
sl@0
   359
    SELECT count(*) FROM t3;
sl@0
   360
    ROLLBACK;
sl@0
   361
  }
sl@0
   362
  signature
sl@0
   363
} $::X
sl@0
   364
sl@0
   365
do_test exclusive-4.2 {
sl@0
   366
  execsql {
sl@0
   367
    BEGIN;
sl@0
   368
    DELETE FROM t3 WHERE random()%10!=0;
sl@0
   369
    INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
sl@0
   370
    DELETE FROM t3 WHERE random()%10!=0;
sl@0
   371
    INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
sl@0
   372
    ROLLBACK;
sl@0
   373
  }
sl@0
   374
  signature
sl@0
   375
} $::X
sl@0
   376
sl@0
   377
do_test exclusive-4.3 {
sl@0
   378
  execsql {
sl@0
   379
    INSERT INTO t3 SELECT randstr(10,400) FROM t3 WHERE random()%10==0;
sl@0
   380
  }
sl@0
   381
} {}
sl@0
   382
sl@0
   383
do_test exclusive-4.4 {
sl@0
   384
  catch {set ::X [signature]}
sl@0
   385
} {0}
sl@0
   386
do_test exclusive-4.5 {
sl@0
   387
  execsql {
sl@0
   388
    PRAGMA locking_mode = NORMAL;
sl@0
   389
    DROP TABLE t3;
sl@0
   390
    DROP TABLE abc;
sl@0
   391
  }
sl@0
   392
} {normal}
sl@0
   393
sl@0
   394
#----------------------------------------------------------------------
sl@0
   395
# Tests exclusive-5.X - test that statement journals are truncated
sl@0
   396
# instead of deleted when in exclusive access mode.
sl@0
   397
#
sl@0
   398
sl@0
   399
# Close and reopen the database so that the temp database is no
sl@0
   400
# longer active.
sl@0
   401
#
sl@0
   402
db close
sl@0
   403
sqlite db test.db
sl@0
   404
sl@0
   405
sl@0
   406
do_test exclusive-5.0 {
sl@0
   407
  execsql {
sl@0
   408
    CREATE TABLE abc(a UNIQUE, b UNIQUE, c UNIQUE);
sl@0
   409
    BEGIN;
sl@0
   410
    INSERT INTO abc VALUES(1, 2, 3);
sl@0
   411
    INSERT INTO abc SELECT a+1, b+1, c+1 FROM abc;
sl@0
   412
  }
sl@0
   413
} {}
sl@0
   414
do_test exclusive-5.1 {
sl@0
   415
  # Three files are open: The db, journal and statement-journal.
sl@0
   416
  set sqlite_open_file_count
sl@0
   417
} {3}
sl@0
   418
do_test exclusive-5.2 {
sl@0
   419
  execsql {
sl@0
   420
    COMMIT;
sl@0
   421
  }
sl@0
   422
  # One file open: the db.
sl@0
   423
  set sqlite_open_file_count
sl@0
   424
} {1}
sl@0
   425
do_test exclusive-5.3 {
sl@0
   426
  execsql {
sl@0
   427
    PRAGMA locking_mode = exclusive;
sl@0
   428
    BEGIN;
sl@0
   429
    INSERT INTO abc VALUES(5, 6, 7);
sl@0
   430
  }
sl@0
   431
  # Two files open: the db and journal.
sl@0
   432
  set sqlite_open_file_count
sl@0
   433
} {2}
sl@0
   434
do_test exclusive-5.4 {
sl@0
   435
  execsql {
sl@0
   436
    INSERT INTO abc SELECT a+10, b+10, c+10 FROM abc;
sl@0
   437
  }
sl@0
   438
  # Three files are open: The db, journal and statement-journal.
sl@0
   439
  set sqlite_open_file_count
sl@0
   440
} {3}
sl@0
   441
do_test exclusive-5.5 {
sl@0
   442
  execsql {
sl@0
   443
    COMMIT;
sl@0
   444
  }
sl@0
   445
  # Three files are still open: The db, journal and statement-journal.
sl@0
   446
  set sqlite_open_file_count
sl@0
   447
} {3}
sl@0
   448
do_test exclusive-5.6 {
sl@0
   449
  execsql {
sl@0
   450
    PRAGMA locking_mode = normal;
sl@0
   451
    SELECT * FROM abc;
sl@0
   452
  }
sl@0
   453
} {normal 1 2 3 2 3 4 5 6 7 11 12 13 12 13 14 15 16 17}
sl@0
   454
do_test exclusive-5.7 {
sl@0
   455
  # Just the db open.
sl@0
   456
  set sqlite_open_file_count
sl@0
   457
} {1}
sl@0
   458
sl@0
   459
finish_test