From: dan Date: Thu, 13 Aug 2015 18:26:09 +0000 (+0000) Subject: Add the sqlite3rbu_savestate() function to the rbu extension. To force rbu to save... X-Git-Tag: version-3.9.0~223 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=82d7aea6d48582e8ffaed70ea37bee807028da1a;p=thirdparty%2Fsqlite.git Add the sqlite3rbu_savestate() function to the rbu extension. To force rbu to save its state to disk without closing the sqlite3rbu* handle. FossilOrigin-Name: 851a875ad6b81f90960caf4d03b116afc911858d --- diff --git a/ext/rbu/rbusave.test b/ext/rbu/rbusave.test new file mode 100644 index 0000000000..1bb71a8e05 --- /dev/null +++ b/ext/rbu/rbusave.test @@ -0,0 +1,105 @@ +# 2015 August 14 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source $testdir/tester.tcl +set ::testprefix rbusave + +do_execsql_test 1.0 { + CREATE TABLE t1(a PRIMARY KEY, b, c) WITHOUT ROWID; + CREATE TABLE t2(a INTEGER PRIMARY KEY, b, c); + CREATE INDEX i1 ON t1(b); + CREATE INDEX i2 ON t2(c, b); + + INSERT INTO t1 VALUES(1, 1, 1); + INSERT INTO t1 VALUES(2, 2, 2); + INSERT INTO t1 VALUES(3, 3, 3); + + INSERT INTO t2 VALUES(1, 1, 1); + INSERT INTO t2 VALUES(2, 2, 2); + INSERT INTO t2 VALUES(3, 3, 3); +} + +do_test 1.1 { + forcedelete test.db2 + sqlite3 db2 test.db2 + db2 eval { + CREATE TABLE data_t1(a, b, c, rbu_control); + INSERT INTO data_t1 VALUES(4, 4, 4, 0); + INSERT INTO data_t1 VALUES(2, NULL, NULL, 1); + INSERT INTO data_t1 VALUES(1, 'one', NULL, '.x.'); + + CREATE TABLE data_t2(a, b, c, rbu_control); + INSERT INTO data_t2 VALUES(4, 4, 4, 0); + INSERT INTO data_t2 VALUES(2, NULL, NULL, 1); + INSERT INTO data_t2 VALUES(1, 'one', NULL, '.x.'); + } +} {} + +proc test_to_bak {} { + foreach f { + test.db test.db-wal test.db-oal test.db-journal + test.db2 test.db2-wal test.db2-oal test.db2-journal + } { + set t [string map {test bak} $f] + forcedelete $t + if {[file exists $f]} { forcecopy $f $t } + } +} + +do_test 1.2 { + test_to_bak + sqlite3rbu rrr bak.db bak.db2 + set nStep 0 + while {[rrr step]=="SQLITE_OK"} {incr nStep} + set res2 [rrr close] +} {SQLITE_DONE} + + +sqlite3rbu rbu test.db test.db2 +set res "SQLITE_OK" +for {set i 1} {$res=="SQLITE_OK"} {incr i} { + set res [rbu step] + + do_test 1.3.$i.1 { + rbu savestate + test_to_bak + sqlite3rbu rrr bak.db bak.db2 + set nRem 0 + while {[rrr step]=="SQLITE_OK"} {incr nRem} + set res2 [rrr close] + } {SQLITE_DONE} + + do_test 1.3.$i.3 { expr $nRem+$i } [expr {$nStep + ($res=="SQLITE_DONE")}] + + do_test 1.3.$i.3 { + sqlite3 bak bak.db + bak eval { + SELECT * FROM t1; + SELECT * FROM t2; + } + } {1 one 1 3 3 3 4 4 4 1 one 1 3 3 3 4 4 4} + + bak close +} + +do_test 1.4 { rbu close } {SQLITE_DONE} + +do_execsql_test 1.5 { + SELECT * FROM t1; + SELECT * FROM t2; +} {1 one 1 3 3 3 4 4 4 1 one 1 3 3 3 4 4 4} + +finish_test + diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index ad831f4533..403d4ebdcb 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -3164,6 +3164,32 @@ sqlite3_int64 sqlite3rbu_progress(sqlite3rbu *pRbu){ return pRbu->nProgress; } +int sqlite3rbu_savestate(sqlite3rbu *p){ + int rc = p->rc; + + if( rc==SQLITE_DONE ) return SQLITE_OK; + + assert( p->eStage>=RBU_STAGE_OAL && p->eStage<=RBU_STAGE_DONE ); + if( p->eStage==RBU_STAGE_OAL ){ + assert( rc!=SQLITE_DONE ); + if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, 0); + } + + p->rc = rc; + rbuSaveState(p, p->eStage); + rc = p->rc; + + if( p->eStage==RBU_STAGE_OAL ){ + assert( rc!=SQLITE_DONE ); + if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbRbu, "COMMIT", 0, 0, 0); + if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbRbu, "BEGIN IMMEDIATE", 0, 0, 0); + if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbMain, "BEGIN IMMEDIATE", 0, 0,0); + } + + p->rc = rc; + return rc; +} + /************************************************************************** ** Beginning of RBU VFS shim methods. The VFS shim modifies the behaviour ** of a standard VFS in the following ways: diff --git a/ext/rbu/sqlite3rbu.h b/ext/rbu/sqlite3rbu.h index ca4b03dd4c..b6cbf4d8b9 100644 --- a/ext/rbu/sqlite3rbu.h +++ b/ext/rbu/sqlite3rbu.h @@ -354,6 +354,18 @@ sqlite3 *sqlite3rbu_db(sqlite3rbu*, int bRbu); */ int sqlite3rbu_step(sqlite3rbu *pRbu); +/* +** Force RBU to save its state to disk. +** +** If a power failure or application crash occurs during an update, following +** system recovery RBU may resume the update from the point at which the state +** was last saved. In other words, from the most recent successful call to +** sqlite3rbu_close() or this function. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +*/ +int sqlite3rbu_savestate(sqlite3rbu *pRbu); + /* ** Close an RBU handle. ** diff --git a/ext/rbu/test_rbu.c b/ext/rbu/test_rbu.c index fbaea16268..6648f28e8b 100644 --- a/ext/rbu/test_rbu.c +++ b/ext/rbu/test_rbu.c @@ -56,7 +56,9 @@ static int test_sqlite3rbu_cmd( ){ int ret = TCL_OK; sqlite3rbu *pRbu = (sqlite3rbu*)clientData; - const char *azMethod[] = { "step", "close", "create_rbu_delta", 0 }; + const char *azMethod[] = { + "step", "close", "create_rbu_delta", "savestate", 0 + }; int iMethod; if( objc!=2 ){ @@ -103,6 +105,13 @@ static int test_sqlite3rbu_cmd( break; } + case 3: /* savestate */ { + int rc = sqlite3rbu_savestate(pRbu); + Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); + ret = (rc==SQLITE_OK ? TCL_OK : TCL_ERROR); + break; + } + default: /* seems unlikely */ assert( !"cannot happen" ); break; diff --git a/manifest b/manifest index 5779cad992..3ec7d5e743 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sinvoking\ssystem\scall\sunlink()\sdirectly\sfrom\sRBU\scode.\sUse\sthe\sxDelete\smethod\sof\sthe\sdefault\sVFS\sinstead. -D 2015-08-13T11:46:21.944 +C Add\sthe\ssqlite3rbu_savestate()\sfunction\sto\sthe\srbu\sextension.\sTo\sforce\srbu\sto\ssave\sits\sstate\sto\sdisk\swithout\sclosing\sthe\ssqlite3rbu*\shandle. +D 2015-08-13T18:26:09.242 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2fc9ca6bf5949d415801c007ed3004a4bdb7c380 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -223,9 +223,10 @@ F ext/rbu/rbudiff.test 6cc806dc36389292f2a8f5842d0103721df4a07d F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89 F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06 F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda -F ext/rbu/sqlite3rbu.c e2ebcebfd0c363b8f90aba5a91cba0b3e93044ea -F ext/rbu/sqlite3rbu.h f0754a19fcc155f6d39d72b38bdbeb1d7623f02e -F ext/rbu/test_rbu.c f99698956cc9158d6bf865e461e2d15876538ac1 +F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 +F ext/rbu/sqlite3rbu.c 08fddeae6b89aeb1e960f9330a2228968210170a +F ext/rbu/sqlite3rbu.h 5357f070cd8c0bcad459b620651ec1656859e4d0 +F ext/rbu/test_rbu.c 2a3652241fa45d5eaa141775e4ae68c1d3582c03 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 F ext/rtree/rtree.c 0f9b595bd0debcbedf1d7a63d0e0678d619e6c9c F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e @@ -1372,7 +1373,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P efb7c9c5d0015c8c966f8d6742c05cda82fc146a -R 574927013afdd5b82f7f2aa79787da64 +P ee966af8ff79189f8b90f3557dea21059517dfe2 +R 5dcd61cef4d3f59a3e6f61e4cf60159a U dan -Z c9a8f55e34994965e95a262cdf26fc13 +Z bdea05956aba407287af182409a84a65 diff --git a/manifest.uuid b/manifest.uuid index 79399d2960..f6ed1de738 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ee966af8ff79189f8b90f3557dea21059517dfe2 \ No newline at end of file +851a875ad6b81f90960caf4d03b116afc911858d \ No newline at end of file