]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add the sqlite3rbu_savestate() function to the rbu extension. To force rbu to save...
authordan <dan@noemail.net>
Thu, 13 Aug 2015 18:26:09 +0000 (18:26 +0000)
committerdan <dan@noemail.net>
Thu, 13 Aug 2015 18:26:09 +0000 (18:26 +0000)
FossilOrigin-Name: 851a875ad6b81f90960caf4d03b116afc911858d

ext/rbu/rbusave.test [new file with mode: 0644]
ext/rbu/sqlite3rbu.c
ext/rbu/sqlite3rbu.h
ext/rbu/test_rbu.c
manifest
manifest.uuid

diff --git a/ext/rbu/rbusave.test b/ext/rbu/rbusave.test
new file mode 100644 (file)
index 0000000..1bb71a8
--- /dev/null
@@ -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
+
index ad831f453362c28bd5c20b55797a2bcd4572fb03..403d4ebdcb2376569962254db1a3c45f84c02d0f 100644 (file)
@@ -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:
index ca4b03dd4ceb4528a0006888232770371a93b186..b6cbf4d8b9012e1b9c2b7a738cd9b393bc7006ef 100644 (file)
@@ -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. 
 **
index fbaea1626875b3b3fdc758189b2d8e52d819dd62..6648f28e8b753b7073f77cd381e79d516c49988c 100644 (file)
@@ -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;
index 5779cad99263251401bf67f1bc1721efb9ccf5a8..3ec7d5e7436aa1ff637cef01320a8bca4f7bd2c5 100644 (file)
--- 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
index 79399d296049e90d3cbfa9fe52cd785cabe0d85d..f6ed1de73823d4b34a337a7311503dba1f21a7e3 100644 (file)
@@ -1 +1 @@
-ee966af8ff79189f8b90f3557dea21059517dfe2
\ No newline at end of file
+851a875ad6b81f90960caf4d03b116afc911858d
\ No newline at end of file