1 2proc do_changeset_test {tn session res} { 3 set r [list] 4 foreach x $res {lappend r $x} 5 uplevel do_test $tn [list [subst -nocommands { 6 set x [list] 7 sqlite3session_foreach c [$session changeset] { lappend x [set c] } 8 set x 9 }]] [list $r] 10} 11 12proc do_patchset_test {tn session res} { 13 set r [list] 14 foreach x $res {lappend r $x} 15 uplevel do_test $tn [list [subst -nocommands { 16 set x [list] 17 sqlite3session_foreach c [$session patchset] { lappend x [set c] } 18 set x 19 }]] [list $r] 20} 21 22 23proc do_changeset_invert_test {tn session res} { 24 set r [list] 25 foreach x $res {lappend r $x} 26 uplevel do_test $tn [list [subst -nocommands { 27 set x [list] 28 set changeset [sqlite3changeset_invert [$session changeset]] 29 sqlite3session_foreach c [set changeset] { lappend x [set c] } 30 set x 31 }]] [list $r] 32} 33 34 35proc do_conflict_test {tn args} { 36 proc xConflict {args} { 37 lappend ::xConflict $args 38 return "" 39 } 40 proc bgerror {args} { set ::background_error $args } 41 42 43 set O(-tables) [list] 44 set O(-sql) [list] 45 set O(-conflicts) [list] 46 47 array set V $args 48 foreach key [array names V] { 49 if {![info exists O($key)]} {error "no such option: $key"} 50 } 51 array set O $args 52 53 sqlite3session S db main 54 foreach t $O(-tables) { S attach $t } 55 execsql $O(-sql) 56 57 set ::xConflict [list] 58 sqlite3changeset_apply db2 [S changeset] xConflict 59 60 set conflicts [list] 61 foreach c $O(-conflicts) { 62 lappend conflicts $c 63 } 64 65 after 1 {set go 1} 66 vwait go 67 68 uplevel do_test $tn [list { set ::xConflict }] [list $conflicts] 69 S delete 70} 71 72proc do_common_sql {sql} { 73 execsql $sql db 74 execsql $sql db2 75} 76 77proc changeset_from_sql {sql {dbname main}} { 78 if {$dbname == "main"} { 79 return [sql_exec_changeset db $sql] 80 } 81 set rc [catch { 82 sqlite3session S db $dbname 83 db eval "SELECT name FROM $dbname.sqlite_master WHERE type = 'table'" { 84 S attach $name 85 } 86 db eval $sql 87 S changeset 88 } changeset] 89 catch { S delete } 90 91 if {$rc} { 92 error $changeset 93 } 94 return $changeset 95} 96 97proc do_then_apply_sql {sql {dbname main}} { 98 proc xConflict args { return "OMIT" } 99 set rc [catch { 100 sqlite3session S db $dbname 101 db eval "SELECT name FROM $dbname.sqlite_master WHERE type = 'table'" { 102 S attach $name 103 } 104 db eval $sql 105 sqlite3changeset_apply db2 [S changeset] xConflict 106 } msg] 107 108 catch { S delete } 109 110 if {$rc} {error $msg} 111} 112 113proc do_iterator_test {tn tbl_list sql res} { 114 sqlite3session S db main 115 if {[llength $tbl_list]==0} { S attach * } 116 foreach t $tbl_list {S attach $t} 117 118 execsql $sql 119 120 set r [list] 121 foreach v $res { lappend r $v } 122 123 set x [list] 124 sqlite3session_foreach c [S changeset] { lappend x $c } 125 uplevel do_test $tn [list [list set {} $x]] [list $r] 126 127 S delete 128} 129 130# Compare the contents of all tables in [db1] and [db2]. Throw an error if 131# they are not identical, or return an empty string if they are. 132# 133proc compare_db {db1 db2} { 134 135 set sql {SELECT name FROM sqlite_master WHERE type = 'table' ORDER BY name} 136 set lot1 [$db1 eval $sql] 137 set lot2 [$db2 eval $sql] 138 139 if {$lot1 != $lot2} { 140 puts $lot1 141 puts $lot2 142 error "databases contain different tables" 143 } 144 145 foreach tbl $lot1 { 146 set col1 [list] 147 set col2 [list] 148 149 $db1 eval "PRAGMA table_info = $tbl" { lappend col1 $name } 150 $db2 eval "PRAGMA table_info = $tbl" { lappend col2 $name } 151 if {$col1 != $col2} { error "table $tbl schema mismatch" } 152 153 set sql "SELECT * FROM $tbl ORDER BY [join $col1 ,]" 154 set data1 [$db1 eval $sql] 155 set data2 [$db2 eval $sql] 156 if {$data1 != $data2} { 157 puts "$data1" 158 puts "$data2" 159 error "table $tbl data mismatch" 160 } 161 } 162 163 return "" 164} 165 166proc changeset_to_list {c} { 167 set list [list] 168 sqlite3session_foreach elem $c { lappend list $elem } 169 lsort $list 170} 171