1# 2014 August 30 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# This file contains tests for the RBU module. More specifically, it 13# contains tests to ensure that RBU works with FTS tables. 14# 15 16if {![info exists testdir]} { 17 set testdir [file join [file dirname [info script]] .. .. test] 18} 19source $testdir/tester.tcl 20set ::testprefix rbufts 21 22ifcapable !fts3 { 23 finish_test 24 return 25} 26 27proc step_rbu {target rbu} { 28 while 1 { 29 sqlite3rbu rbu $target $rbu 30 set rc [rbu step] 31 rbu close 32 if {$rc != "SQLITE_OK"} break 33 } 34 set rc 35} 36 37proc apply_rbu_update {target sql} { 38 forcedelete rbu.db 39 sqlite3 dbrbu rbu.db 40 execsql $sql dbrbu 41 dbrbu close 42 43 step_rbu $target rbu.db 44} 45 46do_execsql_test 1.1.0 { 47 CREATE TABLE t1(i INTEGER PRIMARY KEY, a, b); 48 CREATE VIRTUAL TABLE xx USING fts4(content=t1, a, b); 49 INSERT INTO t1(rowid, a, b) VALUES(10, 'a b c', 'c b a'); 50 INSERT INTO t1(rowid, a, b) VALUES(20, 'a b c', 'd e f'); 51 INSERT INTO t1(rowid, a, b) VALUES(30, 'd e f', 'a b c'); 52 INSERT INTO t1(rowid, a, b) VALUES(40, 'd e f', 'd e f'); 53} 54 55do_execsql_test 1.1.1 { 56 INSERT INTO xx(xx) VALUES('rebuild'); 57 INSERT INTO xx(xx) VALUES('integrity-check'); 58} 59 60do_test 1.1.2 { 61 apply_rbu_update test.db { 62 CREATE TABLE data_t1(i, a, b, rbu_control); 63 INSERT INTO data_t1 VALUES(20, NULL, NULL, 1); -- delete 64 INSERT INTO data_t1 VALUES(30, 'x y z', NULL, '.x.'); -- update 65 INSERT INTO data_t1 VALUES(50, '1 2 3', 'x y z', 0); -- insert 66 67 CREATE VIEW data0_xx AS 68 SELECT i AS rbu_rowid, a, b, 69 CASE WHEN rbu_control IN (0, 1) 70 THEN rbu_control ELSE substr(rbu_control, 2) END AS rbu_control 71 FROM data_t1; 72 } 73} {SQLITE_DONE} 74 75do_execsql_test 1.1.3 { 76 INSERT INTO xx(xx) VALUES('integrity-check'); 77} 78 79reset_db 80do_execsql_test 1.2.1 { 81 CREATE TABLE ccc(addr, text); 82 CREATE VIRTUAL TABLE ccc_fts USING fts4(addr, text, content=ccc); 83 INSERT INTO ccc VALUES('a b c', 'd e f'); 84 INSERT INTO ccc VALUES('a b c', 'd e f'); 85 INSERT INTO ccc_fts(ccc_fts) VALUES('rebuild'); 86 INSERT INTO ccc_fts(ccc_fts) VALUES('integrity-check'); 87} 88 89do_test 1.2.2 { 90 apply_rbu_update test.db { 91 CREATE TABLE data_ccc(addr, text, rbu_rowid, rbu_control); 92 CREATE VIEW data0_ccc_fts AS SELECT * FROM data_ccc; 93 INSERT INTO data_ccc VALUES(NULL, NULL, 1, 1); 94 INSERT INTO data_ccc VALUES('x y z', NULL, 2, 'x.'); 95 INSERT INTO data_ccc VALUES('y y y', '1 1 1', 3, 0); 96 } 97} {SQLITE_DONE} 98 99do_execsql_test 1.2.3 { 100 INSERT INTO ccc_fts(ccc_fts) VALUES('integrity-check'); 101} 102do_execsql_test 1.2.4 { 103 SELECT rowid, * FROM ccc_fts; 104} {2 {x y z} {d e f} 3 {y y y} {1 1 1}} 105 106#------------------------------------------------------------------------- 107# Test the outcome of attempting to delete or update a row within a 108# contentless FTS table using RBU. An error. 109# 110reset_db 111do_execsql_test 3.1 { 112 CREATE VIRTUAL TABLE ft USING fts4(x, content=); 113 INSERT INTO ft(rowid, x) VALUES(1, '1 2 3'); 114 INSERT INTO ft(rowid, x) VALUES(2, '4 5 6'); 115} 116 117do_test 3.2 { 118 list [catch { apply_rbu_update test.db { 119 CREATE TABLE data_ft(x, rbu_rowid, rbu_control); 120 INSERT INTO data_ft VALUES(NULL, 2, 1); 121 } } msg] $msg] 122} {1 {SQLITE_ERROR - SQL logic error]}} 123 124do_test 3.3 { 125 list [catch { apply_rbu_update test.db { 126 CREATE TABLE data_ft(x, rbu_rowid, rbu_control); 127 INSERT INTO data_ft VALUES('7 8 9', 1, 'x'); 128 } } msg] $msg] 129} {1 {SQLITE_ERROR - SQL logic error]}} 130 131 132 133finish_test 134