modernc.org/cc@v1.0.1/v2/testdata/_sqlite/ext/session/session5.test (about) 1 # 2011 April 13 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 the session module. 12 # Specifically, for the sqlite3changeset_concat() command. 13 # 14 15 if {![info exists testdir]} { 16 set testdir [file join [file dirname [info script]] .. .. test] 17 } 18 source [file join [file dirname [info script]] session_common.tcl] 19 source $testdir/tester.tcl 20 ifcapable !session {finish_test; return} 21 22 set testprefix session5 23 24 # Organization of tests: 25 # 26 # session5-1.*: Simple tests to check the concat() function produces 27 # correct results. 28 # 29 # session5-2.*: More complicated tests. 30 # 31 # session5-3.*: Schema mismatch errors. 32 # 33 # session5-4.*: Test the concat cases that indicate that the database 34 # was modified in between recording of the two changesets 35 # being concatenated (i.e. two changesets that INSERT rows 36 # with the same PK values). 37 # 38 39 proc do_concat_test {tn args} { 40 41 set subtest 0 42 foreach sql $args { 43 incr subtest 44 sqlite3session S db main ; S attach * 45 execsql $sql 46 47 set c [S changeset] 48 if {[info commands s_prev] != ""} { 49 set c_concat [sqlite3changeset_concat $c_prev $c] 50 set c_two [s_prev changeset] 51 s_prev delete 52 53 set h_concat [changeset_to_list $c_concat] 54 set h_two [changeset_to_list $c_two] 55 56 do_test $tn.$subtest [list set {} $h_concat] $h_two 57 } 58 set c_prev $c 59 rename S s_prev 60 } 61 62 catch { s_prev delete } 63 } 64 65 #------------------------------------------------------------------------- 66 # Test cases session5-1.* - simple tests. 67 # 68 do_execsql_test 1.0 { 69 CREATE TABLE t1(a PRIMARY KEY, b); 70 } 71 72 do_concat_test 1.1.1 { 73 INSERT INTO t1 VALUES(1, 'one'); 74 } { 75 INSERT INTO t1 VALUES(2, 'two'); 76 } 77 78 do_concat_test 1.1.2 { 79 UPDATE t1 SET b = 'five' WHERE a = 1; 80 } { 81 UPDATE t1 SET b = 'six' WHERE a = 2; 82 } 83 84 do_concat_test 1.1.3 { 85 DELETE FROM t1 WHERE a = 1; 86 } { 87 DELETE FROM t1 WHERE a = 2; 88 } 89 90 91 # 1.2.1: INSERT + DELETE -> (none) 92 # 1.2.2: INSERT + UPDATE -> INSERT 93 # 94 # 1.2.3: DELETE + INSERT (matching data) -> (none) 95 # 1.2.4: DELETE + INSERT (non-matching data) -> UPDATE 96 # 97 # 1.2.5: UPDATE + UPDATE (matching data) -> (none) 98 # 1.2.6: UPDATE + UPDATE (non-matching data) -> UPDATE 99 # 1.2.7: UPDATE + DELETE -> DELETE 100 # 101 do_concat_test 1.2.1 { 102 INSERT INTO t1 VALUES('x', 'y'); 103 } { 104 DELETE FROM t1 WHERE a = 'x'; 105 } 106 do_concat_test 1.2.2 { 107 INSERT INTO t1 VALUES(5.0, 'five'); 108 } { 109 UPDATE t1 SET b = 'six' WHERE a = 5.0; 110 } 111 112 do_execsql_test 1.2.3.1 "INSERT INTO t1 VALUES('I', 'one')" 113 do_concat_test 1.2.3.2 { 114 DELETE FROM t1 WHERE a = 'I'; 115 } { 116 INSERT INTO t1 VALUES('I', 'one'); 117 } 118 do_concat_test 1.2.4 { 119 DELETE FROM t1 WHERE a = 'I'; 120 } { 121 INSERT INTO t1 VALUES('I', 'two'); 122 } 123 do_concat_test 1.2.5 { 124 UPDATE t1 SET b = 'five' WHERE a = 'I'; 125 } { 126 UPDATE t1 SET b = 'two' WHERE a = 'I'; 127 } 128 do_concat_test 1.2.6 { 129 UPDATE t1 SET b = 'six' WHERE a = 'I'; 130 } { 131 UPDATE t1 SET b = 'seven' WHERE a = 'I'; 132 } 133 do_concat_test 1.2.7 { 134 UPDATE t1 SET b = 'eight' WHERE a = 'I'; 135 } { 136 DELETE FROM t1 WHERE a = 'I'; 137 } 138 139 140 #------------------------------------------------------------------------- 141 # Test cases session5-2.* - more complex tests. 142 # 143 db function indirect indirect 144 proc indirect {{x -1}} { 145 S indirect $x 146 s_prev indirect $x 147 } 148 do_concat_test 2.1 { 149 CREATE TABLE abc(a, b, c PRIMARY KEY); 150 INSERT INTO abc VALUES(NULL, NULL, 1); 151 INSERT INTO abc VALUES('abcdefghijkl', NULL, 2); 152 } { 153 DELETE FROM abc WHERE c = 1; 154 UPDATE abc SET c = 1 WHERE c = 2; 155 } { 156 INSERT INTO abc VALUES('abcdefghijkl', NULL, 2); 157 INSERT INTO abc VALUES(1.0, 2.0, 3); 158 } { 159 UPDATE abc SET a = a-1; 160 } { 161 CREATE TABLE def(d, e, f, PRIMARY KEY(e, f)); 162 INSERT INTO def VALUES('x', randomblob(11000), 67); 163 INSERT INTO def SELECT d, e, f+1 FROM def; 164 INSERT INTO def SELECT d, e, f+2 FROM def; 165 INSERT INTO def SELECT d, e, f+4 FROM def; 166 } { 167 DELETE FROM def WHERE rowid>4; 168 } { 169 INSERT INTO def SELECT d, e, f+4 FROM def; 170 } { 171 INSERT INTO abc VALUES(22, 44, -1); 172 } { 173 UPDATE abc SET c=-2 WHERE c=-1; 174 UPDATE abc SET c=-3 WHERE c=-2; 175 } { 176 UPDATE abc SET c=-4 WHERE c=-3; 177 } { 178 UPDATE abc SET a=a+1 WHERE c=-3; 179 UPDATE abc SET a=a+1 WHERE c=-3; 180 } { 181 UPDATE abc SET a=a+1 WHERE c=-3; 182 UPDATE abc SET a=a+1 WHERE c=-3; 183 } { 184 INSERT INTO abc VALUES('one', 'two', 'three'); 185 } { 186 SELECT indirect(1); 187 UPDATE abc SET a='one point five' WHERE c = 'three'; 188 } { 189 SELECT indirect(0); 190 UPDATE abc SET a='one point six' WHERE c = 'three'; 191 } { 192 CREATE TABLE x1(a, b, PRIMARY KEY(a)); 193 SELECT indirect(1); 194 INSERT INTO x1 VALUES(1, 2); 195 } { 196 SELECT indirect(1); 197 UPDATE x1 SET b = 3 WHERE a = 1; 198 } 199 200 catch {db close} 201 forcedelete test.db 202 sqlite3 db test.db 203 do_concat_test 2.2 { 204 CREATE TABLE t1(a, b, PRIMARY KEY(b)); 205 CREATE TABLE t2(a PRIMARY KEY, b); 206 INSERT INTO t1 VALUES('string', 1); 207 INSERT INTO t1 VALUES(4, 2); 208 INSERT INTO t1 VALUES(X'FFAAFFAAFFAA', 3); 209 } { 210 INSERT INTO t2 VALUES('one', 'two'); 211 INSERT INTO t2 VALUES(1, NULL); 212 UPDATE t1 SET a = 5 WHERE a = 2; 213 } { 214 DELETE FROM t2 WHERE a = 1; 215 UPDATE t1 SET a = 4 WHERE a = 2; 216 INSERT INTO t2 VALUES('x', 'y'); 217 } 218 219 do_test 2.3.0 { 220 catch {db close} 221 forcedelete test.db 222 sqlite3 db test.db 223 224 set sql1 "" 225 set sql2 "" 226 for {set i 1} {$i < 120} {incr i} { 227 append sql1 "INSERT INTO x1 VALUES($i*4, $i);" 228 } 229 for {set i 1} {$i < 120} {incr i} { 230 append sql2 "DELETE FROM x1 WHERE a = $i*4;" 231 } 232 set {} {} 233 } {} 234 do_concat_test 2.3 { 235 CREATE TABLE x1(a PRIMARY KEY, b) 236 } $sql1 $sql2 $sql1 $sql2 237 238 do_concat_test 2.4 { 239 CREATE TABLE x2(a PRIMARY KEY, b); 240 CREATE TABLE x3(a PRIMARY KEY, b); 241 242 INSERT INTO x2 VALUES('a', 'b'); 243 INSERT INTO x2 VALUES('x', 'y'); 244 INSERT INTO x3 VALUES('a', 'b'); 245 } { 246 INSERT INTO x2 VALUES('c', 'd'); 247 INSERT INTO x3 VALUES('e', 'f'); 248 INSERT INTO x3 VALUES('x', 'y'); 249 } 250 251 do_concat_test 2.5 { 252 UPDATE x3 SET b = 'Y' WHERE a = 'x' 253 } { 254 DELETE FROM x3 WHERE a = 'x' 255 } { 256 DELETE FROM x2 WHERE a = 'a' 257 } { 258 INSERT INTO x2 VALUES('a', 'B'); 259 } 260 261 for {set k 1} {$k <=10} {incr k} { 262 do_test 2.6.$k.1 { 263 drop_all_tables 264 set sql1 "" 265 set sql2 "" 266 for {set i 1} {$i < 120} {incr i} { 267 append sql1 "INSERT INTO x1 VALUES(randomblob(20+(random()%10)), $i);" 268 } 269 for {set i 1} {$i < 120} {incr i} { 270 append sql2 "DELETE FROM x1 WHERE rowid = $i;" 271 } 272 set {} {} 273 } {} 274 do_concat_test 2.6.$k { 275 CREATE TABLE x1(a PRIMARY KEY, b) 276 } $sql1 $sql2 $sql1 $sql2 277 } 278 279 for {set k 1} {$k <=10} {incr k} { 280 do_test 2.7.$k.1 { 281 drop_all_tables 282 set sql1 "" 283 set sql2 "" 284 for {set i 1} {$i < 120} {incr i} { 285 append sql1 { 286 INSERT INTO x1 VALUES( 287 CASE WHEN random()%2 THEN random() ELSE randomblob(20+random()%10) END, 288 CASE WHEN random()%2 THEN random() ELSE randomblob(20+random()%10) END 289 ); 290 } 291 } 292 for {set i 1} {$i < 120} {incr i} { 293 append sql2 "DELETE FROM x1 WHERE rowid = $i;" 294 } 295 set {} {} 296 } {} 297 do_concat_test 2.7.$k { 298 CREATE TABLE x1(a PRIMARY KEY, b) 299 } $sql1 $sql2 $sql1 $sql2 300 } 301 302 303 #------------------------------------------------------------------------- 304 # Test that schema incompatibilities are detected correctly. 305 # 306 # session5-3.1: Incompatible number of columns. 307 # session5-3.2: Incompatible PK definition. 308 # 309 310 do_test 3.1 { 311 db close 312 forcedelete test.db 313 sqlite3 db test.db 314 315 execsql { CREATE TABLE t1(a PRIMARY KEY, b) } 316 set c1 [changeset_from_sql { INSERT INTO t1 VALUES(1, 2) }] 317 execsql { 318 DROP TABLE t1; 319 CREATE TABLE t1(a PRIMARY KEY, b, c); 320 } 321 set c2 [changeset_from_sql { INSERT INTO t1 VALUES(2, 3, 4) }] 322 323 list [catch { sqlite3changeset_concat $c1 $c2 } msg] $msg 324 } {1 SQLITE_SCHEMA} 325 326 do_test 3.2 { 327 db close 328 forcedelete test.db 329 sqlite3 db test.db 330 331 execsql { CREATE TABLE t1(a PRIMARY KEY, b) } 332 set c1 [changeset_from_sql { INSERT INTO t1 VALUES(1, 2) }] 333 execsql { 334 DROP TABLE t1; 335 CREATE TABLE t1(a, b PRIMARY KEY); 336 } 337 set c2 [changeset_from_sql { INSERT INTO t1 VALUES(2, 3) }] 338 339 list [catch { sqlite3changeset_concat $c1 $c2 } msg] $msg 340 } {1 SQLITE_SCHEMA} 341 342 #------------------------------------------------------------------------- 343 # Test that concat() handles these properly: 344 # 345 # session5-4.1: INSERT + INSERT 346 # session5-4.2: UPDATE + INSERT 347 # session5-4.3: DELETE + UPDATE 348 # session5-4.4: DELETE + DELETE 349 # 350 351 proc do_concat_test2 {tn sql1 sqlX sql2 expected} { 352 sqlite3session S db main ; S attach * 353 execsql $sql1 354 set ::c1 [S changeset] 355 S delete 356 357 execsql $sqlX 358 359 sqlite3session S db main ; S attach * 360 execsql $sql2 361 set ::c2 [S changeset] 362 S delete 363 364 uplevel do_test $tn [list { 365 changeset_to_list [sqlite3changeset_concat $::c1 $::c2] 366 }] [list [normalize_list $expected]] 367 } 368 369 drop_all_tables db 370 do_concat_test2 4.1 { 371 CREATE TABLE t1(a PRIMARY KEY, b); 372 INSERT INTO t1 VALUES('key', 'value'); 373 } { 374 DELETE FROM t1 WHERE a = 'key'; 375 } { 376 INSERT INTO t1 VALUES('key', 'xxx'); 377 } { 378 {INSERT t1 0 X. {} {t key t value}} 379 } 380 do_concat_test2 4.2 { 381 UPDATE t1 SET b = 'yyy'; 382 } { 383 DELETE FROM t1 WHERE a = 'key'; 384 } { 385 INSERT INTO t1 VALUES('key', 'value'); 386 } { 387 {UPDATE t1 0 X. {t key t xxx} {{} {} t yyy}} 388 } 389 do_concat_test2 4.3 { 390 DELETE FROM t1 WHERE a = 'key'; 391 } { 392 INSERT INTO t1 VALUES('key', 'www'); 393 } { 394 UPDATE t1 SET b = 'valueX' WHERE a = 'key'; 395 } { 396 {DELETE t1 0 X. {t key t value} {}} 397 } 398 do_concat_test2 4.4 { 399 DELETE FROM t1 WHERE a = 'key'; 400 } { 401 INSERT INTO t1 VALUES('key', 'ttt'); 402 } { 403 DELETE FROM t1 WHERE a = 'key'; 404 } { 405 {DELETE t1 0 X. {t key t valueX} {}} 406 } 407 408 finish_test