os/persistentdata/persistentstorage/sqlite3api/TEST/TclScript/incrblob2.test
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/persistentdata/persistentstorage/sqlite3api/TEST/TclScript/incrblob2.test	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,409 @@
     1.4 +# 2008 June 9
     1.5 +#
     1.6 +# The author disclaims copyright to this source code.  In place of
     1.7 +# a legal notice, here is a blessing:
     1.8 +#
     1.9 +#    May you do good and not evil.
    1.10 +#    May you find forgiveness for yourself and forgive others.
    1.11 +#    May you share freely, never taking more than you give.
    1.12 +#
    1.13 +#***********************************************************************
    1.14 +#
    1.15 +# Test that it is possible to have two open blob handles on a single
    1.16 +# blob object.
    1.17 +#
    1.18 +# $Id: incrblob2.test,v 1.8 2008/06/28 15:33:26 danielk1977 Exp $
    1.19 +#
    1.20 +
    1.21 +set testdir [file dirname $argv0]
    1.22 +source $testdir/tester.tcl
    1.23 +
    1.24 +ifcapable {!autovacuum || !pragma || !incrblob} {
    1.25 +  finish_test
    1.26 +  return
    1.27 +}
    1.28 +
    1.29 +do_test incrblob2-1.0 {
    1.30 +  execsql {
    1.31 +    CREATE TABLE blobs(id INTEGER PRIMARY KEY, data BLOB);
    1.32 +    INSERT INTO blobs VALUES(NULL, zeroblob(5000));
    1.33 +    INSERT INTO blobs VALUES(NULL, zeroblob(5000));
    1.34 +    INSERT INTO blobs VALUES(NULL, zeroblob(5000));
    1.35 +    INSERT INTO blobs VALUES(NULL, zeroblob(5000));
    1.36 +  }
    1.37 +} {}
    1.38 +
    1.39 +foreach iOffset [list 0 256 4094] {
    1.40 +  do_test incrblob2-1.$iOffset.1 {
    1.41 +    set fd [db incrblob blobs data 1]
    1.42 +    puts $fd "[string repeat x $iOffset]SQLite version 3.6.0"
    1.43 +    close $fd
    1.44 +  } {}
    1.45 +  
    1.46 +  do_test incrblob2-1.$iOffset.2 {
    1.47 +    set fd1 [db incrblob blobs data 1]
    1.48 +    set fd2 [db incrblob blobs data 1]
    1.49 +    fconfigure $fd1 -buffering none
    1.50 +    fconfigure $fd2 -buffering none
    1.51 +    if {$iOffset != 0} {
    1.52 +      seek $fd2 $iOffset start
    1.53 +      seek $fd1 $iOffset start
    1.54 +    }
    1.55 +    read $fd1 6
    1.56 +  } {SQLite}
    1.57 +  
    1.58 +  do_test incrblob2-1.$iOffset.3 {
    1.59 +    read $fd2 6
    1.60 +  } {SQLite}
    1.61 +  
    1.62 +  do_test incrblob2-1.$iOffset.4 {
    1.63 +    seek $fd2 $iOffset start
    1.64 +    seek $fd1 $iOffset start
    1.65 +    puts -nonewline $fd2 "etiLQS"
    1.66 +  } {}
    1.67 +
    1.68 +  
    1.69 +  do_test incrblob2-1.$iOffset.5 {
    1.70 +    seek $fd1 $iOffset start
    1.71 +    read $fd1 6
    1.72 +  } {etiLQS}
    1.73 +  
    1.74 +  do_test incrblob2-1.$iOffset.6 {
    1.75 +    seek $fd2 $iOffset start
    1.76 +    read $fd2 6
    1.77 +  } {etiLQS}
    1.78 +  
    1.79 +  do_test incrblob2-1.$iOffset.7 {
    1.80 +    seek $fd1 $iOffset start
    1.81 +    read $fd1 6
    1.82 +  } {etiLQS}
    1.83 +  
    1.84 +  do_test incrblob2-1.$iOffset.8 {
    1.85 +    close $fd1
    1.86 +    close $fd2
    1.87 +  } {}
    1.88 +}
    1.89 +
    1.90 +#--------------------------------------------------------------------------
    1.91 +
    1.92 +foreach iOffset [list 0 256 4094] {
    1.93 +
    1.94 +  do_test incrblob2-2.$iOffset.1 {
    1.95 +    set fd1 [db incrblob blobs data 1]
    1.96 +    seek $fd1 [expr $iOffset - 5000] end
    1.97 +    fconfigure $fd1 -buffering none
    1.98 +
    1.99 +    set fd2 [db incrblob blobs data 1]
   1.100 +    seek $fd2 [expr $iOffset - 5000] end
   1.101 +    fconfigure $fd2 -buffering none
   1.102 +
   1.103 +    puts -nonewline $fd1 "123456"
   1.104 +  } {}
   1.105 +  
   1.106 +  do_test incrblob2-2.$iOffset.2 {
   1.107 +    read $fd2 6
   1.108 +  } {123456}
   1.109 +
   1.110 +  do_test incrblob2-2.$iOffset.3 {
   1.111 +    close $fd1
   1.112 +    close $fd2
   1.113 +  } {}
   1.114 +}
   1.115 +
   1.116 +do_test incrblob2-3.1 {
   1.117 +  set fd1 [db incrblob blobs data 1]
   1.118 +  fconfigure $fd1 -buffering none
   1.119 +} {}
   1.120 +do_test incrblob2-3.2 {
   1.121 +  execsql {
   1.122 +    INSERT INTO blobs VALUES(5, zeroblob(10240));
   1.123 +  }
   1.124 +} {}
   1.125 +do_test incrblob2-3.3 {
   1.126 +  set rc [catch { read $fd1 6 } msg]
   1.127 +  list $rc $msg
   1.128 +} {0 123456}
   1.129 +do_test incrblob2-3.4 {
   1.130 +  close $fd1
   1.131 +} {}
   1.132 +
   1.133 +#--------------------------------------------------------------------------
   1.134 +# The following tests - incrblob2-4.* - test that blob handles are 
   1.135 +# invalidated at the correct times.
   1.136 +#
   1.137 +do_test incrblob2-4.1 {
   1.138 +  unset -nocomplain data
   1.139 +  db eval BEGIN
   1.140 +  db eval { CREATE TABLE t1(id INTEGER PRIMARY KEY, data BLOB); }
   1.141 +  for {set ii 1} {$ii < 100} {incr ii} {
   1.142 +    set data [string repeat "blob$ii" 500]
   1.143 +    db eval { INSERT INTO t1 VALUES($ii, $data) }
   1.144 +  }
   1.145 +  db eval COMMIT
   1.146 +} {}
   1.147 +
   1.148 +proc aborted_handles {} {
   1.149 +  global handles
   1.150 +
   1.151 +  set aborted {}
   1.152 +  for {set ii 1} {$ii < 100} {incr ii} {
   1.153 +    set str "blob$ii"
   1.154 +    set nByte [string length $str]
   1.155 +    set iOffset [expr $nByte * $ii * 2]
   1.156 +
   1.157 +    set rc [catch {sqlite3_blob_read $handles($ii) $iOffset $nByte} msg]
   1.158 +    if {$rc && $msg eq "SQLITE_ABORT"} {
   1.159 +      lappend aborted $ii
   1.160 +    } else {
   1.161 +      if {$rc || $msg ne $str} {
   1.162 +        error "blob $ii: $msg"
   1.163 +      }
   1.164 +    }
   1.165 +  }
   1.166 +  set aborted
   1.167 +}
   1.168 +
   1.169 +do_test incrblob2-4.2 {
   1.170 +  for {set ii 1} {$ii < 100} {incr ii} {
   1.171 +    set handles($ii) [db incrblob t1 data $ii]
   1.172 +  }
   1.173 +  aborted_handles
   1.174 +} {}
   1.175 +
   1.176 +# Update row 3. This should abort handle 3 but leave all others untouched.
   1.177 +#
   1.178 +do_test incrblob2-4.3 {
   1.179 +  db eval {UPDATE t1 SET data = data || '' WHERE id = 3}
   1.180 +  aborted_handles
   1.181 +} {3}
   1.182 +
   1.183 +# Test that a write to handle 3 also returns SQLITE_ABORT.
   1.184 +#
   1.185 +do_test incrblob2-4.3.1 {
   1.186 +  set rc [catch {sqlite3_blob_write $::handles(3) 10 HELLO} msg]
   1.187 +  list $rc $msg
   1.188 +} {1 SQLITE_ABORT}
   1.189 +
   1.190 +# Delete row 14. This should abort handle 6 but leave all others untouched.
   1.191 +#
   1.192 +do_test incrblob2-4.4 {
   1.193 +  db eval {DELETE FROM t1 WHERE id = 14}
   1.194 +  aborted_handles
   1.195 +} {3 14}
   1.196 +
   1.197 +# Change the rowid of row 15 to 102. Should abort handle 15.
   1.198 +#
   1.199 +do_test incrblob2-4.5 {
   1.200 +  db eval {UPDATE t1 SET id = 102 WHERE id = 15}
   1.201 +  aborted_handles
   1.202 +} {3 14 15}
   1.203 +
   1.204 +# Clobber row 92 using INSERT OR REPLACE.
   1.205 +#
   1.206 +do_test incrblob2-4.6 {
   1.207 +  db eval {INSERT OR REPLACE INTO t1 VALUES(92, zeroblob(1000))}
   1.208 +  aborted_handles
   1.209 +} {3 14 15 92}
   1.210 +
   1.211 +# Clobber row 65 using UPDATE OR REPLACE on row 35. This should abort 
   1.212 +# handles 35 and 65.
   1.213 +#
   1.214 +do_test incrblob2-4.7 {
   1.215 +  db eval {UPDATE OR REPLACE t1 SET id = 65 WHERE id = 35}
   1.216 +  aborted_handles
   1.217 +} {3 14 15 35 65 92}
   1.218 +
   1.219 +# Insert a couple of new rows. This should not invalidate any handles.
   1.220 +#
   1.221 +do_test incrblob2-4.9 {
   1.222 +  db eval {INSERT INTO t1 SELECT NULL, data FROM t1}
   1.223 +  aborted_handles
   1.224 +} {3 14 15 35 65 92}
   1.225 +
   1.226 +# Delete all rows from 1 to 25. This should abort all handles up to 25.
   1.227 +#
   1.228 +do_test incrblob2-4.9 {
   1.229 +  db eval {DELETE FROM t1 WHERE id >=1 AND id <= 25}
   1.230 +  aborted_handles
   1.231 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 35 65 92}
   1.232 +
   1.233 +# Delete the whole table (this will use sqlite3BtreeClearTable()). All handles
   1.234 +# should now be aborted.
   1.235 +#
   1.236 +do_test incrblob2-4.10 {
   1.237 +  db eval {DELETE FROM t1}
   1.238 +  aborted_handles
   1.239 +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99}
   1.240 +
   1.241 +do_test incrblob2-4.1.X {
   1.242 +  for {set ii 1} {$ii < 100} {incr ii} {
   1.243 +    close $handles($ii) 
   1.244 +  }
   1.245 +} {}
   1.246 +
   1.247 +#--------------------------------------------------------------------------
   1.248 +# The following tests - incrblob2-5.* - test that in shared cache an open
   1.249 +# blob handle counts as a read-lock on its table.
   1.250 +#
   1.251 +ifcapable shared_cache {
   1.252 +  db close
   1.253 +  set ::enable_shared_cache [sqlite3_enable_shared_cache 1]
   1.254 +
   1.255 +  do_test incrblob2-5.1 {
   1.256 +    sqlite3 db test.db
   1.257 +    sqlite3 db2 test.db
   1.258 +
   1.259 +    execsql {
   1.260 +      INSERT INTO t1 VALUES(1, 'abcde');
   1.261 +    }
   1.262 +  } {}
   1.263 +
   1.264 +  do_test incrblob2-5.2 {
   1.265 +    catchsql { INSERT INTO t1 VALUES(2, 'fghij') } db2
   1.266 +  } {0 {}}
   1.267 +
   1.268 +  do_test incrblob2-5.3 {
   1.269 +    set blob [db incrblob t1 data 1]
   1.270 +    catchsql { INSERT INTO t1 VALUES(3, 'klmno') } db2
   1.271 +  } {1 {database is locked}}
   1.272 +
   1.273 +  do_test incrblob2-5.4 {
   1.274 +    close $blob
   1.275 +    execsql BEGIN db2
   1.276 +    catchsql { INSERT INTO t1 VALUES(4, 'pqrst') } db2
   1.277 +  } {0 {}}
   1.278 +
   1.279 +  do_test incrblob2-5.5 {
   1.280 +    set blob [db incrblob -readonly t1 data 1]
   1.281 +    catchsql { INSERT INTO t1 VALUES(5, 'uvwxy') } db2
   1.282 +  } {1 {database table is locked}}
   1.283 +
   1.284 +  do_test incrblob2-5.6 {
   1.285 +    close $blob
   1.286 +    catchsql { INSERT INTO t1 VALUES(3, 'klmno') } db2
   1.287 +  } {0 {}}
   1.288 +
   1.289 +  db2 close
   1.290 +  db close
   1.291 +  sqlite3_enable_shared_cache $::enable_shared_cache
   1.292 +}
   1.293 +
   1.294 +#--------------------------------------------------------------------------
   1.295 +# The following tests - incrblob2-6.* - test a specific scenario that might
   1.296 +# be causing an error.
   1.297 +#
   1.298 +sqlite3 db test.db
   1.299 +do_test incrblob2-6.1 {
   1.300 +  execsql {
   1.301 +    DELETE FROM t1;
   1.302 +    INSERT INTO t1 VALUES(1, zeroblob(100));
   1.303 +  }
   1.304 +  
   1.305 +  set rdHandle [db incrblob -readonly t1 data 1]
   1.306 +  set wrHandle [db incrblob t1 data 1]
   1.307 +
   1.308 +  sqlite3_blob_read $rdHandle 0 100
   1.309 +
   1.310 +  sqlite3_blob_write $wrHandle 0 ABCDEF
   1.311 +
   1.312 +  close $wrHandle
   1.313 +  close $rdHandle
   1.314 +} {}
   1.315 +
   1.316 +do_test incrblob2-6.2 {
   1.317 +  set rdHandle [db incrblob -readonly t1 data 1]
   1.318 +  sqlite3_blob_read $rdHandle 0 2
   1.319 +} {AB}
   1.320 +
   1.321 +do_test incrblob2-6.3 {
   1.322 +  set wrHandle [db incrblob t1 data 1]
   1.323 +  sqlite3_blob_write $wrHandle 0 ZZZZZZZZZZ
   1.324 +  sqlite3_blob_read $rdHandle 2 4
   1.325 +} {ZZZZ}
   1.326 +
   1.327 +do_test incrblob2-6.4 {
   1.328 +  close $wrHandle
   1.329 +  close $rdHandle
   1.330 +} {}
   1.331 +
   1.332 +sqlite3_memory_highwater 1
   1.333 +do_test incrblob2-7.1 {
   1.334 +  db eval {
   1.335 +    CREATE TABLE t2(B BLOB);
   1.336 +    INSERT INTO t2 VALUES(zeroblob(10 * 1024 * 1024)); 
   1.337 +  }
   1.338 +  expr {[sqlite3_memory_highwater]<(5 * 1024 * 1024)}
   1.339 +} {1}
   1.340 +
   1.341 +do_test incrblob2-7.2 {
   1.342 +  set h [db incrblob t2 B 1]
   1.343 +  expr {[sqlite3_memory_highwater]<(5 * 1024 * 1024)}
   1.344 +} {1}
   1.345 +
   1.346 +do_test incrblob2-7.3 {
   1.347 +  seek $h 0 end
   1.348 +  tell $h
   1.349 +} [expr 10 * 1024 * 1024]
   1.350 +
   1.351 +do_test incrblob2-7.4 {
   1.352 +  expr {[sqlite3_memory_highwater]<(5 * 1024 * 1024)}
   1.353 +} {1}
   1.354 +
   1.355 +do_test incrblob2-7.5 {
   1.356 +  close $h
   1.357 +} {}
   1.358 +
   1.359 +#---------------------------------------------------------------------------
   1.360 +# The following tests, incrblob2-8.*, test that nothing terrible happens
   1.361 +# when a statement transaction is rolled back while there are open 
   1.362 +# incremental-blob handles. At one point an assert() was failing when
   1.363 +# this was attempted.
   1.364 +#
   1.365 +do_test incrblob2-8.1 {
   1.366 +  execsql BEGIN
   1.367 +  set h [db incrblob t2 B 1]
   1.368 +  set rc [catch {
   1.369 +    db eval {SELECT ROWID FROM t2} { execsql "DROP TABLE t2" }
   1.370 +  } msg] 
   1.371 +  list $rc $msg
   1.372 +} {1 {database table is locked}}
   1.373 +do_test incrblob2-8.2 {
   1.374 +  close $h
   1.375 +  execsql COMMIT
   1.376 +} {}
   1.377 +do_test incrblob2-8.3 {
   1.378 +  execsql {
   1.379 +    CREATE TABLE t3(a INTEGER UNIQUE, b TEXT);
   1.380 +    INSERT INTO t3 VALUES(1, 'aaaaaaaaaaaaaaaaaaaa');
   1.381 +    INSERT INTO t3 VALUES(2, 'bbbbbbbbbbbbbbbbbbbb');
   1.382 +    INSERT INTO t3 VALUES(3, 'cccccccccccccccccccc');
   1.383 +    INSERT INTO t3 VALUES(4, 'dddddddddddddddddddd');
   1.384 +    INSERT INTO t3 VALUES(5, 'eeeeeeeeeeeeeeeeeeee');
   1.385 +  }
   1.386 +} {}
   1.387 +do_test incrblob2-8.4 {
   1.388 +  execsql BEGIN
   1.389 +  set h [db incrblob t3 b 3]
   1.390 +  sqlite3_blob_read $h 0 20
   1.391 +} {cccccccccccccccccccc}
   1.392 +do_test incrblob2-8.5 {
   1.393 +  catchsql {UPDATE t3 SET a = 6 WHERE a > 3}
   1.394 +} {1 {column a is not unique}}
   1.395 +do_test incrblob2-8.6 {
   1.396 +  catchsql {UPDATE t3 SET a = 6 WHERE a > 3}
   1.397 +} {1 {column a is not unique}}
   1.398 +do_test incrblob2-8.7 {
   1.399 +  sqlite3_blob_read $h 0 20
   1.400 +} {cccccccccccccccccccc}
   1.401 +do_test incrblob2-8.8 {
   1.402 +  catchsql {UPDATE t3 SET a = 6 WHERE a = 3 OR a = 5}
   1.403 +} {1 {column a is not unique}}
   1.404 +do_test incrblob2-8.9 {
   1.405 +  set rc [catch {sqlite3_blob_read $h 0 20} msg]
   1.406 +  list $rc $msg
   1.407 +} {1 SQLITE_ABORT}
   1.408 +do_test incrblob2-8.X {
   1.409 +  close $h
   1.410 +} {}
   1.411 +
   1.412 +finish_test