📄 trans2.test
字号:
# 2008 August 27## The author disclaims copyright to this source code. In place of# a legal notice, here is a blessing:## May you do good and not evil.# May you find forgiveness for yourself and forgive others.# May you share freely, never taking more than you give.##***********************************************************************## This file implements regression tests for SQLite library. The# focus of this script is transactions## $Id: trans2.test,v 1.1 2008/08/27 18:56:36 drh Exp $#set testdir [file dirname $argv0]source $testdir/tester.tcl# A procedure to scramble the elements of list $inlist into a random order.#proc scramble {inlist} { set y {} foreach x $inlist { lappend y [list [expr {rand()}] $x] } set y [lsort $y] set outlist {} foreach x $y { lappend outlist [lindex $x 1] } return $outlist}# Generate a UUID using randomness.#expr srand(1)proc random_uuid {} { set u {} for {set i 0} {$i<5} {incr i} { append u [format %06x [expr {int(rand()*16777216)}]] } return $u}# Compute hashes on the u1 and u2 fields of the sample data.#proc hash1 {} { global data set x "" foreach rec [lsort -integer -index 0 $data] { append x [lindex $rec 1] } return [md5 $x]}proc hash2 {} { global data set x "" foreach rec [lsort -integer -index 0 $data] { append x [lindex $rec 3] } return [md5 $x]}# Create the initial data set#unset -nocomplain data i max_rowid todel n rec max1 id origres newresunset -nocomplain inssql modsql s j zset data {}for {set i 0} {$i<400} {incr i} { set rec [list $i [random_uuid] [expr {int(rand()*5000)+1000}] [random_uuid]] lappend data $rec}set max_rowid [expr {$i-1}]# Create the T1 table used to hold test data. Populate that table with# the initial data set and check hashes to make sure everything is correct.#do_test trans2-1.1 { execsql { PRAGMA cache_size=100; CREATE TABLE t1( id INTEGER PRIMARY KEY, u1 TEXT UNIQUE, z BLOB NOT NULL, u2 TEXT UNIQUE ); } foreach rec [scramble $data] { foreach {id u1 z u2} $rec break db eval {INSERT INTO t1 VALUES($id,$u1,zeroblob($z),$u2)} } db eval {SELECT md5sum(u1), md5sum(u2) FROM t1 ORDER BY id}} [list [hash1] [hash2]]# Repeat the main test loop multiple times.#for {set i 2} {$i<=30} {incr i} { # Delete one row out of every 10 in the database. This will add # many pages to the freelist. # set todel {} set n [expr {[llength $data]/10}] set data [scramble $data] foreach rec [lrange $data 0 $n] { lappend todel [lindex $rec 0] } set data [lrange $data [expr {$n+1}] end] set max1 [lindex [lindex $data 0] 0] foreach rec $data { set id [lindex $rec 0] if {$id>$max1} {set max1 $id} } set origres [list [hash1] [hash2]] do_test trans2-$i.1 { db eval "DELETE FROM t1 WHERE id IN ([join $todel ,])" db eval {SELECT md5sum(u1), md5sum(u2) FROM t1 ORDER BY id} } $origres integrity_check trans2-$i.2 # Begin a transaction and insert many new records. # set newdata {} foreach id $todel { set rec [list $id [random_uuid] \ [expr {int(rand()*5000)+1000}] [random_uuid]] lappend newdata $rec lappend data $rec } for {set j 1} {$j<50} {incr j} { set id [expr {$max_rowid+$j}] lappend todel $id set rec [list $id [random_uuid] \ [expr {int(rand()*5000)+1000}] [random_uuid]] lappend newdata $rec lappend data $rec } set max_rowid [expr {$max_rowid+$j-1}] set modsql {} set inssql {} set newres [list [hash1] [hash2]] do_test trans2-$i.3 { db eval BEGIN foreach rec [scramble $newdata] { foreach {id u1 z u2} $rec break set s "INSERT INTO t1 VALUES($id,'$u1',zeroblob($z),'$u2');" append modsql $s\n append inssql $s\n db eval $s } db eval {SELECT md5sum(u1), md5sum(u2) FROM t1 ORDER BY id} } $newres integrity_check trans2-$i.4 # Do a large update that aborts do to a constraint failure near # the end. This stresses the statement journal mechanism. # do_test trans2-$i.10 { catchsql { UPDATE t1 SET u1=u1||'x', z = CASE WHEN id<$max_rowid THEN zeroblob((random()&65535)%5000 + 1000) END; } } {1 {t1.z may not be NULL}} do_test trans2-$i.11 { db eval {SELECT md5sum(u1), md5sum(u2) FROM t1 ORDER BY id} } $newres # Delete all of the newly inserted records. Verify that the database # is back to its original state. # do_test trans2-$i.20 { set s "DELETE FROM t1 WHERE id IN ([join $todel ,]);" append modsql $s\n db eval $s db eval {SELECT md5sum(u1), md5sum(u2) FROM t1 ORDER BY id} } $origres # Do another large update that aborts do to a constraint failure near # the end. This stresses the statement journal mechanism. # do_test trans2-$i.30 { catchsql { UPDATE t1 SET u1=u1||'x', z = CASE WHEN id<$max1 THEN zeroblob((random()&65535)%5000 + 1000) END; } } {1 {t1.z may not be NULL}} do_test trans2-$i.31 { db eval {SELECT md5sum(u1), md5sum(u2) FROM t1 ORDER BY id} } $origres # Redo the inserts # do_test trans2-$i.40 { db eval $inssql append modsql $inssql db eval {SELECT md5sum(u1), md5sum(u2) FROM t1 ORDER BY id} } $newres # Rollback the transaction. Verify that the content is restored. # do_test trans2-$i.90 { db eval ROLLBACK db eval {SELECT md5sum(u1), md5sum(u2) FROM t1 ORDER BY id} } $origres integrity_check trans2-$i.91 # Repeat all the changes, but this time commit. # do_test trans2-$i.92 { db eval BEGIN catchsql { UPDATE t1 SET u1=u1||'x', z = CASE WHEN id<$max1 THEN zeroblob((random()&65535)%5000 + 1000) END; } db eval $modsql catchsql { UPDATE t1 SET u1=u1||'x', z = CASE WHEN id<$max1 THEN zeroblob((random()&65535)%5000 + 1000) END; } db eval COMMIT db eval {SELECT md5sum(u1), md5sum(u2) FROM t1 ORDER BY id} } $newres integrity_check trans2-$i.93}unset -nocomplain data i max_rowid todel n rec max1 id origres newresunset -nocomplain inssql modsql s j zfinish_test
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -