| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | 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 |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | 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 |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | 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 { |
| | |
| | lappend rebase [sqlite3changeset_apply_v2 db $c xConflict] |
| | } |
| | |
| | } |
| | |
| | |
| | |
| | |
| | sqlite3rebaser_create R |
| | foreach r $rebase { |
| | |
| | R configure $r |
| | } |
| | set c1r [R rebase $c1] |
| | R delete |
| | |
| | |
| | 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}} {}} |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | 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.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 |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | 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] |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | 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 |
| |
|