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