OLD | NEW |
(Empty) | |
| 1 # 2015-07-31 |
| 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 # |
| 12 # Tests for the [sqldiff --rbu] command. |
| 13 # |
| 14 # |
| 15 if {![info exists testdir]} { |
| 16 set testdir [file join [file dirname [info script]] .. .. test] |
| 17 } |
| 18 source $testdir/tester.tcl |
| 19 set testprefix rbudiff |
| 20 |
| 21 set PROG [test_find_sqldiff] |
| 22 db close |
| 23 |
| 24 proc get_rbudiff_sql {db1 db2} { |
| 25 exec $::PROG --rbu $db1 $db2 |
| 26 } |
| 27 |
| 28 proc get_vtab_rbudiff_sql {db1 db2} { |
| 29 exec $::PROG --vtab --rbu $db1 $db2 |
| 30 } |
| 31 |
| 32 proc step_rbu {target rbu} { |
| 33 while 1 { |
| 34 sqlite3rbu rbu $target $rbu |
| 35 set rc [rbu step] |
| 36 rbu close |
| 37 if {$rc != "SQLITE_OK"} break |
| 38 } |
| 39 set rc |
| 40 } |
| 41 |
| 42 proc apply_rbudiff {sql target} { |
| 43 test_rbucount $sql |
| 44 forcedelete rbu.db |
| 45 sqlite3 rbudb rbu.db |
| 46 rbudb eval $sql |
| 47 rbudb close |
| 48 step_rbu $target rbu.db |
| 49 } |
| 50 |
| 51 proc sqlesc {id} { |
| 52 set ret "'[string map {' ''} $id]'" |
| 53 set ret |
| 54 } |
| 55 |
| 56 # The only argument is the output of an [sqldiff -rbu] run. This command |
| 57 # tests that the contents of the rbu_count table is correct. An exception |
| 58 # is thrown if it is not. |
| 59 # |
| 60 proc test_rbucount {sql} { |
| 61 sqlite3 tmpdb "" |
| 62 tmpdb eval $sql |
| 63 tmpdb eval { |
| 64 SELECT name FROM sqlite_master WHERE name LIKE 'data%' AND type='table' |
| 65 } { |
| 66 set a [tmpdb eval "SELECT count(*) FROM [sqlesc $name]"] |
| 67 set b [tmpdb eval {SELECT cnt FROM rbu_count WHERE tbl = $name}] |
| 68 if {$a != $b} { |
| 69 tmpdb close |
| 70 error "rbu_count error - tbl = $name" |
| 71 } |
| 72 } |
| 73 tmpdb close |
| 74 return "" |
| 75 } |
| 76 |
| 77 proc rbudiff_cksum {db1} { |
| 78 set txt "" |
| 79 |
| 80 sqlite3 dbtmp $db1 |
| 81 foreach tbl [dbtmp eval {SELECT name FROM sqlite_master WHERE type='table'}] { |
| 82 set cols [list] |
| 83 dbtmp eval "PRAGMA table_info = [sqlesc $tbl]" { |
| 84 lappend cols "quote( $name )" |
| 85 } |
| 86 append txt [dbtmp eval \ |
| 87 "SELECT [join $cols {||'.'||}] FROM [sqlesc $tbl] ORDER BY 1" |
| 88 ] |
| 89 } |
| 90 dbtmp close |
| 91 |
| 92 md5 $txt |
| 93 } |
| 94 |
| 95 foreach {tn init mod} { |
| 96 1 { |
| 97 CREATE TABLE t1(a PRIMARY KEY, b, c); |
| 98 INSERT INTO t1 VALUES(1, 2, 3); |
| 99 INSERT INTO t1 VALUES(4, 5, 6); |
| 100 |
| 101 CREATE TABLE t2(a, b, c, PRIMARY KEY(b, c)); |
| 102 INSERT INTO t2 VALUES(1, 2, 3); |
| 103 INSERT INTO t2 VALUES(4, 5, 6); |
| 104 } { |
| 105 INSERT INTO t1 VALUES(7, 8, 9); |
| 106 DELETE FROM t1 WHERE a=4; |
| 107 UPDATE t1 SET c = 11 WHERE a = 1; |
| 108 |
| 109 INSERT INTO t2 VALUES(7, 8, 9); |
| 110 DELETE FROM t2 WHERE a=4; |
| 111 UPDATE t2 SET c = 11 WHERE a = 1; |
| 112 } |
| 113 |
| 114 2 { |
| 115 CREATE TABLE t1(a, b, c, PRIMARY KEY(a, b, c)); |
| 116 INSERT INTO t1 VALUES('u', 'v', 'w'); |
| 117 INSERT INTO t1 VALUES('x', 'y', 'z'); |
| 118 } { |
| 119 DELETE FROM t1 WHERE a='u'; |
| 120 INSERT INTO t1 VALUES('a', 'b', 'c'); |
| 121 } |
| 122 |
| 123 3 { |
| 124 CREATE TABLE t1(i INTEGER PRIMARY KEY, x); |
| 125 INSERT INTO t1 VALUES(1, |
| 126 X'0000000000000000111111111111111122222222222222223333333333333333' |
| 127 ); |
| 128 CREATE TABLE t2(y INTEGER PRIMARY KEY, x); |
| 129 INSERT INTO t2 VALUES(1, |
| 130 X'0000000000000000111111111111111122222222222222223333333333333333' |
| 131 ); |
| 132 } { |
| 133 DELETE FROM t1; |
| 134 INSERT INTO t1 VALUES(1, |
| 135 X'0000000000000000111111111111111122222555555552223333333333333333' |
| 136 ); |
| 137 DELETE FROM t2; |
| 138 INSERT INTO t2 VALUES(1, |
| 139 X'0000000000000000111111111111111122222222222222223333333FFF333333' |
| 140 ); |
| 141 } |
| 142 |
| 143 4 { |
| 144 CREATE TABLE x1(a, b, c, PRIMARY KEY(a, b, c)); |
| 145 INSERT INTO x1 VALUES('u', 'v', NULL); |
| 146 INSERT INTO x1 VALUES('x', 'y', 'z'); |
| 147 INSERT INTO x1 VALUES('a', NULL, 'b'); |
| 148 } { |
| 149 INSERT INTO x1 VALUES('a', 'b', 'c'); |
| 150 } |
| 151 |
| 152 5 { |
| 153 CREATE TABLE t1(a PRIMARY KEY, b); |
| 154 INSERT INTO t1 VALUES(1, NULL); |
| 155 INSERT INTO t1 VALUES(2, X''); |
| 156 } { |
| 157 UPDATE t1 SET b = X'' WHERE a=1; |
| 158 UPDATE t1 SET b = NULL WHERE a=2; |
| 159 } |
| 160 |
| 161 } { |
| 162 catch { db close } |
| 163 |
| 164 forcedelete test.db test.db2 |
| 165 sqlite3 db test.db |
| 166 db eval "$init" |
| 167 sqlite3 db test.db2 |
| 168 db eval "$init ; $mod" |
| 169 db close |
| 170 |
| 171 do_test 1.$tn.2 { |
| 172 set sql [get_rbudiff_sql test.db test.db2] |
| 173 apply_rbudiff $sql test.db |
| 174 } {SQLITE_DONE} |
| 175 do_test 1.$tn.3 { rbudiff_cksum test.db } [rbudiff_cksum test.db2] |
| 176 |
| 177 forcedelete test.db test.db2 |
| 178 sqlite3 db test.db |
| 179 db eval "$init ; $mod" |
| 180 sqlite3 db test.db2 |
| 181 db eval "$init" |
| 182 db close |
| 183 |
| 184 do_test 1.$tn.4 { |
| 185 set sql [get_rbudiff_sql test.db test.db2] |
| 186 apply_rbudiff $sql test.db |
| 187 } {SQLITE_DONE} |
| 188 do_test 1.$tn.5 { rbudiff_cksum test.db } [rbudiff_cksum test.db2] |
| 189 } |
| 190 |
| 191 #------------------------------------------------------------------------- |
| 192 # Test that if the --vtab switch is present, [sqldiff] handles virtual |
| 193 # table types fts[345] and rtree correctly. |
| 194 # |
| 195 ifcapable fts3&&fts5&&rtree { |
| 196 |
| 197 foreach {tn init mod} { |
| 198 1 { |
| 199 CREATE VIRTUAL TABLE t1 USING fts5(c); |
| 200 INSERT INTO t1 VALUES('a b c'); |
| 201 INSERT INTO t1 VALUES('a b c'); |
| 202 } { |
| 203 DELETE FROM t1 WHERE rowid = 1; |
| 204 INSERT INTO t1 VALUES('a b c'); |
| 205 } |
| 206 |
| 207 2 { |
| 208 CREATE VIRTUAL TABLE "x y" USING 'rtree'(id, x1, x2); |
| 209 INSERT INTO "x y" VALUES(1, 2, 3); |
| 210 INSERT INTO "x y" VALUES(2, 4, 6); |
| 211 } { |
| 212 DELETE FROM "x y" WHERE rowid = 1; |
| 213 INSERT INTO "x y" VALUES(3, 6, 9); |
| 214 } |
| 215 |
| 216 3 { |
| 217 CREATE VIRTUAL TABLE 'x''y' USING fts3; |
| 218 INSERT INTO 'x''y' VALUES('one two three'); |
| 219 INSERT INTO 'x''y' VALUES('four five six'); |
| 220 } { |
| 221 DELETE FROM 'x''y' WHERE rowid = 1; |
| 222 INSERT INTO 'x''y' VALUES('one two three'); |
| 223 } |
| 224 } { |
| 225 |
| 226 forcedelete test.db test.db2 |
| 227 sqlite3 db test.db |
| 228 db eval "$init" |
| 229 sqlite3 db test.db2 |
| 230 db eval "$init ; $mod" |
| 231 db close |
| 232 |
| 233 do_test 2.$tn.1 { |
| 234 set sql [get_vtab_rbudiff_sql test.db test.db2] |
| 235 apply_rbudiff $sql test.db |
| 236 } {SQLITE_DONE} |
| 237 do_test 2.$tn.2 { rbudiff_cksum test.db } [rbudiff_cksum test.db2] |
| 238 } |
| 239 |
| 240 } |
| 241 |
| 242 ifcapable fts5 { |
| 243 foreach {tn init mod} { |
| 244 1 { |
| 245 CREATE VIRTUAL TABLE t1 USING fts5(c); |
| 246 INSERT INTO t1 VALUES('a b c'); |
| 247 INSERT INTO t1 VALUES('a b c'); |
| 248 } { |
| 249 DELETE FROM t1 WHERE rowid = 1; |
| 250 INSERT INTO t1 VALUES('a b c'); |
| 251 } |
| 252 |
| 253 2 { |
| 254 CREATE VIRTUAL TABLE t1 USING FTs5(c); |
| 255 INSERT INTO t1 VALUES('a b c'); |
| 256 INSERT INTO t1 VALUES('a b c'); |
| 257 } { |
| 258 DELETE FROM t1 WHERE rowid = 1; |
| 259 INSERT INTO t1 VALUES('a b c'); |
| 260 } |
| 261 |
| 262 3 { |
| 263 creAte virTUal |
| 264 tablE t1 USING FTs5(c); |
| 265 INSERT INTO t1 VALUES('a b c'); |
| 266 INSERT INTO t1 VALUES('a b c'); |
| 267 } { |
| 268 DELETE FROM t1 WHERE rowid = 1; |
| 269 INSERT INTO t1 VALUES('a b c'); |
| 270 } |
| 271 |
| 272 } { |
| 273 forcedelete test.db test.db2 |
| 274 sqlite3 db test.db |
| 275 db eval "$init" |
| 276 sqlite3 db test.db2 |
| 277 db eval "$init ; $mod" |
| 278 db eval { INSERT INTO t1(t1) VALUES('optimize') } |
| 279 db close |
| 280 |
| 281 do_test 3.$tn.1 { |
| 282 set sql [get_vtab_rbudiff_sql test.db test.db2] |
| 283 apply_rbudiff $sql test.db |
| 284 } {SQLITE_DONE} |
| 285 |
| 286 sqlite3 db test.db |
| 287 sqlite3 db2 test.db2 |
| 288 do_test 3.$tn.2 { |
| 289 db2 eval { SELECT * FROM t1 ORDER BY rowid } |
| 290 } [db eval { SELECT * FROM t1 ORDER BY rowid }] |
| 291 |
| 292 do_test 3.$tn.3 { |
| 293 db2 eval { INSERT INTO t1(t1) VALUES('integrity-check') } |
| 294 } {} |
| 295 |
| 296 db close |
| 297 db2 close |
| 298 } |
| 299 } |
| 300 |
| 301 |
| 302 finish_test |
| 303 |
OLD | NEW |