1# 2011 March 07 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 session1 22 23# Run all tests in this file twice. Once with "WITHOUT ROWID", and once 24# with regular rowid tables. 25# 26foreach {tn trailing} { 27 1 "" 28 2 " WITHOUT ROWID " 29} { 30eval [string map [list %WR% $trailing] { 31 32db close 33forcedelete test.db test.db2 34reset_db 35 36do_execsql_test $tn.1.0 { 37 CREATE TABLE t1(x PRIMARY KEY, y) %WR%; 38 INSERT INTO t1 VALUES('abc', 'def'); 39} 40 41#------------------------------------------------------------------------- 42# Test creating, attaching tables to and deleting session objects. 43# 44do_test $tn.1.1 { sqlite3session S db main } {S} 45do_test $tn.1.2 { S delete } {} 46do_test $tn.1.3 { sqlite3session S db main } {S} 47do_test $tn.1.4 { S attach t1 } {} 48do_test $tn.1.5 { S delete } {} 49do_test $tn.1.6 { sqlite3session S db main } {S} 50do_test $tn.1.7 { S attach t1 ; S attach t2 ; S attach t3 } {} 51do_test $tn.1.8 { S attach t1 ; S attach t2 ; S attach t3 } {} 52do_test $tn.1.9 { S delete } {} 53do_test $tn.1.10 { 54 sqlite3session S db main 55 S attach t1 56 execsql { INSERT INTO t1 VALUES('ghi', 'jkl') } 57} {} 58do_test $tn.1.11 { S delete } {} 59if {$tn==1} { 60 do_test $tn.1.12 { 61 sqlite3session S db main 62 S attach t1 63 execsql { INSERT INTO t1 VALUES('mno', 'pqr') } 64 execsql { UPDATE t1 SET x = 111 WHERE rowid = 1 } 65 execsql { DELETE FROM t1 WHERE rowid = 2 } 66 } {} 67 do_test $tn.1.13 { 68 S changeset 69 S delete 70 } {} 71} 72 73#------------------------------------------------------------------------- 74# Simple changeset tests. Also test the sqlite3changeset_invert() 75# function. 76# 77do_test $tn.2.1.1 { 78 execsql { DELETE FROM t1 } 79 sqlite3session S db main 80 S attach t1 81 execsql { INSERT INTO t1 VALUES(1, 'Sukhothai') } 82 execsql { INSERT INTO t1 VALUES(2, 'Ayutthaya') } 83 execsql { INSERT INTO t1 VALUES(3, 'Thonburi') } 84} {} 85do_changeset_test $tn.2.1.2 S { 86 {INSERT t1 0 X. {} {i 1 t Sukhothai}} 87 {INSERT t1 0 X. {} {i 2 t Ayutthaya}} 88 {INSERT t1 0 X. {} {i 3 t Thonburi}} 89} 90do_changeset_invert_test $tn.2.1.3 S { 91 {DELETE t1 0 X. {i 1 t Sukhothai} {}} 92 {DELETE t1 0 X. {i 2 t Ayutthaya} {}} 93 {DELETE t1 0 X. {i 3 t Thonburi} {}} 94} 95do_test $tn.2.1.4 { S delete } {} 96 97do_test $tn.2.2.1 { 98 sqlite3session S db main 99 S attach t1 100 execsql { DELETE FROM t1 WHERE 1 } 101} {} 102do_changeset_test $tn.2.2.2 S { 103 {DELETE t1 0 X. {i 1 t Sukhothai} {}} 104 {DELETE t1 0 X. {i 2 t Ayutthaya} {}} 105 {DELETE t1 0 X. {i 3 t Thonburi} {}} 106} 107do_changeset_invert_test $tn.2.2.3 S { 108 {INSERT t1 0 X. {} {i 1 t Sukhothai}} 109 {INSERT t1 0 X. {} {i 2 t Ayutthaya}} 110 {INSERT t1 0 X. {} {i 3 t Thonburi}} 111} 112do_test $tn.2.2.4 { S delete } {} 113 114do_test $tn.2.3.1 { 115 execsql { DELETE FROM t1 } 116 sqlite3session S db main 117 execsql { INSERT INTO t1 VALUES(1, 'Sukhothai') } 118 execsql { INSERT INTO t1 VALUES(2, 'Ayutthaya') } 119 execsql { INSERT INTO t1 VALUES(3, 'Thonburi') } 120 S attach t1 121 execsql { 122 UPDATE t1 SET x = 10 WHERE x = 1; 123 UPDATE t1 SET y = 'Surin' WHERE x = 2; 124 UPDATE t1 SET x = 20, y = 'Thapae' WHERE x = 3; 125 } 126} {} 127 128do_changeset_test $tn.2.3.2 S { 129 {INSERT t1 0 X. {} {i 10 t Sukhothai}} 130 {DELETE t1 0 X. {i 1 t Sukhothai} {}} 131 {UPDATE t1 0 X. {i 2 t Ayutthaya} {{} {} t Surin}} 132 {DELETE t1 0 X. {i 3 t Thonburi} {}} 133 {INSERT t1 0 X. {} {i 20 t Thapae}} 134} 135 136do_changeset_invert_test $tn.2.3.3 S { 137 {DELETE t1 0 X. {i 10 t Sukhothai} {}} 138 {INSERT t1 0 X. {} {i 1 t Sukhothai}} 139 {UPDATE t1 0 X. {i 2 t Surin} {{} {} t Ayutthaya}} 140 {INSERT t1 0 X. {} {i 3 t Thonburi}} 141 {DELETE t1 0 X. {i 20 t Thapae} {}} 142} 143do_test $tn.2.3.4 { S delete } {} 144 145do_test $tn.2.4.1 { 146 sqlite3session S db main 147 S attach t1 148 execsql { INSERT INTO t1 VALUES(100, 'Bangkok') } 149 execsql { DELETE FROM t1 WHERE x = 100 } 150} {} 151do_changeset_test $tn.2.4.2 S {} 152do_changeset_invert_test $tn.2.4.3 S {} 153do_test $tn.2.4.4 { S delete } {} 154 155#------------------------------------------------------------------------- 156# Test the application of simple changesets. These tests also test that 157# the conflict callback is invoked correctly. For these tests, the 158# conflict callback always returns OMIT. 159# 160db close 161forcedelete test.db test.db2 162sqlite3 db test.db 163sqlite3 db2 test.db2 164 165proc xConflict {args} { 166 lappend ::xConflict $args 167 return "" 168} 169 170proc bgerror {args} { set ::background_error $args } 171 172proc do_conflict_test {tn args} { 173 set O(-tables) [list] 174 set O(-sql) [list] 175 set O(-conflicts) [list] 176 177 array set V $args 178 foreach key [array names V] { 179 if {![info exists O($key)]} {error "no such option: $key"} 180 } 181 array set O $args 182 183 sqlite3session S db main 184 foreach t $O(-tables) { S attach $t } 185 execsql $O(-sql) 186 set ::xConflict [list] 187 sqlite3changeset_apply db2 [S changeset] xConflict 188 189 set conflicts [list] 190 foreach c $O(-conflicts) { 191 lappend conflicts $c 192 } 193 194 after 1 {set go 1} 195 vwait go 196 197 uplevel do_test $tn [list { set ::xConflict }] [list $conflicts] 198 S delete 199} 200 201proc do_db2_test {testname sql {result {}}} { 202 uplevel do_test $testname [list "execsql {$sql} db2"] [list [list {*}$result]] 203} 204 205# Test INSERT changesets. 206# 207do_test $tn.3.1.0 { 208 execsql { CREATE TABLE t1(a PRIMARY KEY, b NOT NULL) %WR% } db2 209 execsql { 210 CREATE TABLE t1(a PRIMARY KEY, b) %WR%; 211 INSERT INTO t1 VALUES(1, 'one'); 212 INSERT INTO t1 VALUES(2, 'two'); 213 } db 214} {} 215do_db2_test $tn.3.1.1 "INSERT INTO t1 VALUES(6, 'VI')" 216do_conflict_test $tn.3.1.2 -tables t1 -sql { 217 INSERT INTO t1 VALUES(3, 'three'); 218 INSERT INTO t1 VALUES(4, 'four'); 219 INSERT INTO t1 VALUES(5, 'five'); 220 INSERT INTO t1 VALUES(6, 'six'); 221 INSERT INTO t1 VALUES(7, 'seven'); 222 INSERT INTO t1 VALUES(8, NULL); 223} -conflicts { 224 {INSERT t1 CONFLICT {i 6 t six} {i 6 t VI}} 225 {INSERT t1 CONSTRAINT {i 8 n {}}} 226} 227 228do_db2_test $tn.3.1.3 "SELECT * FROM t1 ORDER BY a" { 229 3 three 4 four 5 five 6 VI 7 seven 230} 231do_execsql_test $tn.3.1.4 "SELECT * FROM t1" { 232 1 one 2 two 3 three 4 four 5 five 6 six 7 seven 8 {} 233} 234 235# Test DELETE changesets. 236# 237do_execsql_test $tn.3.2.1 { 238 PRAGMA foreign_keys = on; 239 CREATE TABLE t2(a PRIMARY KEY, b)%WR%; 240 CREATE TABLE t3(c, d REFERENCES t2); 241 INSERT INTO t2 VALUES(1, 'one'); 242 INSERT INTO t2 VALUES(2, 'two'); 243 INSERT INTO t2 VALUES(3, 'three'); 244 INSERT INTO t2 VALUES(4, 'four'); 245} 246do_db2_test $tn.3.2.2 { 247 PRAGMA foreign_keys = on; 248 CREATE TABLE t2(a PRIMARY KEY, b)%WR%; 249 CREATE TABLE t3(c, d REFERENCES t2); 250 INSERT INTO t2 VALUES(1, 'one'); 251 INSERT INTO t2 VALUES(2, 'two'); 252 INSERT INTO t2 VALUES(4, 'five'); 253 INSERT INTO t3 VALUES('i', 1); 254} 255do_conflict_test $tn.3.2.3 -tables t2 -sql { 256 DELETE FROM t2 WHERE a = 1; 257 DELETE FROM t2 WHERE a = 2; 258 DELETE FROM t2 WHERE a = 3; 259 DELETE FROM t2 WHERE a = 4; 260} -conflicts { 261 {DELETE t2 NOTFOUND {i 3 t three}} 262 {DELETE t2 DATA {i 4 t four} {i 4 t five}} 263 {FOREIGN_KEY 1} 264} 265do_execsql_test $tn.3.2.4 "SELECT * FROM t2" {} 266do_db2_test $tn.3.2.5 "SELECT * FROM t2" {4 five} 267 268# Test UPDATE changesets. 269# 270do_execsql_test $tn.3.3.1 { 271 CREATE TABLE t4(a, b, c, PRIMARY KEY(b, c))%WR%; 272 INSERT INTO t4 VALUES(1, 2, 3); 273 INSERT INTO t4 VALUES(4, 5, 6); 274 INSERT INTO t4 VALUES(7, 8, 9); 275 INSERT INTO t4 VALUES(10, 11, 12); 276} 277do_db2_test $tn.3.3.2 { 278 CREATE TABLE t4(a NOT NULL, b, c, PRIMARY KEY(b, c))%WR%; 279 INSERT INTO t4 VALUES(0, 2, 3); 280 INSERT INTO t4 VALUES(4, 5, 7); 281 INSERT INTO t4 VALUES(7, 8, 9); 282 INSERT INTO t4 VALUES(10, 11, 12); 283} 284do_conflict_test $tn.3.3.3 -tables t4 -sql { 285 UPDATE t4 SET a = -1 WHERE b = 2; 286 UPDATE t4 SET a = -1 WHERE b = 5; 287 UPDATE t4 SET a = NULL WHERE c = 9; 288 UPDATE t4 SET a = 'x' WHERE b = 11; 289} -conflicts { 290 {UPDATE t4 DATA {i 1 i 2 i 3} {i -1 {} {} {} {}} {i 0 i 2 i 3}} 291 {UPDATE t4 NOTFOUND {i 4 i 5 i 6} {i -1 {} {} {} {}}} 292 {UPDATE t4 CONSTRAINT {i 7 i 8 i 9} {n {} {} {} {} {}}} 293} 294do_db2_test $tn.3.3.4 { SELECT * FROM t4 } {0 2 3 4 5 7 7 8 9 x 11 12} 295do_execsql_test $tn.3.3.5 { SELECT * FROM t4 } {-1 2 3 -1 5 6 {} 8 9 x 11 12} 296 297#------------------------------------------------------------------------- 298# This next block of tests verifies that values returned by the conflict 299# handler are intepreted correctly. 300# 301 302proc test_reset {} { 303 db close 304 db2 close 305 forcedelete test.db test.db2 306 sqlite3 db test.db 307 sqlite3 db2 test.db2 308} 309 310proc xConflict {args} { 311 lappend ::xConflict $args 312 return $::conflict_return 313} 314 315foreach {tn2 conflict_return after} { 316 1 OMIT {1 2 value1 4 5 7 10 x x} 317 2 REPLACE {1 2 value1 4 5 value2 10 8 9} 318} { 319 test_reset 320 321 do_test $tn.4.$tn2.1 { 322 foreach db {db db2} { 323 execsql { 324 CREATE TABLE t1(a, b, c, PRIMARY KEY(a))%WR%; 325 INSERT INTO t1 VALUES(1, 2, 3); 326 INSERT INTO t1 VALUES(4, 5, 6); 327 INSERT INTO t1 VALUES(7, 8, 9); 328 } $db 329 } 330 execsql { 331 REPLACE INTO t1 VALUES(4, 5, 7); 332 REPLACE INTO t1 VALUES(10, 'x', 'x'); 333 } db2 334 } {} 335 336 do_conflict_test $tn.4.$tn2.2 -tables t1 -sql { 337 UPDATE t1 SET c = 'value1' WHERE a = 1; -- no conflict 338 UPDATE t1 SET c = 'value2' WHERE a = 4; -- DATA conflict 339 UPDATE t1 SET a = 10 WHERE a = 7; -- CONFLICT conflict 340 } -conflicts { 341 {INSERT t1 CONFLICT {i 10 i 8 i 9} {i 10 t x t x}} 342 {UPDATE t1 DATA {i 4 {} {} i 6} {{} {} {} {} t value2} {i 4 i 5 i 7}} 343 } 344 345 do_db2_test $tn.4.$tn2.3 "SELECT * FROM t1 ORDER BY a" $after 346} 347 348foreach {tn2 conflict_return} { 349 1 OMIT 350 2 REPLACE 351} { 352 test_reset 353 354 do_test $tn.5.$tn2.1 { 355 # Create an identical schema in both databases. 356 set schema { 357 CREATE TABLE "'foolish name'"(x, y, z, PRIMARY KEY(x, y))%WR%; 358 } 359 execsql $schema db 360 execsql $schema db2 361 362 # Add some rows to [db2]. These rows will cause conflicts later 363 # on when the changeset from [db] is applied to it. 364 execsql { 365 INSERT INTO "'foolish name'" VALUES('one', 'one', 'ii'); 366 INSERT INTO "'foolish name'" VALUES('one', 'two', 'i'); 367 INSERT INTO "'foolish name'" VALUES('two', 'two', 'ii'); 368 } db2 369 370 } {} 371 372 do_conflict_test $tn.5.$tn2.2 -tables {{'foolish name'}} -sql { 373 INSERT INTO "'foolish name'" VALUES('one', 'two', 2); 374 } -conflicts { 375 {INSERT {'foolish name'} CONFLICT {t one t two i 2} {t one t two t i}} 376 } 377 378 set res(REPLACE) {one one ii one two 2 two two ii} 379 set res(OMIT) {one one ii one two i two two ii} 380 do_db2_test $tn.5.$tn2.3 { 381 SELECT * FROM "'foolish name'" ORDER BY x, y 382 } $res($conflict_return) 383 384 385 do_test $tn.5.$tn2.1 { 386 set schema { 387 CREATE TABLE d1("z""z" PRIMARY KEY, y)%WR%; 388 INSERT INTO d1 VALUES(1, 'one'); 389 INSERT INTO d1 VALUES(2, 'two'); 390 } 391 execsql $schema db 392 execsql $schema db2 393 394 execsql { 395 UPDATE d1 SET y = 'TWO' WHERE "z""z" = 2; 396 } db2 397 398 } {} 399 400 do_conflict_test $tn.5.$tn2.2 -tables d1 -sql { 401 DELETE FROM d1 WHERE "z""z" = 2; 402 } -conflicts { 403 {DELETE d1 DATA {i 2 t two} {i 2 t TWO}} 404 } 405 406 set res(REPLACE) {1 one} 407 set res(OMIT) {1 one 2 TWO} 408 do_db2_test $tn.5.$tn2.3 "SELECT * FROM d1" $res($conflict_return) 409} 410 411#------------------------------------------------------------------------- 412# Test that two tables can be monitored by a single session object. 413# 414test_reset 415set schema { 416 CREATE TABLE t1(a COLLATE nocase PRIMARY KEY, b)%WR%; 417 CREATE TABLE t2(a, b PRIMARY KEY)%WR%; 418} 419do_test $tn.6.0 { 420 execsql $schema db 421 execsql $schema db2 422 execsql { 423 INSERT INTO t1 VALUES('a', 'b'); 424 INSERT INTO t2 VALUES('a', 'b'); 425 } db2 426} {} 427 428set conflict_return "" 429do_conflict_test $tn.6.1 -tables {t1 t2} -sql { 430 INSERT INTO t1 VALUES('1', '2'); 431 INSERT INTO t1 VALUES('A', 'B'); 432 INSERT INTO t2 VALUES('A', 'B'); 433} -conflicts { 434 {INSERT t1 CONFLICT {t A t B} {t a t b}} 435} 436 437do_db2_test $tn.6.2 "SELECT * FROM t1 ORDER BY a" {1 2 a b} 438do_db2_test $tn.6.3 "SELECT * FROM t2 ORDER BY a" {A B a b} 439 440#------------------------------------------------------------------------- 441# Test that session objects are not confused by changes to table in 442# other databases. 443# 444catch { db2 close } 445drop_all_tables 446forcedelete test.db2 447do_iterator_test $tn.7.1 * { 448 ATTACH 'test.db2' AS aux; 449 CREATE TABLE main.t1(x PRIMARY KEY, y)%WR%; 450 CREATE TABLE aux.t1(x PRIMARY KEY, y)%WR%; 451 452 INSERT INTO main.t1 VALUES('one', 1); 453 INSERT INTO main.t1 VALUES('two', 2); 454 INSERT INTO aux.t1 VALUES('three', 3); 455 INSERT INTO aux.t1 VALUES('four', 4); 456} { 457 {INSERT t1 0 X. {} {t two i 2}} 458 {INSERT t1 0 X. {} {t one i 1}} 459} 460 461#------------------------------------------------------------------------- 462# Test the sqlite3session_isempty() function. 463# 464do_test $tn.8.1 { 465 execsql { 466 CREATE TABLE t5(x PRIMARY KEY, y)%WR%; 467 CREATE TABLE t6(x PRIMARY KEY, y)%WR%; 468 INSERT INTO t5 VALUES('a', 'b'); 469 INSERT INTO t6 VALUES('a', 'b'); 470 } 471 sqlite3session S db main 472 S attach * 473 474 S isempty 475} {1} 476do_test $tn.8.2 { 477 execsql { DELETE FROM t5 } 478 S isempty 479} {0} 480do_test $tn.8.3 { 481 S delete 482 sqlite3session S db main 483 S attach t5 484 execsql { DELETE FROM t5 } 485 S isempty 486} {1} 487do_test $tn.8.4 { S delete } {} 488 489do_test $tn.8.5 { 490 sqlite3session S db main 491 S attach t5 492 S attach t6 493 execsql { INSERT INTO t5 VALUES(1, 2) } 494 S isempty 495} {0} 496 497do_test $tn.8.6 { 498 S delete 499 sqlite3session S db main 500 S attach t5 501 S attach t6 502 execsql { INSERT INTO t6 VALUES(1, 2) } 503 S isempty 504} {0} 505do_test $tn.8.7 { S delete } {} 506 507#------------------------------------------------------------------------- 508# 509do_execsql_test $tn.9.1 { 510 CREATE TABLE t7(a, b, c, d, e PRIMARY KEY, f, g)%WR%; 511 INSERT INTO t7 VALUES(1, 1, 1, 1, 1, 1, 1); 512} 513do_test $tn.9.2 { 514 sqlite3session S db main 515 S attach * 516 execsql { UPDATE t7 SET b=2, d=2 } 517} {} 518do_changeset_test $tn.9.2 S {{UPDATE t7 0 ....X.. {{} {} i 1 {} {} i 1 i 1 {} {} {} {}} {{} {} i 2 {} {} i 2 {} {} {} {} {} {}}}} 519S delete 520catch { db2 close } 521 522#------------------------------------------------------------------------- 523# Test a really long table name. 524# 525reset_db 526set tblname [string repeat tblname123 100] 527do_test $tn.10.1.1 { 528 execsql " 529 CREATE TABLE $tblname (a PRIMARY KEY, b)%WR%; 530 INSERT INTO $tblname VALUES('xyz', 'def'); 531 " 532 sqlite3session S db main 533 S attach $tblname 534 execsql " 535 INSERT INTO $tblname VALUES('uvw', 'abc'); 536 DELETE FROM $tblname WHERE a = 'xyz'; 537 " 538} {} 539do_changeset_test $tn.10.1.2 S " 540 {INSERT $tblname 0 X. {} {t uvw t abc}} 541 {DELETE $tblname 0 X. {t xyz t def} {}} 542" 543do_test $tn.10.1.4 { S delete } {} 544 545#--------------------------------------------------------------- 546reset_db 547do_execsql_test $tn.11.1 { 548 CREATE TABLE t1(a, b); 549} 550do_test $tn.11.2 { 551 sqlite3session S db main 552 S attach t1 553 execsql { 554 INSERT INTO t1 VALUES(1, 2); 555 } 556 S changeset 557} {} 558 559S delete 560 561 562#------------------------------------------------------------------------- 563# Test a really long table name. 564# 565reset_db 566set tblname [string repeat tblname123 100] 567do_test $tn.10.1.1 { 568 execsql " 569 CREATE TABLE $tblname (a PRIMARY KEY, b)%WR%; 570 INSERT INTO $tblname VALUES('xyz', 'def'); 571 " 572 sqlite3session S db main 573 S attach $tblname 574 execsql " 575 INSERT INTO $tblname VALUES('uvw', 'abc'); 576 DELETE FROM $tblname WHERE a = 'xyz'; 577 " 578} {} 579do_changeset_test $tn.10.1.2 S " 580 {INSERT $tblname 0 X. {} {t uvw t abc}} 581 {DELETE $tblname 0 X. {t xyz t def} {}} 582" 583do_test $tn.10.1.4 { S delete } {} 584 585#------------------------------------------------------------------------- 586# Test the effect of updating a column from 0.0 to 0.0. 587# 588reset_db 589do_execsql_test $tn.11.1 { 590 CREATE TABLE t1(a INTEGER PRIMARY KEY, b REAL)%WR%; 591 INSERT INTO t1 VALUES(1, 0.0); 592} 593do_iterator_test $tn.11.2 * { 594 UPDATE t1 SET b = 0.0; 595} { 596} 597 598reset_db 599do_execsql_test $tn.12.1 { 600 CREATE TABLE t1(r INTEGER PRIMARY KEY, a, b)%WR%; 601 CREATE INDEX i1 ON t1(a); 602 INSERT INTO t1 VALUES(1, 1, 1); 603 INSERT INTO t1 VALUES(2, 1, 2); 604 INSERT INTO t1 VALUES(3, 1, 3); 605} 606 607do_iterator_test $tn.12.2 * { 608 UPDATE t1 SET b='one' WHERE a=1; 609} { 610 {UPDATE t1 0 X.. {i 1 {} {} i 1} {{} {} {} {} t one}} 611 {UPDATE t1 0 X.. {i 2 {} {} i 2} {{} {} {} {} t one}} 612 {UPDATE t1 0 X.. {i 3 {} {} i 3} {{} {} {} {} t one}} 613} 614 615#------------------------------------------------------------------------- 616# Test that no savepoint is used if -nosavepoint is specified. 617# 618do_execsql_test $tn.13.1 { 619 CREATE TABLE x1(a INTEGER PRIMARY KEY, b)%WR%; 620} 621do_test $tn.13.2 { 622 execsql BEGIN 623 set C [changeset_from_sql { 624 INSERT INTO x1 VALUES(1, 'one'); 625 INSERT INTO x1 VALUES(2, 'two'); 626 INSERT INTO x1 VALUES(3, 'three'); 627 }] 628 execsql ROLLBACK 629 execsql { 630 INSERT INTO x1 VALUES(1, 'i'); 631 INSERT INTO x1 VALUES(2, 'ii'); 632 INSERT INTO x1 VALUES(3, 'iii'); 633 } 634} {} 635 636proc xConflict {args} { 637 set ret [lindex $::CONFLICT_HANDLERS 0] 638 set ::CONFLICT_HANDLERS [lrange $::CONFLICT_HANDLERS 1 end] 639 set ret 640} 641do_test $tn.13.3 { 642 set CONFLICT_HANDLERS [list REPLACE REPLACE ABORT] 643 execsql BEGIN 644 catch { sqlite3changeset_apply_v2 db $C xConflict } msg 645 execsql { 646 SELECT * FROM x1 647 } 648} {1 i 2 ii 3 iii} 649do_test $tn.13.3 { 650 set CONFLICT_HANDLERS [list REPLACE REPLACE ABORT] 651 execsql ROLLBACK 652 execsql BEGIN 653 catch { sqlite3changeset_apply_v2 -nosavepoint db $C xConflict } msg 654 execsql { SELECT * FROM x1 } 655} {1 one 2 two 3 iii} 656execsql ROLLBACK 657 658do_test $tn.14.1 { sqlite3session_config strm_size -1 } 64 659do_test $tn.14.2 { sqlite3session_config strm_size 65536 } 65536 660do_test $tn.14.3 { sqlite3session_config strm_size 64 } 64 661do_test $tn.14.4 { 662 list [catch {sqlite3session_config invalid 123} msg] $msg 663} {1 SQLITE_MISUSE} 664 665}] 666} 667 668 669finish_test 670