1# 2021 Februar 20 2# 3# The author disclaims copyright to this source code. In place of 4# a legal notice, here is a blessing: 5# 6# May you do good and not evil. 7# May you find forgiveness for yourself and forgive others. 8# May you share freely, never taking more than you give. 9# 10#*********************************************************************** 11# This file implements regression tests for SQLite library. 12# 13 14if {![info exists testdir]} { 15 set testdir [file join [file dirname [info script]] .. .. test] 16} 17source [file join [file dirname [info script]] session_common.tcl] 18source $testdir/tester.tcl 19ifcapable !session {finish_test; return} 20 21set testprefix sessionnoop 22 23#------------------------------------------------------------------------- 24# Test plan: 25# 26# 1.*: Test that concatenating changesets cannot produce a noop UPDATE. 27# 2.*: Test that rebasing changesets cannot produce a noop UPDATE. 28# 3.*: Test that sqlite3changeset_apply() ignores noop UPDATE changes. 29# 30 31do_execsql_test 1.0 { 32 CREATE TABLE t1(a PRIMARY KEY, b, c, d); 33 INSERT INTO t1 VALUES(1, 1, 1, 1); 34 INSERT INTO t1 VALUES(2, 2, 2, 2); 35 INSERT INTO t1 VALUES(3, 3, 3, 3); 36} 37 38proc do_concat_test {tn sql1 sql2 res} { 39 uplevel [list do_test $tn [subst -nocommands { 40 set C1 [changeset_from_sql {$sql1}] 41 set C2 [changeset_from_sql {$sql2}] 42 set C3 [sqlite3changeset_concat [set C1] [set C2]] 43 set got [list] 44 sqlite3session_foreach elem [set C3] { lappend got [set elem] } 45 set got 46 }] [list {*}$res]] 47} 48 49do_concat_test 1.1 { 50 UPDATE t1 SET c=c+1; 51} { 52 UPDATE t1 SET c=c-1; 53} { 54} 55 56#------------------------------------------------------------------------- 57reset_db 58do_execsql_test 2.0 { 59 CREATE TABLE t1(a PRIMARY KEY, b, c); 60 INSERT INTO t1 VALUES(1, 1, 1); 61 INSERT INTO t1 VALUES(2, 2, 2); 62 INSERT INTO t1 VALUES(3, 3, 3); 63} 64 65proc do_rebase_test {tn sql_local sql_remote conflict_res expected} { 66 proc xConflict {args} [list return $conflict_res] 67 68 uplevel [list \ 69 do_test $tn [subst -nocommands { 70 execsql BEGIN 71 set c_remote [changeset_from_sql {$sql_remote}] 72 execsql ROLLBACK 73 74 execsql BEGIN 75 set c_local [changeset_from_sql {$sql_local}] 76 set base [sqlite3changeset_apply_v2 db [set c_remote] xConflict] 77 execsql ROLLBACK 78 79 sqlite3rebaser_create R 80 R config [set base] 81 set res [list] 82 sqlite3session_foreach elem [R rebase [set c_local]] { 83 lappend res [set elem] 84 } 85 R delete 86 set res 87 }] [list {*}$expected] 88 ] 89} 90 91do_rebase_test 2.1 { 92 UPDATE t1 SET c=2 WHERE a=1; -- local 93} { 94 UPDATE t1 SET c=3 WHERE a=1; -- remote 95} OMIT { 96 {UPDATE t1 0 X.. {i 1 {} {} i 3} {{} {} {} {} i 2}} 97} 98 99do_rebase_test 2.2 { 100 UPDATE t1 SET c=2 WHERE a=1; -- local 101} { 102 UPDATE t1 SET c=3 WHERE a=1; -- remote 103} REPLACE { 104} 105 106do_rebase_test 2.3.1 { 107 UPDATE t1 SET c=4 WHERE a=1; -- local 108} { 109 UPDATE t1 SET c=4 WHERE a=1 -- remote 110} OMIT { 111 {UPDATE t1 0 X.. {i 1 {} {} i 4} {{} {} {} {} i 4}} 112} 113 114do_rebase_test 2.3.2 { 115 UPDATE t1 SET c=5 WHERE a=1; -- local 116} { 117 UPDATE t1 SET c=5 WHERE a=1 -- remote 118} REPLACE { 119} 120 121#------------------------------------------------------------------------- 122# 123reset_db 124do_execsql_test 3.0 { 125 CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); 126 INSERT INTO t1 VALUES(1, 1, 1); 127 INSERT INTO t1 VALUES(2, 2, 2); 128 INSERT INTO t1 VALUES(3, 3, 3); 129 INSERT INTO t1 VALUES(4, 4, 4); 130} 131 132# Arg $pkstr contains one character for each column in the table. An 133# "X" for PK column, or a "." for a non-PK. 134# 135proc mk_tbl_header {name pkstr} { 136 set ret [binary format H2c 54 [string length $pkstr]] 137 foreach i [split $pkstr {}] { 138 if {$i=="X"} { 139 append ret [binary format H2 01] 140 } else { 141 if {$i!="."} {error "bad pkstr: $pkstr ($i)"} 142 append ret [binary format H2 00] 143 } 144 } 145 append ret $name 146 append ret [binary format H2 00] 147 set ret 148} 149 150proc mk_update_change {args} { 151 set ret [binary format H2H2 17 00] 152 foreach a $args { 153 if {$a==""} { 154 append ret [binary format H2 00] 155 } else { 156 append ret [binary format H2W 01 $a] 157 } 158 } 159 set ret 160} 161 162proc xConflict {args} { return "ABORT" } 163do_test 3.1 { 164 set C [mk_tbl_header t1 X..] 165 append C [mk_update_change 1 {} 1 {} {} 500] 166 append C [mk_update_change 2 {} {} {} {} {}] 167 append C [mk_update_change 3 3 {} {} 600 {}] 168 append C [mk_update_change 4 {} {} {} {} {}] 169 170 sqlite3changeset_apply_v2 db $C xConflict 171} {} 172do_execsql_test 3.2 { 173 SELECT * FROM t1 174} { 175 1 1 500 176 2 2 2 177 3 600 3 178 4 4 4 179} 180 181 182 183 184 185 186finish_test 187 188