Download ext/session/sessionrebase.test from AryaWu/sqlite: direct link, hf CLI and curl.
- Browser
- Download file 13.1 kB
-
https://huggingface.co/AryaWu/sqlite/resolve/main/ext/session/sessionrebase.test
- Command line
-
hf download hf://AryaWu/sqlite/ext/session/sessionrebase.test
-
curl -L -o sessionrebase.test https://huggingface.co/AryaWu/sqlite/resolve/main/ext/session/sessionrebase.test
13.1 kB
| # 2018 March 14 | |
| # | |
| # 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. | |
| # | |
| if {![info exists testdir]} { | |
| set testdir [file join [file dirname [info script]] .. .. test] | |
| } | |
| source [file join [file dirname [info script]] session_common.tcl] | |
| source $testdir/tester.tcl | |
| ifcapable !session {finish_test; return} | |
| set testprefix sessionrebase | |
| set ::lConflict [list] | |
| proc xConflict {args} { | |
| set res [lindex $::lConflict 0] | |
| set ::lConflict [lrange $::lConflict 1 end] | |
| return $res | |
| } | |
| #------------------------------------------------------------------------- | |
| # The following test cases - 1.* - test that the rebase blobs output by | |
| # sqlite3_changeset_apply_v2 look correct in some simple cases. The blob | |
| # is itself a changeset, containing records determined as follows: | |
| # | |
| # * For each conflict resolved with REPLACE, the rebase blob contains | |
| # a DELETE record. All fields other than the PK fields are undefined. | |
| # | |
| # * For each conflict resolved with OMIT, the rebase blob contains an | |
| # INSERT record. For an INSERT or UPDATE operation, the indirect flag | |
| # is clear and all updated fields are defined. For a DELETE operation, | |
| # the indirect flag is set and all non-PK fields left undefined. | |
| # | |
| proc do_apply_v2_test {tn sql modsql conflict_handler res} { | |
| execsql BEGIN | |
| sqlite3session S db main | |
| S attach * | |
| execsql $sql | |
| set changeset [S changeset] | |
| S delete | |
| execsql ROLLBACK | |
| execsql BEGIN | |
| execsql $modsql | |
| set ::lConflict $conflict_handler | |
| set blob [sqlite3changeset_apply_v2 db $changeset xConflict] | |
| execsql ROLLBACK | |
| uplevel [list do_test $tn [list changeset_to_list $blob] [list {*}$res]] | |
| } | |
| set ::lConflict [list] | |
| proc xConflict {args} { | |
| set res [lindex $::lConflict 0] | |
| set ::lConflict [lrange $::lConflict 1 end] | |
| return $res | |
| } | |
| # Take a copy of database test.db in file test.db2. Execute $sql1 | |
| # against test.db and $sql2 against test.db2. Capture a changeset | |
| # for each. Then send the test.db2 changeset to test.db and apply | |
| # it with the conflict handlers in $conflict_handler. Patch the | |
| # test.db changeset and then execute it against test.db2. Test that | |
| # the two databases come out the same. | |
| # | |
| proc do_rebase_test {tn sql1 sql2 conflict_handler {testsql ""} {testres ""}} { | |
| for {set i 1} {$i <= 2} {incr i} { | |
| forcedelete test.db2 test.db2-journal test.db2-wal | |
| forcecopy test.db test.db2 | |
| sqlite3 db2 test.db2 | |
| db eval BEGIN | |
| sqlite3session S1 db main | |
| S1 object_config rowid 1 | |
| S1 attach * | |
| execsql $sql1 db | |
| set c1 [S1 changeset] | |
| S1 delete | |
| if {$i==1} { | |
| sqlite3session S2 db2 main | |
| S2 object_config rowid 1 | |
| S2 attach * | |
| execsql $sql2 db2 | |
| set c2 [S2 changeset] | |
| S2 delete | |
| } else { | |
| set c2 [list] | |
| foreach sql [split $sql2 ";"] { | |
| if {[string is space $sql]} continue | |
| sqlite3session S2 db2 main | |
| S2 object_config rowid 1 | |
| S2 attach * | |
| execsql $sql db2 | |
| lappend c2 [S2 changeset] | |
| S2 delete | |
| } | |
| } | |
| set ::lConflict $conflict_handler | |
| set rebase [list] | |
| if {$i==1} { | |
| lappend rebase [sqlite3changeset_apply_v2 db $c2 xConflict] | |
| } else { | |
| foreach c $c2 { | |
| #puts "apply_v2: [changeset_to_list $c]" | |
| lappend rebase [sqlite3changeset_apply_v2 db $c xConflict] | |
| } | |
| #puts "llength: [llength $rebase]" | |
| } | |
| #if {$tn=="2.1.4"} { puts [changeset_to_list $rebase] ; breakpoint } | |
| #puts [changeset_to_list [lindex $rebase 0]] ; breakpoint | |
| #puts [llength $rebase] | |
| sqlite3rebaser_create R | |
| foreach r $rebase { | |
| #puts [changeset_to_list $r] | |
| R configure $r | |
| } | |
| set c1r [R rebase $c1] | |
| R delete | |
| #if {$tn=="2.1.4"} { puts [changeset_to_list $c1r] } | |
| sqlite3changeset_apply_v2 db2 $c1r xConflictAbort | |
| if {[string range $tn end end]!="*"} { | |
| uplevel [list do_test $tn.$i.1 [list compare_db db db2] {}] | |
| } | |
| db2 close | |
| if {$testsql!=""} { | |
| uplevel [list do_execsql_test $tn.$i.2 $testsql $testres] | |
| } | |
| db eval ROLLBACK | |
| } | |
| } | |
| do_execsql_test 1.0 { | |
| CREATE TABLE t1(a INTEGER PRIMARY KEY, b); | |
| INSERT INTO t1 VALUES(1, 'value A'); | |
| } | |
| do_apply_v2_test 1.1.1 { | |
| UPDATE t1 SET b = 'value B' WHERE a=1; | |
| } { | |
| UPDATE t1 SET b = 'value C' WHERE a=1; | |
| } { | |
| OMIT | |
| } { | |
| {INSERT t1 0 X. {} {i 1 t {value B}}} | |
| } | |
| do_apply_v2_test 1.1.2 { | |
| UPDATE t1 SET b = 'value B' WHERE a=1; | |
| } { | |
| UPDATE t1 SET b = 'value C' WHERE a=1; | |
| } { | |
| REPLACE | |
| } { | |
| {INSERT t1 1 X. {} {i 1 t {value B}}} | |
| } | |
| do_apply_v2_test 1.2.1 { | |
| INSERT INTO t1 VALUES(2, 'first'); | |
| } { | |
| INSERT INTO t1 VALUES(2, 'second'); | |
| } { | |
| OMIT | |
| } { | |
| {INSERT t1 0 X. {} {i 2 t first}} | |
| } | |
| do_apply_v2_test 1.2.2 { | |
| INSERT INTO t1 VALUES(2, 'first'); | |
| } { | |
| INSERT INTO t1 VALUES(2, 'second'); | |
| } { | |
| REPLACE | |
| } { | |
| {INSERT t1 1 X. {} {i 2 t first}} | |
| } | |
| do_apply_v2_test 1.3.1 { | |
| DELETE FROM t1 WHERE a=1; | |
| } { | |
| UPDATE t1 SET b='value D' WHERE a=1; | |
| } { | |
| OMIT | |
| } { | |
| {DELETE t1 0 X. {i 1 t {value A}} {}} | |
| } | |
| do_apply_v2_test 1.3.2 { | |
| DELETE FROM t1 WHERE a=1; | |
| } { | |
| UPDATE t1 SET b='value D' WHERE a=1; | |
| } { | |
| REPLACE | |
| } { | |
| {DELETE t1 1 X. {i 1 t {value A}} {}} | |
| } | |
| #------------------------------------------------------------------------- | |
| # Test cases 2.* - simple tests of rebasing actual changesets. | |
| # | |
| # 2.1.1 - 1u2u1r | |
| # 2.1.2 - 1u2u2r | |
| # 2.1.3 - 1d2d | |
| # 2.1.4 - 1d2u1r | |
| # 2.1.5 - 1d2u2r !! | |
| # 2.1.6 - 1u2d1r | |
| # 2.1.7 - 1u2d2r | |
| # | |
| # 2.1.8 - 1i2i2r | |
| # 2.1.9 - 1i2i1r | |
| # | |
| proc xConflictAbort {args} { | |
| return "ABORT" | |
| } | |
| reset_db | |
| do_execsql_test 2.1.0 { | |
| CREATE TABLE t1 (a INTEGER PRIMARY KEY, b TEXT); | |
| INSERT INTO t1 VALUES(1, 'one'); | |
| INSERT INTO t1 VALUES(2, 'two'); | |
| INSERT INTO t1 VALUES(3, 'three'); | |
| } | |
| do_rebase_test 2.1.1 { | |
| UPDATE t1 SET b = 'two.1' WHERE a=2 | |
| } { | |
| UPDATE t1 SET b = 'two.2' WHERE a=2; | |
| } { | |
| OMIT | |
| } { SELECT * FROM t1 } {1 one 2 two.1 3 three} | |
| do_rebase_test 2.1.2 { | |
| UPDATE t1 SET b = 'two.1' WHERE a=2 | |
| } { | |
| UPDATE t1 SET b = 'two.2' WHERE a=2; | |
| } { | |
| REPLACE | |
| } { SELECT * FROM t1 } {1 one 2 two.2 3 three} | |
| do_rebase_test 2.1.3 { | |
| DELETE FROM t1 WHERE a=3 | |
| } { | |
| DELETE FROM t1 WHERE a=3; | |
| } { | |
| OMIT | |
| } { SELECT * FROM t1 } {1 one 2 two} | |
| do_rebase_test 2.1.4 { | |
| DELETE FROM t1 WHERE a=1 | |
| } { | |
| UPDATE t1 SET b='one.2' WHERE a=1 | |
| } { | |
| OMIT | |
| } { SELECT * FROM t1 } {2 two 3 three} | |
| #do_rebase_test 2.1.5 { | |
| # DELETE FROM t1 WHERE a=1; | |
| #} { | |
| # UPDATE t1 SET b='one.2' WHERE a=1 | |
| #} { | |
| # REPLACE | |
| #} { SELECT * FROM t1 } {2 two 3 three} | |
| do_rebase_test 2.1.6 { | |
| UPDATE t1 SET b='three.1' WHERE a=3 | |
| } { | |
| DELETE FROM t1 WHERE a=3; | |
| } { | |
| OMIT | |
| } { SELECT * FROM t1 } {1 one 2 two 3 three.1} | |
| do_rebase_test 2.1.7 { | |
| UPDATE t1 SET b='three.1' WHERE a=3 | |
| } { | |
| DELETE FROM t1 WHERE a=3; | |
| } { | |
| REPLACE | |
| } { SELECT * FROM t1 } {1 one 2 two} | |
| do_rebase_test 2.1.8 { | |
| INSERT INTO t1 VALUES(4, 'four.1') | |
| } { | |
| INSERT INTO t1 VALUES(4, 'four.2'); | |
| } { | |
| REPLACE | |
| } { SELECT * FROM t1 } {1 one 2 two 3 three 4 four.2} | |
| do_rebase_test 2.1.9 { | |
| INSERT INTO t1 VALUES(4, 'four.1') | |
| } { | |
| INSERT INTO t1 VALUES(4, 'four.2'); | |
| } { | |
| OMIT | |
| } { SELECT * FROM t1 } {1 one 2 two 3 three 4 four.1} | |
| do_execsql_test 2.2.0 { | |
| CREATE TABLE t2(x, y, z PRIMARY KEY); | |
| INSERT INTO t2 VALUES('i', 'a', 'A'); | |
| INSERT INTO t2 VALUES('ii', 'b', 'B'); | |
| INSERT INTO t2 VALUES('iii', 'c', 'C'); | |
| CREATE TABLE t3(a INTEGER PRIMARY KEY, b, c); | |
| INSERT INTO t3 VALUES(-1, 'z', 'Z'); | |
| INSERT INTO t3 VALUES(-2, 'y', 'Y'); | |
| } | |
| do_rebase_test 2.2.1 { | |
| UPDATE t2 SET x=1 WHERE z='A' | |
| } { | |
| UPDATE t2 SET y='one' WHERE z='A'; | |
| } { | |
| } { SELECT * FROM t2 WHERE z='A' } { 1 one A } | |
| do_rebase_test 2.2.2 { | |
| UPDATE t2 SET x=1, y='one' WHERE z='B' | |
| } { | |
| UPDATE t2 SET y='two' WHERE z='B'; | |
| } { | |
| REPLACE | |
| } { SELECT * FROM t2 WHERE z='B' } { 1 two B } | |
| do_rebase_test 2.2.3 { | |
| UPDATE t2 SET x=1, y='one' WHERE z='B' | |
| } { | |
| UPDATE t2 SET y='two' WHERE z='B'; | |
| } { | |
| OMIT | |
| } { SELECT * FROM t2 WHERE z='B' } { 1 one B } | |
| reset_db | |
| do_execsql_test 2.3.0 { | |
| CREATE TABLE t1 (b TEXT); | |
| INSERT INTO t1(rowid, b) VALUES(1, 'one'); | |
| INSERT INTO t1(rowid, b) VALUES(2, 'two'); | |
| INSERT INTO t1(rowid, b) VALUES(3, 'three'); | |
| } | |
| do_rebase_test 2.3.1 { | |
| UPDATE t1 SET b = 'two.1' WHERE rowid=2 | |
| } { | |
| UPDATE t1 SET b = 'two.2' WHERE rowid=2; | |
| } { | |
| OMIT | |
| } { SELECT rowid, * FROM t1 } {1 one 2 two.1 3 three} | |
| do_rebase_test 2.3.2 { | |
| UPDATE t1 SET b = 'two.1' WHERE rowid=2 | |
| } { | |
| UPDATE t1 SET b = 'two.2' WHERE rowid=2; | |
| } { | |
| REPLACE | |
| } { SELECT rowid, * FROM t1 } {1 one 2 two.2 3 three} | |
| do_rebase_test 2.3.3 { | |
| DELETE FROM t1 WHERE rowid=3 | |
| } { | |
| DELETE FROM t1 WHERE rowid=3; | |
| } { | |
| OMIT | |
| } { SELECT rowid, * FROM t1 } {1 one 2 two} | |
| do_rebase_test 2.3.4 { | |
| DELETE FROM t1 WHERE rowid=1 | |
| } { | |
| UPDATE t1 SET b='one.2' WHERE rowid=1 | |
| } { | |
| OMIT | |
| } { SELECT rowid, * FROM t1 } {2 two 3 three} | |
| do_rebase_test 2.3.6 { | |
| UPDATE t1 SET b='three.1' WHERE rowid=3 | |
| } { | |
| DELETE FROM t1 WHERE rowid=3; | |
| } { | |
| OMIT | |
| } { SELECT rowid, * FROM t1 } {1 one 2 two 3 three.1} | |
| do_rebase_test 2.3.7 { | |
| UPDATE t1 SET b='three.1' WHERE rowid=3 | |
| } { | |
| DELETE FROM t1 WHERE rowid=3; | |
| } { | |
| REPLACE | |
| } { SELECT rowid, * FROM t1 } {1 one 2 two} | |
| do_rebase_test 2.3.8 { | |
| INSERT INTO t1(rowid, b) VALUES(4, 'four.1') | |
| } { | |
| INSERT INTO t1(rowid, b) VALUES(4, 'four.2'); | |
| } { | |
| REPLACE | |
| } { SELECT rowid, * FROM t1 } {1 one 2 two 3 three 4 four.2} | |
| do_rebase_test 2.3.9 { | |
| INSERT INTO t1(rowid, b) VALUES(4, 'four.1') | |
| } { | |
| INSERT INTO t1(rowid, b) VALUES(4, 'four.2'); | |
| } { | |
| OMIT | |
| } { SELECT rowid, * FROM t1 } {1 one 2 two 3 three 4 four.1} | |
| #------------------------------------------------------------------------- | |
| reset_db | |
| do_execsql_test 3.0 { | |
| CREATE TABLE t3(a, b, c, PRIMARY KEY(b, c)); | |
| CREATE TABLE abcdefghijkl(x PRIMARY KEY, y, z); | |
| INSERT INTO t3 VALUES(1, 2, 3); | |
| INSERT INTO t3 VALUES(4, 2, 5); | |
| INSERT INTO t3 VALUES(7, 2, 9); | |
| INSERT INTO abcdefghijkl VALUES('a', 'b', 'c'); | |
| INSERT INTO abcdefghijkl VALUES('d', 'e', 'f'); | |
| INSERT INTO abcdefghijkl VALUES('g', 'h', 'i'); | |
| } | |
| breakpoint | |
| # do_rebase_test 3.6.tn { | |
| # UPDATE abcdefghijkl SET z='X', y='X' WHERE x='d'; | |
| # } { | |
| # UPDATE abcdefghijkl SET y=1 WHERE x='d'; | |
| # UPDATE abcdefghijkl SET z=1 WHERE x='d'; | |
| # } [list REPLACE REPLACE REPLACE] | |
| foreach {tn p} { | |
| 1 OMIT 2 REPLACE | |
| } { | |
| do_rebase_test 3.1.$tn { | |
| INSERT INTO t3 VALUES(1, 1, 1); | |
| UPDATE abcdefghijkl SET y=2; | |
| } { | |
| INSERT INTO t3 VALUES(4, 1, 1); | |
| DELETE FROM abcdefghijkl; | |
| } [list $p $p $p $p $p $p $p $p] | |
| do_rebase_test 3.2.$tn { | |
| INSERT INTO abcdefghijkl SELECT * FROM t3; | |
| UPDATE t3 SET b=b+1; | |
| } { | |
| INSERT INTO t3 VALUES(3, 3, 3); | |
| INSERT INTO abcdefghijkl SELECT * FROM t3; | |
| } [list $p $p $p $p $p $p $p $p] | |
| do_rebase_test 3.3.$tn { | |
| INSERT INTO abcdefghijkl VALUES(22, 23, 24); | |
| } { | |
| INSERT INTO abcdefghijkl VALUES(22, 25, 26); | |
| UPDATE abcdefghijkl SET y=400 WHERE x=22; | |
| } [list $p $p $p $p $p $p $p $p] | |
| do_rebase_test 3.4.$tn { | |
| INSERT INTO abcdefghijkl VALUES(22, 23, 24); | |
| } { | |
| INSERT INTO abcdefghijkl VALUES(22, 25, 26); | |
| UPDATE abcdefghijkl SET y=400 WHERE x=22; | |
| } [list REPLACE $p] | |
| do_rebase_test 3.5.$tn* { | |
| UPDATE abcdefghijkl SET y='X' WHERE x='d'; | |
| } { | |
| DELETE FROM abcdefghijkl WHERE x='d'; | |
| INSERT INTO abcdefghijkl VALUES('d', NULL, NULL); | |
| } [list $p $p $p] | |
| do_rebase_test 3.5.$tn { | |
| UPDATE abcdefghijkl SET y='X' WHERE x='d'; | |
| } { | |
| DELETE FROM abcdefghijkl WHERE x='d'; | |
| INSERT INTO abcdefghijkl VALUES('d', NULL, NULL); | |
| } [list REPLACE $p $p] | |
| do_rebase_test 3.6.$tn { | |
| UPDATE abcdefghijkl SET z='X', y='X' WHERE x='d'; | |
| } { | |
| UPDATE abcdefghijkl SET y=1 WHERE x='d'; | |
| UPDATE abcdefghijkl SET z=1 WHERE x='d'; | |
| } [list REPLACE $p $p] | |
| } | |
| #------------------------------------------------------------------------- | |
| # Check that apply_v2() does not create a rebase buffer for a patchset. | |
| # And that it is not possible to rebase a patchset. | |
| # | |
| do_execsql_test 4.0 { | |
| CREATE TABLE t5(o PRIMARY KEY, p, q); | |
| INSERT INTO t5 VALUES(1, 2, 3); | |
| INSERT INTO t5 VALUES(4, 5, 6); | |
| } | |
| foreach {tn cmd rebasable} { | |
| 1 patchset 0 | |
| 2 changeset 1 | |
| } { | |
| proc xConflict {args} { return "OMIT" } | |
| do_test 4.1.$tn { | |
| execsql { | |
| BEGIN; | |
| DELETE FROM t5 WHERE o=4; | |
| } | |
| sqlite3session S db main | |
| S attach * | |
| execsql { | |
| INSERT INTO t5 VALUES(4, 'five', 'six'); | |
| } | |
| set P [S $cmd] | |
| S delete | |
| execsql ROLLBACK; | |
| set ::rebase [sqlite3changeset_apply_v2 db $P xConflict] | |
| expr [llength $::rebase]>0 | |
| } $rebasable | |
| } | |
| foreach {tn cmd rebasable} { | |
| 1 patchset 0 | |
| 2 changeset 1 | |
| } { | |
| do_test 4.2.$tn { | |
| sqlite3session S db main | |
| S attach * | |
| execsql { | |
| INSERT INTO t5 VALUES(5+$tn, 'five', 'six'); | |
| } | |
| set P [S $cmd] | |
| S delete | |
| sqlite3rebaser_create R | |
| R configure $::rebase | |
| expr [catch {R rebase $P}]==0 | |
| } $rebasable | |
| catch { R delete } | |
| } | |
| finish_test | |