]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Remove "PRAGMA pager_ota_mode".
authordan <dan@noemail.net>
Sat, 7 Feb 2015 19:17:36 +0000 (19:17 +0000)
committerdan <dan@noemail.net>
Sat, 7 Feb 2015 19:17:36 +0000 (19:17 +0000)
FossilOrigin-Name: 8ac58e46782bd6b81c06fdf1cb5b316b8a4e1ddf

14 files changed:
ext/ota/README.txt
ext/ota/ota1.test
ext/ota/ota2.test [deleted file]
ext/ota/ota4.test [deleted file]
ext/ota/ota6.test
ext/ota/sqlite3ota.c
manifest
manifest.uuid
src/pager.c
src/pager.h
src/pragma.c
src/pragma.h
src/wal.c
tool/mkpragmatab.tcl

index 943d1822afa376033e7c9300b0fa459119c0a4bc..42ac29064c7a0ec154b02ab8352acb7319ba8474 100644 (file)
@@ -5,21 +5,8 @@ User documentation is in sqlite3ota.h.
 SQLite Hacks
 ------------
 
-1) PRAGMA ota_mode:
 
-  This is a new flag pragma. If the flag is set:
-
-  * INSERT/DELETE/UPDATE commands are prevented from updating any but the main
-    b-tree for each table (the PK index for WITHOUT ROWID tables or the 
-    rowid b-tree for others).
-
-  * The above statements do not check UNIQUE constraints - except those enforced
-    by the main b-tree.
-
-  * All non-temporary triggers are disabled.
-
-
-2) PRAGMA pager_ota_mode=1:
+1) PRAGMA pager_ota_mode=1:
 
   This pragma sets a flag on the pager associated with the main database only.
   In a zipvfs system, this pragma is intercepted by zipvfs and the flag is set
@@ -51,7 +38,7 @@ SQLite Hacks
   pager_ota_mode connections. If two or more such connections attempt to write
   simultaneously, the results are undefined.
 
-3) PRAGMA pager_ota_mode=2:
+2) PRAGMA pager_ota_mode=2:
 
   The pager_ota_mode pragma may also be set to 2 if the main database is open 
   in WAL mode. This prevents SQLite from checkpointing the wal file as part
@@ -60,14 +47,7 @@ SQLite Hacks
   The effects of setting pager_ota_mode=2 if the db is not in WAL mode are
   undefined.
 
-4) sqlite3_index_writer()
-
-  This new API function is used to create VMs that can insert or delete entries
-  from individual index b-trees within the database. The VMs apply affinities
-  and check that UNIQUE constraints are not violated before updating index
-  b-trees.
-
-5) sqlite3_ckpt_open/step/close()
+3) sqlite3_ckpt_open/step/close()
 
   API for performing (and resuming) incremental checkpoints.
 
index afb5fd5865a36d93eb6dcd33aabdf56b78eb9241..265a3d2a2ff9693b943c01637fbec6b7fd902fec 100644 (file)
@@ -187,6 +187,7 @@ foreach {tn2 cmd} {1 run_ota 2 step_ota 3 step_ota_uri} {
 
     do_test 1.$tn2.$tn.1 {
       create_ota1 ota.db
+      breakpoint
       $cmd test.db ota.db
     } {SQLITE_DONE}
 
diff --git a/ext/ota/ota2.test b/ext/ota/ota2.test
deleted file mode 100644 (file)
index 3c273e3..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-# 2014 August 30
-#
-# 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 ota2
-
-forcedelete {*}[glob -nocomplain test.db?*]
-
-do_execsql_test 1.0 {
-  CREATE TABLE t1(a, b);
-  INSERT INTO t1 VALUES(1, 2);
-} {}
-do_test 1.1 { glob test.db* } {test.db}
-
-do_execsql_test 1.2 {
-  PRAGMA pager_ota_mode = 1;
-  INSERT INTO t1 VALUES(3, 4);
-  INSERT INTO t1 VALUES(5, 6);
-  SELECT * FROM t1;
-} {1 2 3 4 5 6}
-
-do_test 1.3 { lsort [glob test.db*] } {test.db test.db-oal}
-
-do_test 1.4 {
-  sqlite3 db2 test.db
-  db2 eval { SELECT * FROM t1 }
-} {1 2}
-
-do_test 1.5 {
-  catchsql { INSERT INTO t1 VALUES(7, 8) } db2
-} {1 {database is locked}}
-
-db2 close
-db close
-
-sqlite3 db test.db
-do_execsql_test 1.6 {
-  PRAGMA pager_ota_mode = 1;
-  SELECT * FROM t1;
-} {1 2 3 4 5 6}
-
-do_execsql_test 1.7 {
-  INSERT INTO t1 VALUES(7,8);
-  SELECT * FROM t1;
-} {1 2 3 4 5 6 7 8}
-
-db close
-sqlite3 db2 test.db
-
-do_test 1.8 {
-  execsql { BEGIN; SELECT * FROM t1 } db2
-} {1 2}
-do_test 1.9 {
-  file rename test.db-oal test.db-wal
-  execsql { SELECT * FROM t1 } db2
-} {1 2}
-do_test 1.10 {
-  execsql { COMMIT; SELECT * FROM t1 } db2
-} {1 2 3 4 5 6 7 8}
-
-
-finish_test
diff --git a/ext/ota/ota4.test b/ext/ota/ota4.test
deleted file mode 100644 (file)
index a12cbd8..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-# 2014 August 30
-#
-# 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.
-#
-#***********************************************************************
-#
-# Test some properties of the pager_ota_mode and ota_mode pragmas.
-#
-
-if {![info exists testdir]} {
-  set testdir [file join [file dirname [info script]] .. .. test]
-}
-source $testdir/tester.tcl
-set ::testprefix ota4
-
-#-------------------------------------------------------------------------
-# The following tests aim to verify some properties of the pager_ota_mode
-# pragma:
-#
-# 1. Cannot set the pager_ota_mode flag on a WAL mode database.
-#
-# 2. Or if there is an open read transaction.
-#
-# 3. Cannot start a transaction with pager_ota_mode set if there
-#    is a WAL file in the file-system.
-# 
-# 4. Or if the wal-mode flag is set in the database file header.
-# 
-# 5. Cannot open a transaction with pager_ota_mode set if the database
-#    file has been modified by a rollback mode client since the *-oal
-#    file was started.
-#
-
-do_execsql_test 1.1.1 { 
-  PRAGMA journal_mode = wal;
-  SELECT * FROM sqlite_master;
-} {wal}
-do_catchsql_test 1.1.2 { 
-  PRAGMA pager_ota_mode = 1 
-} {1 {cannot set pager_ota_mode in wal mode}}
-
-
-do_execsql_test 1.2.1 { 
-  PRAGMA journal_mode = delete;
-  BEGIN;
-    SELECT * FROM sqlite_master;
-} {delete}
-do_catchsql_test 1.2.2 { 
-  PRAGMA pager_ota_mode = 1 
-} {1 {cannot set pager_ota_mode with open transaction}}
-do_execsql_test 1.2.3 { 
-  COMMIT;
-} {}
-
-
-do_execsql_test 1.3.1 {
-  PRAGMA journal_mode = wal;
-  CREATE TABLE t1(a, b);
-  INSERT INTO t1 VALUES(1, 2);
-} {wal}
-do_test 1.3.2 {
-  forcecopy test.db-wal test.db-bak
-  execsql { 
-    PRAGMA journal_mode = delete;
-    PRAGMA pager_ota_mode = 1;
-  }
-  forcecopy test.db-bak test.db-wal
-  catchsql {
-    SELECT * FROM sqlite_master
-  }
-} {1 {unable to open database file}}
-
-do_test 1.4.1 {
-  db close
-  forcedelete test.db-wal test.db-oal
-  sqlite3 db test.db
-  execsql { 
-    PRAGMA journal_mode = wal;
-    PRAGMA pager_ota_mode = 1;
-  }
-  catchsql {
-    SELECT * FROM sqlite_master;
-  }
-} {1 {unable to open database file}}
-
-do_test 1.5.1 {
-  forcedelete test.db-oal
-  reset_db
-  execsql {
-    PRAGMA journal_mode = delete;
-    CREATE TABLE t1(a, b);
-    INSERT INTO t1 VALUES(1, 2);
-  }
-  execsql {
-    PRAGMA pager_ota_mode = 1;
-    INSERT INTO t1 VALUES(3, 4);
-  }
-  db close
-  sqlite3 db test.db
-  execsql {
-    SELECT * FROM t1;
-  }
-} {1 2}
-do_execsql_test 1.5.2 {
-  PRAGMA pager_ota_mode = 1;
-  SELECT * FROM t1;
-  INSERT INTO t1 VALUES(5, 6);
-} {1 2 3 4}
-do_test 5.3 {
-  db close
-  sqlite3 db test.db
-  execsql {
-    INSERT INTO t1 VALUES(7, 8);
-    SELECT * FROM t1;
-  }
-} {1 2 7 8}
-do_catchsql_test 1.5.4 {
-  PRAGMA pager_ota_mode = 1;
-  SELECT * FROM t1;
-} {1 {database is locked}}
-
-finish_test
-
index f15873629c09c6789e06178a4501ccaeb8fc0cd9..8027f36c5f19fb17de8deec56e8ffd33610d1841 100644 (file)
@@ -50,7 +50,7 @@ for {set nStep 1} {$nStep < 7} {incr nStep} {
     setup_test
     sqlite3ota ota test.db ota.db
     for {set i 0} {$i<$nStep} {incr i} {ota step}
-  
+
     ota close
     sqlite3 db test.db
     execsql { INSERT INTO t1 VALUES(5, 'hello') }
@@ -65,7 +65,7 @@ for {set nStep 1} {$nStep < 7} {incr nStep} {
   } {1 0}
   do_test 1.$nStep.4 {
     list [catch { ota close } msg] $msg
-  } {1 {SQLITE_BUSY - database is locked}}
+  } {1 {SQLITE_BUSY - database modified during ota update}}
 }
 
 for {set nStep 7} {$nStep < 8} {incr nStep} {
@@ -122,7 +122,5 @@ for {set nStep 8} {$nStep < 20} {incr nStep} {
 }
 
 
-
 finish_test
 
-
index 20b9ede75bff2b9d95148debe79bf9606a0c6b13..2e23d5658cfa4f81becefe897d32cc5dfe8ba0cd 100644 (file)
@@ -62,6 +62,9 @@
 **   Valid if STAGE==3. The blob to pass to sqlite3ckpt_start() to resume
 **   the incremental checkpoint.
 **
+** OTA_STATE_COOKIE:
+**   Valid if STAGE==1. The current change-counter cookie value in the 
+**   target db file.
 */
 #define OTA_STATE_STAGE       1
 #define OTA_STATE_TBL         2
@@ -69,6 +72,7 @@
 #define OTA_STATE_ROW         4
 #define OTA_STATE_PROGRESS    5
 #define OTA_STATE_CKPT        6
+#define OTA_STATE_COOKIE      7
 
 #define OTA_STAGE_OAL         1
 #define OTA_STAGE_COPY        2
@@ -166,8 +170,13 @@ struct sqlite3ota {
   int nProgress;                  /* Rows processed for all objects */
   OtaObjIter objiter;             /* Iterator for skipping through tbl/idx */
   sqlite3_ckpt *pCkpt;            /* Incr-checkpoint handle */
+  sqlite3_vfs *pVfs;              /* Special ota VFS object */
+  unsigned int iCookie;
 };
 
+static void otaCreateVfs(sqlite3ota*, const char*);
+static void otaDeleteVfs(sqlite3ota*);
+
 /*
 ** Prepare the SQL statement in buffer zSql against database handle db.
 ** If successful, set *ppStmt to point to the new statement and return
@@ -704,6 +713,19 @@ static char *otaMPrintf(sqlite3ota *p, const char *zFmt, ...){
   return zSql;
 }
 
+static void *otaMalloc(sqlite3ota *p, int nByte){
+  void *pRet = 0;
+  if( p->rc==SQLITE_OK ){
+    pRet = sqlite3_malloc(nByte);
+    if( pRet==0 ){
+      p->rc = SQLITE_NOMEM;
+    }else{
+      memset(pRet, 0, nByte);
+    }
+  }
+  return pRet;
+}
+
 /*
 ** This function constructs and returns a pointer to a nul-terminated 
 ** string containing some SQL clause or list based on one or more of the 
@@ -1434,11 +1456,11 @@ static int otaGetUpdateStmt(
 ** error occurs, leave an error code and message in the OTA handle.
 */
 static void otaOpenDatabase(sqlite3ota *p){
+  int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
   assert( p->rc==SQLITE_OK );
-  sqlite3_close(p->db);
-  p->db = 0;
+  assert( p->db==0 );
 
-  p->rc = sqlite3_open(p->zTarget, &p->db);
+  p->rc = sqlite3_open_v2(p->zTarget, &p->db, flags, p->pVfs->zName);
   if( p->rc ){
     p->zErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db));
   }
@@ -1506,8 +1528,10 @@ static void otaMoveOalFile(sqlite3ota *p){
 
     /* Re-open the databases. */
     otaObjIterFinalize(&p->objiter);
-    otaOpenDatabase(p);
+    sqlite3_close(p->db);
+    p->db = 0;
     p->eStage = OTA_STAGE_CKPT;
+    otaOpenDatabase(p);
   }
 
   sqlite3_free(zWal);
@@ -1795,13 +1819,15 @@ static void otaSaveTransactionState(sqlite3ota *p){
         "(%d, %Q), "
         "(%d, %d), "
         "(%d, %lld), "
-        "(%d, ?) ",
+        "(%d, ?), "
+        "(%d, %lld) ",
         OTA_STATE_STAGE, p->eStage,
         OTA_STATE_TBL, p->objiter.zTbl, 
         OTA_STATE_IDX, p->objiter.zIdx, 
         OTA_STATE_ROW, p->nStep, 
         OTA_STATE_PROGRESS, p->nProgress,
-        OTA_STATE_CKPT
+        OTA_STATE_CKPT,
+        OTA_STATE_COOKIE, (sqlite3_int64)p->iCookie
       )
   );
   assert( pInsert==0 || rc==SQLITE_OK );
@@ -1896,6 +1922,19 @@ static OtaState *otaLoadState(sqlite3ota *p){
         );
         break;
 
+      case OTA_STATE_COOKIE:
+        /* At this point (p->iCookie) contains the value of the change-counter
+        ** cookie (the thing that gets incremented when a transaction is 
+        ** committed in rollback mode) currently stored on page 1 of the 
+        ** database file. */
+        if( pRet->eStage==OTA_STAGE_OAL 
+         && p->iCookie!=(unsigned int)sqlite3_column_int64(pStmt, 1) 
+        ){
+          rc = SQLITE_BUSY;
+          p->zErrmsg = sqlite3_mprintf("database modified during ota update");
+        }
+        break;
+
       default:
         rc = SQLITE_CORRUPT;
         break;
@@ -1965,13 +2004,18 @@ sqlite3ota *sqlite3ota_open(const char *zTarget, const char *zOta){
   if( p ){
     OtaState *pState = 0;
 
-    /* Open the target database */
+    /* Create the custom VFS */
     memset(p, 0, sizeof(sqlite3ota));
-    p->zTarget = (char*)&p[1];
-    memcpy(p->zTarget, zTarget, nTarget+1);
-    p->zOta = &p->zTarget[nTarget+1];
-    memcpy(p->zOta, zOta, nOta+1);
-    otaOpenDatabase(p);
+    otaCreateVfs(p, 0);
+
+    /* Open the target database */
+    if( p->rc==SQLITE_OK ){
+      p->zTarget = (char*)&p[1];
+      memcpy(p->zTarget, zTarget, nTarget+1);
+      p->zOta = &p->zTarget[nTarget+1];
+      memcpy(p->zOta, zOta, nOta+1);
+      otaOpenDatabase(p);
+    }
 
     /* If it has not already been created, create the ota_state table */
     if( p->rc==SQLITE_OK ){
@@ -1997,7 +2041,6 @@ sqlite3ota *sqlite3ota_open(const char *zTarget, const char *zOta){
       if( p->eStage==OTA_STAGE_OAL ){
         const char *zScript =
           "PRAGMA journal_mode=off;"
-          "PRAGMA pager_ota_mode=1;"
           "BEGIN IMMEDIATE;"
         ;
         p->rc = sqlite3_exec(p->db, zScript, 0, 0, &p->zErrmsg);
@@ -2081,13 +2124,10 @@ int sqlite3ota_close(sqlite3ota *p, char **pzErrmsg){
       p->rc = sqlite3_exec(p->db, "COMMIT", 0, 0, &p->zErrmsg);
     }
 
-    if( p->rc==SQLITE_OK && p->eStage==OTA_STAGE_CKPT ){
-      p->rc = sqlite3_exec(p->db, "PRAGMA pager_ota_mode=2", 0, 0, &p->zErrmsg);
-    }
-
-    /* Close the open database handle */
+    /* Close the open database handle and VFS object. */
     if( p->pCkpt ) sqlite3_ckpt_close(p->pCkpt, 0, 0);
     sqlite3_close(p->db);
+    otaDeleteVfs(p);
 
     otaEditErrmsg(p);
     rc = p->rc;
@@ -2109,6 +2149,577 @@ sqlite3_int64 sqlite3ota_progress(sqlite3ota *pOta){
   return pOta->nProgress;
 }
 
+/**************************************************************************
+** Beginning of OTA VFS shim methods. The VFS shim modifies the behaviour
+** of a standard VFS in the following ways:
+**
+**   TODO
+*/
+
+#if 0
+#define OTA_FILE_VANILLA    0
+#define OTA_FILE_TARGET_DB  1
+#define OTA_FILE_TARGET_WAL 2
+#endif
+
+typedef struct ota_file ota_file;
+typedef struct ota_vfs ota_vfs;
+
+struct ota_file {
+  sqlite3_file base;              /* sqlite3_file methods */
+  sqlite3_file *pReal;            /* Underlying file handle */
+  ota_vfs *pOtaVfs;               /* Pointer to the ota_vfs object */
+
+  int nShm;                       /* Number of entries in apShm[] array */
+  char **apShm;                   /* Array of mmap'd *-shm regions */
+  char *zFilename;                /* Filename for *-oal file only */
+};
+
+struct ota_vfs {
+  sqlite3_vfs base;             /* ota VFS shim methods */
+  sqlite3_vfs *pRealVfs;        /* Underlying VFS */
+  sqlite3ota *pOta;
+  ota_file *pTargetDb;          /* Target database file descriptor */
+  const char *zTargetDb;        /* Path that pTargetDb was opened with */
+};
+
+/*
+** Close an ota file.
+*/
+static int otaVfsClose(sqlite3_file *pFile){
+  ota_file *p = (ota_file*)pFile;
+  ota_vfs *pOtaVfs = p->pOtaVfs;
+  int rc;
+  int i;
+
+  /* Free the contents of the apShm[] array. And the array itself. */
+  for(i=0; i<p->nShm; i++){
+    sqlite3_free(p->apShm[i]);
+  }
+  sqlite3_free(p->apShm);
+  p->apShm = 0;
+  sqlite3_free(p->zFilename);
+
+  if( p==pOtaVfs->pTargetDb ){
+    pOtaVfs->pTargetDb = 0;
+    pOtaVfs->zTargetDb = 0;
+  }
+
+  rc = p->pReal->pMethods->xClose(p->pReal);
+  return rc;
+}
+
+
+/*
+** Read and return an unsigned 32-bit big-endian integer from the buffer 
+** passed as the only argument.
+*/
+static unsigned int otaGetU32(unsigned char *aBuf){
+  return ((unsigned int)aBuf[0] << 24)
+       + ((unsigned int)aBuf[1] << 16)
+       + ((unsigned int)aBuf[2] <<  8)
+       + ((unsigned int)aBuf[3]);
+}
+
+/*
+** Read data from an otaVfs-file.
+*/
+static int otaVfsRead(
+  sqlite3_file *pFile, 
+  void *zBuf, 
+  int iAmt, 
+  sqlite_int64 iOfst
+){
+  ota_file *p = (ota_file*)pFile;
+  ota_vfs *pOtaVfs = p->pOtaVfs;
+  int rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst);
+  if( rc==SQLITE_OK && p==pOtaVfs->pTargetDb && iOfst==0 ){
+    unsigned char *pBuf = (unsigned char*)zBuf;
+    assert( iAmt>=100 );
+    pOtaVfs->pOta->iCookie = otaGetU32(&pBuf[24]);
+  }
+  return rc;
+}
+
+/*
+** Write data to an otaVfs-file.
+*/
+static int otaVfsWrite(
+  sqlite3_file *pFile, 
+  const void *zBuf, 
+  int iAmt, 
+  sqlite_int64 iOfst
+){
+  ota_file *p = (ota_file*)pFile;
+  ota_vfs *pOtaVfs = p->pOtaVfs;
+  int rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst);
+  if( rc==SQLITE_OK && p==pOtaVfs->pTargetDb && iOfst==0 ){
+    unsigned char *pBuf = (unsigned char*)zBuf;
+    assert( iAmt>=100 );
+    pOtaVfs->pOta->iCookie = otaGetU32(&pBuf[24]);
+  }
+  return rc;
+}
+
+/*
+** Truncate an otaVfs-file.
+*/
+static int otaVfsTruncate(sqlite3_file *pFile, sqlite_int64 size){
+  ota_file *p = (ota_file*)pFile;
+  return p->pReal->pMethods->xTruncate(p->pReal, size);
+}
+
+/*
+** Sync an otaVfs-file.
+*/
+static int otaVfsSync(sqlite3_file *pFile, int flags){
+  ota_file *p = (ota_file *)pFile;
+  return p->pReal->pMethods->xSync(p->pReal, flags);
+}
+
+/*
+** Return the current file-size of an otaVfs-file.
+*/
+static int otaVfsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
+  ota_file *p = (ota_file *)pFile;
+  return p->pReal->pMethods->xFileSize(p->pReal, pSize);
+}
+
+/*
+** Lock an otaVfs-file.
+*/
+static int otaVfsLock(sqlite3_file *pFile, int eLock){
+  ota_file *p = (ota_file*)pFile;
+  ota_vfs *pOtaVfs = p->pOtaVfs;
+  int rc = SQLITE_OK;
+  int eStage = pOtaVfs->pOta->eStage;
+
+  if( pOtaVfs->pTargetDb==p 
+   && (eStage==OTA_STAGE_OAL || eStage==OTA_STAGE_CKPT) 
+   && eLock==SQLITE_LOCK_EXCLUSIVE
+  ){
+    /* Do not allow EXCLUSIVE locks. Preventing SQLite from taking this 
+    ** prevents it from checkpointing the database from sqlite3_close(). */
+    rc = SQLITE_BUSY;
+  }else{
+    rc = p->pReal->pMethods->xLock(p->pReal, eLock);
+  }
+
+  return rc;
+}
+
+/*
+** Unlock an otaVfs-file.
+*/
+static int otaVfsUnlock(sqlite3_file *pFile, int eLock){
+  ota_file *p = (ota_file *)pFile;
+  return p->pReal->pMethods->xUnlock(p->pReal, eLock);
+}
+
+/*
+** Check if another file-handle holds a RESERVED lock on an otaVfs-file.
+*/
+static int otaVfsCheckReservedLock(sqlite3_file *pFile, int *pResOut){
+  ota_file *p = (ota_file *)pFile;
+  return p->pReal->pMethods->xCheckReservedLock(p->pReal, pResOut);
+}
+
+/*
+** File control method. For custom operations on an otaVfs-file.
+*/
+static int otaVfsFileControl(sqlite3_file *pFile, int op, void *pArg){
+  ota_file *p = (ota_file *)pFile;
+  return p->pReal->pMethods->xFileControl(p->pReal, op, pArg);
+}
+
+/*
+** Return the sector-size in bytes for an otaVfs-file.
+*/
+static int otaVfsSectorSize(sqlite3_file *pFile){
+  ota_file *p = (ota_file *)pFile;
+  return p->pReal->pMethods->xSectorSize(p->pReal);
+}
+
+/*
+** Return the device characteristic flags supported by an otaVfs-file.
+*/
+static int otaVfsDeviceCharacteristics(sqlite3_file *pFile){
+  ota_file *p = (ota_file *)pFile;
+  return p->pReal->pMethods->xDeviceCharacteristics(p->pReal);
+}
+
+/*
+** Shared-memory methods are all pass-thrus.
+*/
+static int otaVfsShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
+  ota_file *p = (ota_file*)pFile;
+  ota_vfs *pOtaVfs = p->pOtaVfs;
+  int rc = SQLITE_OK;
+
+#ifdef SQLITE_AMALGAMATION
+    assert( WAL_WRITE_CKPT==1 );
+#endif
+
+  if( pOtaVfs->pTargetDb==p && pOtaVfs->pOta->eStage==OTA_STAGE_OAL ){
+    /* Magic number 1 is the WAL_WRITE_CKPT lock. Preventing SQLite from
+    ** taking this lock also prevents any checkpoints from occurring. 
+    ** todo: really, it's not clear why this might occur, as 
+    ** wal_autocheckpoint ought to be turned off.  */
+    if( ofst==1 && n==1 ) rc = SQLITE_BUSY;
+  }else{
+    assert( p->nShm==0 );
+    return p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags);
+  }
+
+  return rc;
+}
+
+static int otaVfsShmMap(
+  sqlite3_file *pFile, 
+  int iRegion, 
+  int szRegion, 
+  int isWrite, 
+  void volatile **pp
+){
+  ota_file *p = (ota_file*)pFile;
+  ota_vfs *pOtaVfs = p->pOtaVfs;
+  int rc = SQLITE_OK;
+
+  /* If not in OTA_STAGE_OAL, allow this call to pass through. Or, if this
+  ** ota is in the OTA_STAGE_OAL state, use heap memory for *-shm space 
+  ** instead of a file on disk.  */
+  if( pOtaVfs->pTargetDb==p && pOtaVfs->pOta->eStage==OTA_STAGE_OAL ){
+    if( iRegion<=p->nShm ){
+      int nByte = (iRegion+1) * sizeof(char*);
+      char **apNew = (char**)sqlite3_realloc(p->apShm, nByte);
+      if( apNew==0 ){
+        rc = SQLITE_NOMEM;
+      }else{
+        memset(&apNew[p->nShm], 0, sizeof(char*) * (1 + iRegion - p->nShm));
+        p->apShm = apNew;
+        p->nShm = iRegion+1;
+      }
+    }
+
+    if( rc==SQLITE_OK && p->apShm[iRegion]==0 ){
+      char *pNew = (char*)sqlite3_malloc(szRegion);
+      if( pNew==0 ){
+        rc = SQLITE_NOMEM;
+      }else{
+        p->apShm[iRegion] = pNew;
+      }
+    }
+
+    if( rc==SQLITE_OK ){
+      *pp = p->apShm[iRegion];
+    }else{
+      *pp = 0;
+    }
+  }else{
+    assert( p->apShm==0 );
+    rc = p->pReal->pMethods->xShmMap(p->pReal, iRegion, szRegion, isWrite, pp);
+  }
+
+  return rc;
+}
+
+/*
+** Memory barrier.
+*/
+static void otaVfsShmBarrier(sqlite3_file *pFile){
+  ota_file *p = (ota_file *)pFile;
+  p->pReal->pMethods->xShmBarrier(p->pReal);
+}
+
+static int otaVfsShmUnmap(sqlite3_file *pFile, int delFlag){
+  ota_file *p = (ota_file*)pFile;
+  ota_vfs *pOtaVfs = p->pOtaVfs;
+  int rc = SQLITE_OK;
+
+  if( pOtaVfs->pTargetDb==p && pOtaVfs->pOta->eStage==OTA_STAGE_OAL ){
+    /* no-op */
+  }else{
+    rc = p->pReal->pMethods->xShmUnmap(p->pReal, delFlag);
+  }
+  return rc;
+}
+
+
+static int otaVfsIswal(ota_vfs *pOtaVfs, const char *zPath){
+  int nPath = strlen(zPath);
+  int nTargetDb = strlen(pOtaVfs->zTargetDb);
+  return ( nPath==(nTargetDb+4) 
+        && 0==memcmp(zPath, pOtaVfs->zTargetDb, nTargetDb)
+        && 0==memcmp(&zPath[nTargetDb], "-wal", 4)
+  );
+}
+
+
+/*
+** Open an ota file handle.
+*/
+static int otaVfsOpen(
+  sqlite3_vfs *pVfs,
+  const char *zName,
+  sqlite3_file *pFile,
+  int flags,
+  int *pOutFlags
+){
+  static sqlite3_io_methods otavfs_io_methods = {
+    2,                            /* iVersion */
+    otaVfsClose,                  /* xClose */
+    otaVfsRead,                   /* xRead */
+    otaVfsWrite,                  /* xWrite */
+    otaVfsTruncate,               /* xTruncate */
+    otaVfsSync,                   /* xSync */
+    otaVfsFileSize,               /* xFileSize */
+    otaVfsLock,                   /* xLock */
+    otaVfsUnlock,                 /* xUnlock */
+    otaVfsCheckReservedLock,      /* xCheckReservedLock */
+    otaVfsFileControl,            /* xFileControl */
+    otaVfsSectorSize,             /* xSectorSize */
+    otaVfsDeviceCharacteristics,  /* xDeviceCharacteristics */
+    otaVfsShmMap,                 /* xShmMap */
+    otaVfsShmLock,                /* xShmLock */
+    otaVfsShmBarrier,             /* xShmBarrier */
+    otaVfsShmUnmap                /* xShmUnmap */
+  };
+  ota_vfs *pOtaVfs = (ota_vfs*)pVfs;
+  sqlite3_vfs *pRealVfs = pOtaVfs->pRealVfs;
+  sqlite3ota *p = pOtaVfs->pOta;
+  ota_file *pFd = (ota_file *)pFile;
+  int rc = SQLITE_OK;
+  const char *zOpen = zName;
+
+  memset(pFd, 0, sizeof(ota_file));
+  pFd->pReal = (sqlite3_file*)&pFd[1];
+  pFd->pOtaVfs = pOtaVfs;
+
+  if( zName && p->eStage==OTA_STAGE_OAL && otaVfsIswal(pOtaVfs, zName) ){
+    char *zCopy = otaStrndup(zName, -1, &rc);
+    if( zCopy ){
+      int nCopy = strlen(zCopy);
+      zCopy[nCopy-3] = 'o';
+      zOpen = (const char*)(pFd->zFilename = zCopy);
+    }
+  }
+
+  if( rc==SQLITE_OK ){
+    rc = pRealVfs->xOpen(pRealVfs, zOpen, pFd->pReal, flags, pOutFlags);
+  }
+  if( pFd->pReal->pMethods ){
+    pFile->pMethods = &otavfs_io_methods;
+    if( pOtaVfs->pTargetDb==0 ){
+      /* This is the target db file. */
+      assert( (flags & SQLITE_OPEN_MAIN_DB) );
+      assert( zOpen==zName );
+      pOtaVfs->pTargetDb = pFd;
+      pOtaVfs->zTargetDb = zName;
+    }
+  }
+
+  return rc;
+}
+
+/*
+** Delete the file located at zPath.
+*/
+static int otaVfsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
+  sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
+  return pRealVfs->xDelete(pRealVfs, zPath, dirSync);
+}
+
+/*
+** Test for access permissions. Return true if the requested permission
+** is available, or false otherwise.
+*/
+static int otaVfsAccess(
+  sqlite3_vfs *pVfs, 
+  const char *zPath, 
+  int flags, 
+  int *pResOut
+){
+  ota_vfs *pOtaVfs = (ota_vfs*)pVfs;
+  sqlite3_vfs *pRealVfs = pOtaVfs->pRealVfs;
+  int rc;
+
+  rc = pRealVfs->xAccess(pRealVfs, zPath, flags, pResOut);
+
+  if( rc==SQLITE_OK 
+   && flags==SQLITE_ACCESS_EXISTS 
+   && pOtaVfs->pOta->eStage==OTA_STAGE_OAL 
+   && otaVfsIswal(pOtaVfs, zPath) 
+  ){
+    if( *pResOut ){
+      rc = SQLITE_CANTOPEN;
+    }else{
+      *pResOut = 1;
+    }
+  }
+
+  return rc;
+}
+
+/*
+** Populate buffer zOut with the full canonical pathname corresponding
+** to the pathname in zPath. zOut is guaranteed to point to a buffer
+** of at least (DEVSYM_MAX_PATHNAME+1) bytes.
+*/
+static int otaVfsFullPathname(
+  sqlite3_vfs *pVfs, 
+  const char *zPath, 
+  int nOut, 
+  char *zOut
+){
+  sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
+  return pRealVfs->xFullPathname(pRealVfs, zPath, nOut, zOut);
+}
+
+#ifndef SQLITE_OMIT_LOAD_EXTENSION
+/*
+** Open the dynamic library located at zPath and return a handle.
+*/
+static void *otaVfsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
+  sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
+  return pRealVfs->xDlOpen(pRealVfs, zPath);
+}
+
+/*
+** Populate the buffer zErrMsg (size nByte bytes) with a human readable
+** utf-8 string describing the most recent error encountered associated 
+** with dynamic libraries.
+*/
+static void otaVfsDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
+  sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
+  pRealVfs->xDlError(pRealVfs, nByte, zErrMsg);
+}
+
+/*
+** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
+*/
+static void (*otaVfsDlSym(
+  sqlite3_vfs *pVfs, 
+  void *pArg, 
+  const char *zSym
+))(void){
+  sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
+  return pRealVfs->xDlSym(pRealVfs, pArg, zSym);
+}
+
+/*
+** Close the dynamic library handle pHandle.
+*/
+static void otaVfsDlClose(sqlite3_vfs *pVfs, void *pHandle){
+  sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
+  return pRealVfs->xDlClose(pRealVfs, pHandle);
+}
+#endif /* SQLITE_OMIT_LOAD_EXTENSION */
+
+/*
+** Populate the buffer pointed to by zBufOut with nByte bytes of 
+** random data.
+*/
+static int otaVfsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
+  sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
+  return pRealVfs->xRandomness(pRealVfs, nByte, zBufOut);
+}
+
+/*
+** Sleep for nMicro microseconds. Return the number of microseconds 
+** actually slept.
+*/
+static int otaVfsSleep(sqlite3_vfs *pVfs, int nMicro){
+  sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
+  return pRealVfs->xSleep(pRealVfs, nMicro);
+}
+
+/*
+** Return the current time as a Julian Day number in *pTimeOut.
+*/
+static int otaVfsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
+  sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
+  return pRealVfs->xCurrentTime(pRealVfs, pTimeOut);
+}
+
+static int otaVfsGetLastError(sqlite3_vfs *pVfs, int a, char *b){
+  return 0;
+}
+
+static void otaCreateVfs(sqlite3ota *p, const char *zParent){
+
+  /* Template for VFS */
+  static sqlite3_vfs vfs_template = {
+    1,                            /* iVersion */
+    0,                            /* szOsFile */
+    0,                            /* mxPathname */
+    0,                            /* pNext */
+    0,                            /* zName */
+    0,                            /* pAppData */
+    otaVfsOpen,                   /* xOpen */
+    otaVfsDelete,                 /* xDelete */
+    otaVfsAccess,                 /* xAccess */
+    otaVfsFullPathname,           /* xFullPathname */
+
+    otaVfsDlOpen,                 /* xDlOpen */
+    otaVfsDlError,                /* xDlError */
+    otaVfsDlSym,                  /* xDlSym */
+    otaVfsDlClose,                /* xDlClose */
+
+    otaVfsRandomness,             /* xRandomness */
+    otaVfsSleep,                  /* xSleep */
+    otaVfsCurrentTime,            /* xCurrentTime */
+    otaVfsGetLastError,           /* xGetLastError */
+    0,                            /* xCurrentTimeInt64 (version 2) */
+    0, 0, 0                       /* Unimplemented version 3 methods */
+  };
+
+  sqlite3_vfs *pParent;           /* Parent VFS */
+  ota_vfs *pNew = 0;              /* Newly allocated VFS */
+
+  assert( p->rc==SQLITE_OK );
+  pParent = sqlite3_vfs_find(zParent);
+  if( pParent==0 ){
+    p->rc = SQLITE_ERROR;
+    p->zErrmsg = sqlite3_mprintf("no such vfs: %s", zParent);
+  }else{
+    int nByte = sizeof(ota_vfs) + 64;
+    pNew = (ota_vfs*)otaMalloc(p, nByte);
+  }
+
+  if( pNew ){
+    int rnd;
+    char *zName;
+    memcpy(&pNew->base, &vfs_template, sizeof(sqlite3_vfs));
+    pNew->base.mxPathname = pParent->mxPathname;
+    pNew->base.szOsFile = sizeof(ota_file) + pParent->szOsFile;
+    pNew->pOta = p;
+    pNew->pRealVfs = pParent;
+
+    /* Give the new VFS a unique name */
+    sqlite3_randomness(sizeof(int), (void*)&rnd);
+    pNew->base.zName = (const char*)(zName = (char*)&pNew[1]);
+    sprintf(zName, "ota_vfs_%d", rnd);
+
+    /* Register the new VFS (not as the default) */
+    assert( p->rc==SQLITE_OK );
+    p->rc = sqlite3_vfs_register(&pNew->base, 0);
+    if( p->rc ){
+      p->zErrmsg = sqlite3_mprintf("error in sqlite3_vfs_register()");
+      sqlite3_free(pNew);
+    }else{
+      p->pVfs = &pNew->base;
+    }
+  }
+}
+
+static void otaDeleteVfs(sqlite3ota *p){
+  if( p->pVfs ){
+    sqlite3_vfs_unregister(p->pVfs);
+    sqlite3_free(p->pVfs);
+    p->pVfs = 0;
+  }
+}
+
 
 /**************************************************************************/
 
index 4d69256b43fe27f9460c2f211bb0ac8d4edeb7f1..93b2368df6ed69bae88c6f88aa03d7ee2237a4b0 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Merge\sthe\scommand-line\sshell\senhancements\sfrom\strunk.
-D 2015-02-06T15:03:45.342
+C Remove\s"PRAGMA\spager_ota_mode".
+D 2015-02-07T19:17:36.157
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 6b9e7677829aa94b9f30949656e27312aefb9a46
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -123,20 +123,18 @@ F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512
 F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95
 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e
 F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
-F ext/ota/README.txt 78d4a9f78f567d4bf826cf0f02df6254902562ca
+F ext/ota/README.txt 2ce4ffbb0aaa6731b041c27a7359f9a5f1c69152
 F ext/ota/ota.c c11a85af71dccc45976622fe7a51169a481caa91
-F ext/ota/ota1.test 719854e444dff2ead58ff6b62d8315954bd7762a
+F ext/ota/ota1.test e6b64d6ffb23dcae72386da153626b40566a69e9
 F ext/ota/ota10.test 85e0f6e7964db5007590c1b299e75211ed4240d4
-F ext/ota/ota2.test 2829bc08ffbb71b605392a68fedfd554763356a7
 F ext/ota/ota3.test a77efbce7723332eb688d2b28bf18204fc9614d7
-F ext/ota/ota4.test 82434aa39c9acca6cd6317f6b0ab07b0ec6c2e7d
 F ext/ota/ota5.test ad0799daf8923ddebffe75ae8c5504ca90b7fadb
-F ext/ota/ota6.test 82f1f757ec9b2ad07d6de4060b8e3ba8e44dfdd3
+F ext/ota/ota6.test 1fbba5fd46e3e0bfa5ae1d0caf9da27d15cb7cdf
 F ext/ota/ota7.test 1fe2c5761705374530e29f70c39693076028221a
 F ext/ota/ota8.test cd70e63a0c29c45c0906692827deafa34638feda
 F ext/ota/ota9.test d3eee95dd836824d07a22e5efcdb7bf6e869358b
 F ext/ota/otafault.test 508ba87c83d632670ac0f94371a465d4bb4d49dd
-F ext/ota/sqlite3ota.c bf417242a191617841cc1ab0815071b49444c9c8
+F ext/ota/sqlite3ota.c 7015400382d1d6655626046f2c1763634dd8a168
 F ext/ota/sqlite3ota.h b4c54c7df5d223f2ee40efa5ba363188daa3ad37
 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
 F ext/rtree/rtree.c 14e6239434d4e3f65d3e90320713f26aa24e167f
@@ -232,14 +230,14 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
 F src/os_unix.c aefeaf915aaef9f81aa2645e0d5d06fa1bd83beb
 F src/os_win.c 8223e7db5b7c4a81d8b161098ac3959400434cdb
 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
-F src/pager.c 90b164ac8fefed940cd50fad6938cd18b55af8f3
-F src/pager.h 19d83e2782fe978976cb1acf474d09d9a6124ac3
+F src/pager.c 46bc7849b02c51e13f0165fa6d6faa452e91a957
+F src/pager.h 20954a3fa1bbf05d39063d94e789ad9efd15e5d1
 F src/parse.y c5d0d964f9ac023e8154cad512e54b0b6058e086
 F src/pcache.c d210cf90d04365a74f85d21374dded65af67b0cb
 F src/pcache.h b44658c9c932d203510279439d891a2a83e12ba8
 F src/pcache1.c 1e77432b40b7d3288327d9cdf399dcdfd2b6d3bf
-F src/pragma.c 8042d2b202140c49ffccb267aaa2012b50e337e4
-F src/pragma.h d2f776d719d156544638fe3f87f9627d8e16222f
+F src/pragma.c ea0be138a99784b14e87bd4522fea40e7b979e9c
+F src/pragma.h 09c89bca58e9a44de2116cc8272b8d454657129f
 F src/prepare.c 173a5a499138451b2561614ecb87d78f9f4644b9
 F src/printf.c 05edc41450d0eb2c05ef7db113bf32742ae65325
 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
@@ -318,7 +316,7 @@ F src/vdbemem.c 31d8eabb0cd78bfeab4e5124c7363c3e9e54db9f
 F src/vdbesort.c 6d64c5448b64851b99931ede980addc3af70d5e2
 F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010
 F src/vtab.c c08ec66f45919eaa726bf88aa53eb08379d607f9
-F src/wal.c 735d081f736fd7fecbf8f2aa213484e641ba35ff
+F src/wal.c 7a8a4e7a40d693d44dbfc4d1f2bcb7e2b620f530
 F src/wal.h 0d3ba0c3f1b4c25796cb213568a84b9f9063f465
 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804
 F src/where.c d46de821bc604a4fd36fa3928c086950e91aafb1
@@ -1219,7 +1217,7 @@ F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6
 F tool/mkautoconfamal.sh d1a2da0e15b2ed33d60af35c7e9d483f13a8eb9f
 F tool/mkkeywordhash.c dfff09dbbfaf950e89af294f48f902181b144670
 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
-F tool/mkpragmatab.tcl a5cb9b20ad7abb2ffd519c85f1f8f99bcbfa6823
+F tool/mkpragmatab.tcl 94f196c9961e0ca3513e29f57125a3197808be2d
 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
 F tool/mksqlite3c-noext.tcl 9ef48e1748dce7b844f67e2450ff9dfeb0fb4ab5
 F tool/mksqlite3c.tcl 6b8e572a90eb4e0086e3ba90d88b76c085919863
@@ -1255,7 +1253,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 7f10a0eaf1fedfa020cbd7019ec9342ffdc3b9b0 0f65a7e2e09f801b66897479d501607caeae4abf
-R 1ef390b8e8775fda79ba88277a4a2044
-U drh
-Z f716caa3559c7f56ae8a7035846f96fb
+P c3931db560ab4a2601c7f7318fb02c8d5e6862b1
+R 8cb076bc2c2cc0b3b28786011832c69d
+T *branch * ota-update-no-pager_ota_mode
+T *sym-ota-update-no-pager_ota_mode *
+T -sym-ota-update *
+U dan
+Z b552e61eecb5b9b2a0bf7b3905abae17
index 67420b8cdc978e877f05318f41551283bfe35832..78b4daf1f53e1f42ddfc01a4fb0bd9524742fba9 100644 (file)
@@ -1 +1 @@
-c3931db560ab4a2601c7f7318fb02c8d5e6862b1
\ No newline at end of file
+8ac58e46782bd6b81c06fdf1cb5b316b8a4e1ddf
\ No newline at end of file
index 7cc35505f65371370c6c74bcc5b7057f1296ea61..4b8e31d51373aeb0b1eb7225599861f870705d2d 100644 (file)
@@ -642,9 +642,6 @@ struct Pager {
   u8 noLock;                  /* Do not lock (except in WAL mode) */
   u8 readOnly;                /* True for a read-only database */
   u8 memDb;                   /* True to inhibit all file I/O */
-#ifdef SQLITE_ENABLE_OTA
-  u8 otaMode;                 /* Non-zero if in ota_mode */
-#endif
 
   /**************************************************************************
   ** The following block contains those class members that change during
@@ -720,16 +717,6 @@ struct Pager {
 #endif
 };
 
-/*
-** Return the value of the pager otaMode flag (0, 1 or 2). Or, if
-** SQLITE_ENABLE_OTA is not defined, return constant value 0.
-*/
-#ifdef SQLITE_ENABLE_OTA
-# define PagerOtaMode(pPager) ((pPager)->otaMode)
-#else
-# define PagerOtaMode(pPager) 0
-#endif
-
 /*
 ** Indexes for use with Pager.aStat[]. The Pager.aStat[] array contains
 ** the values accessed by passing SQLITE_DBSTATUS_CACHE_HIT, CACHE_MISS 
@@ -2052,7 +2039,7 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){
     if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
   }
 
-  if( !pPager->exclusiveMode && !PagerOtaMode(pPager)
+  if( !pPager->exclusiveMode
    && (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0))
   ){
     rc2 = pagerUnlockDb(pPager, SHARED_LOCK);
@@ -4007,9 +3994,7 @@ int sqlite3PagerClose(Pager *pPager){
   /* pPager->errCode = 0; */
   pPager->exclusiveMode = 0;
 #ifndef SQLITE_OMIT_WAL
-  sqlite3WalClose(pPager->pWal, 
-      pPager->ckptSyncFlags, pPager->pageSize, (PagerOtaMode(pPager)?0:pTmp)
-  );
+  sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags, pPager->pageSize, pTmp);
   pPager->pWal = 0;
 #endif
   pager_reset(pPager);
@@ -5210,11 +5195,6 @@ int sqlite3PagerSharedLock(Pager *pPager){
     ** mode. Otherwise, the following function call is a no-op.
     */
     rc = pagerOpenWalIfPresent(pPager);
-    if( rc==SQLITE_OK && PagerOtaMode(pPager) ){
-      int nWal = sqlite3Strlen30(pPager->zWal);
-      pPager->zWal[nWal-3] = 'o';
-      rc = pagerOpenWalInternal(pPager, 0);
-    }
 
 #ifndef SQLITE_OMIT_WAL
     assert( pPager->pWal==0 || rc==SQLITE_OK );
@@ -5224,17 +5204,6 @@ int sqlite3PagerSharedLock(Pager *pPager){
   if( pagerUseWal(pPager) ){
     assert( rc==SQLITE_OK );
     rc = pagerBeginReadTransaction(pPager);
-    if( rc==SQLITE_OK && PagerOtaMode(pPager)==1 ){
-      rc = sqlite3WalCheckSalt(pPager->pWal, pPager->fd);
-      if( rc!=SQLITE_OK ){
-        sqlite3WalClose(pPager->pWal, 0, 0, 0);
-        pPager->pWal = 0;
-      }else{
-#ifdef SQLITE_ENABLE_OTA
-        pPager->otaMode = 2;
-#endif
-      }
-    }
   }
 
   if( pPager->eState==PAGER_OPEN && rc==SQLITE_OK ){
@@ -7129,7 +7098,7 @@ void sqlite3PagerClearCache(Pager *pPager){
 */
 int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){
   int rc = SQLITE_OK;
-  if( pPager->pWal && PagerOtaMode(pPager)==0 ){
+  if( pPager->pWal ){
     rc = sqlite3WalCheckpoint(pPager->pWal, eMode,
         (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
         pPager->pBusyHandlerArg,
@@ -7197,7 +7166,7 @@ static int pagerOpenWal(Pager *pPager){
   */
   if( rc==SQLITE_OK ){
     rc = sqlite3WalOpen(pPager->pVfs,
-        pPager->fd, pPager->zWal, pPager->exclusiveMode || PagerOtaMode(pPager),
+        pPager->fd, pPager->zWal, pPager->exclusiveMode,
         pPager->journalSizeLimit, &pPager->pWal
     );
   }
@@ -7263,7 +7232,6 @@ int sqlite3PagerOpenWal(
   Pager *pPager,                  /* Pager object */
   int *pbOpen                     /* OUT: Set to true if call is a no-op */
 ){
-  if( PagerOtaMode(pPager) ) return SQLITE_CANTOPEN_BKPT;
   return pagerOpenWalInternal(pPager, pbOpen);
 }
 
@@ -7313,20 +7281,6 @@ int sqlite3PagerCloseWal(Pager *pPager){
   return rc;
 }
 
-/*
-** This function is called by the wal.c module to obtain the 8 bytes of 
-** "salt" written into the wal file header. In OTA mode, this is a copy
-** of bytes 24-31 of the database file. In non-OTA mode, it is 8 bytes
-** of pseudo-random data.
-*/
-void sqlite3PagerWalSalt(Pager *pPager, u32 *aSalt){
-  if( PagerOtaMode(pPager) ){
-    memcpy(aSalt, pPager->dbFileVers, 8);
-  }else{
-    sqlite3_randomness(8, aSalt);
-  }
-}
-
 #endif /* !SQLITE_OMIT_WAL */
 
 #ifdef SQLITE_ENABLE_ZIPVFS
@@ -7344,17 +7298,6 @@ int sqlite3PagerWalFramesize(Pager *pPager){
 #endif
 
 #ifdef SQLITE_ENABLE_OTA
-/*
-** Set or clear the "OTA mode" flag.
-*/
-int sqlite3PagerSetOtaMode(Pager *pPager, int iOta){
-  assert( iOta==1 || iOta==2 );
-  if( iOta==1 && (pPager->pWal || pPager->eState!=PAGER_OPEN) ){
-    return SQLITE_ERROR;
-  }
-  pPager->otaMode = iOta;
-  return SQLITE_OK;
-}
 
 /*
 ** Open an incremental checkpoint handle.
index 289ef9d42b4f6469c99f5ce5fe2bbad8e68b5e98..10df8e0deb4f43712e57f224073069dab14b7587 100644 (file)
@@ -210,8 +210,6 @@ void *sqlite3PagerCodec(DbPage *);
 # define enable_simulated_io_errors()
 #endif
 
-int sqlite3PagerSetOtaMode(Pager *pPager, int bOta);
-void sqlite3PagerWalSalt(Pager *pPager, u32 *aSalt);
 int sqlite3PagerWalCheckpointStart(sqlite3*, Pager*, u8*, int, sqlite3_ckpt**);
 
 #endif /* _PAGER_H_ */
index d4c5ba51dc3abc3a700f527326a17f3ea25068c2..ac217d45970c75ad2e8f42feb32287bffefc0e42 100644 (file)
@@ -422,50 +422,6 @@ void sqlite3Pragma(
   }
 #endif /* !SQLITE_OMIT_PAGER_PRAGMAS && !SQLITE_OMIT_DEPRECATED */
 
-  /*
-  **  PRAGMA [database.]pager_ota_mode=[01]
-  **
-  ** This pragma sets a flag on the pager associated with the main database
-  ** only. The flag can only be set when there is no open transaction and 
-  ** the pager does not already have an open WAL file.
-  **
-  ** Once the flag has been set, it is not possible to open a regular WAL
-  ** file. If, when the next read-transaction is opened, a *-wal file is 
-  ** found or the database header flags indicate that it is a wal-mode 
-  ** database, SQLITE_CANTOPEN is returned.
-  **
-  ** Otherwise, if no WAL file or flags are found, the pager opens the *-oal
-  ** file and uses it as a write-ahead-log with the *-shm data stored in
-  ** heap-memory. If the *-oal file already exists but the database file has
-  ** been modified since it was created, an SQLITE_BUSY_SNAPSHOT error is
-  ** returned and the read-transaction cannot be opened.
-  **
-  ** Other clients see a rollback-mode database on which the pager_ota_mode
-  ** client is holding a SHARED lock.
-  */
-#ifdef SQLITE_ENABLE_OTA
-  case PragTyp_PAGER_OTA_MODE: {
-    Btree *pBt = pDb->pBt;
-    assert( pBt!=0 );
-    if( zRight ){
-      int iArg = sqlite3Atoi(zRight);
-      Pager *pPager = sqlite3BtreePager(pBt);
-      if( sqlite3BtreeIsInReadTrans(pBt) ){
-        sqlite3ErrorMsg(pParse, 
-            "cannot set pager_ota_mode with open transaction"
-        );
-      }else if( sqlite3PagerWalSupported(pPager)==0 ){
-        sqlite3ErrorMsg(pParse,
-            "cannot set pager_ota_mode without wal support"
-        );
-      }else if( sqlite3PagerSetOtaMode(sqlite3BtreePager(pBt), iArg) ){
-        sqlite3ErrorMsg(pParse, "cannot set pager_ota_mode in wal mode");
-      }
-    }
-    break;
-  }
-#endif /* SQLITE_ENABLE_OTA */
-
 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
   /*
   **  PRAGMA [database.]page_size
index b2cf43911bdcd0e94da58f000304030636d4b5cb..c9ae8e6eb8e94e4857b5029b69e4fe333c6201ce 100644 (file)
 #define PragTyp_PAGE_COUNT                    22
 #define PragTyp_MMAP_SIZE                     23
 #define PragTyp_PAGE_SIZE                     24
-#define PragTyp_PAGER_OTA_MODE                25
-#define PragTyp_SECURE_DELETE                 26
-#define PragTyp_SHRINK_MEMORY                 27
-#define PragTyp_SOFT_HEAP_LIMIT               28
-#define PragTyp_STATS                         29
-#define PragTyp_SYNCHRONOUS                   30
-#define PragTyp_TABLE_INFO                    31
-#define PragTyp_TEMP_STORE                    32
-#define PragTyp_TEMP_STORE_DIRECTORY          33
-#define PragTyp_THREADS                       34
-#define PragTyp_WAL_AUTOCHECKPOINT            35
-#define PragTyp_WAL_CHECKPOINT                36
-#define PragTyp_ACTIVATE_EXTENSIONS           37
-#define PragTyp_HEXKEY                        38
-#define PragTyp_KEY                           39
-#define PragTyp_REKEY                         40
-#define PragTyp_LOCK_STATUS                   41
-#define PragTyp_PARSER_TRACE                  42
+#define PragTyp_SECURE_DELETE                 25
+#define PragTyp_SHRINK_MEMORY                 26
+#define PragTyp_SOFT_HEAP_LIMIT               27
+#define PragTyp_STATS                         28
+#define PragTyp_SYNCHRONOUS                   29
+#define PragTyp_TABLE_INFO                    30
+#define PragTyp_TEMP_STORE                    31
+#define PragTyp_TEMP_STORE_DIRECTORY          32
+#define PragTyp_THREADS                       33
+#define PragTyp_WAL_AUTOCHECKPOINT            34
+#define PragTyp_WAL_CHECKPOINT                35
+#define PragTyp_ACTIVATE_EXTENSIONS           36
+#define PragTyp_HEXKEY                        37
+#define PragTyp_KEY                           38
+#define PragTyp_REKEY                         39
+#define PragTyp_LOCK_STATUS                   40
+#define PragTyp_PARSER_TRACE                  41
 #define PragFlag_NeedSchema           0x01
 #define PragFlag_ReadOnly             0x02
 static const struct sPragmaNames {
@@ -304,12 +303,6 @@ static const struct sPragmaNames {
     /* ePragFlag: */ 0,
     /* iArg:      */ 0 },
 #endif
-#if defined(SQLITE_ENABLE_OTA)
-  { /* zName:     */ "pager_ota_mode",
-    /* ePragTyp:  */ PragTyp_PAGER_OTA_MODE,
-    /* ePragFlag: */ 0,
-    /* iArg:      */ 0 },
-#endif
 #if defined(SQLITE_DEBUG)
   { /* zName:     */ "parser_trace",
     /* ePragTyp:  */ PragTyp_PARSER_TRACE,
@@ -463,4 +456,4 @@ static const struct sPragmaNames {
     /* iArg:      */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
 #endif
 };
-/* Number of pragmas: 59 on by default, 73 total. */
+/* Number of pragmas: 59 on by default, 72 total. */
index bf2ef44a465cae74263f7d7267d57dde8804407c..fb51ac9fd284ead099f7968d174602c0a18cb500 100644 (file)
--- a/src/wal.c
+++ b/src/wal.c
@@ -2920,9 +2920,7 @@ int sqlite3WalFrames(
     sqlite3Put4byte(&aWalHdr[4], WAL_MAX_VERSION);
     sqlite3Put4byte(&aWalHdr[8], szPage);
     sqlite3Put4byte(&aWalHdr[12], pWal->nCkpt);
-    if( pWal->nCkpt==0 ){
-      sqlite3PagerWalSalt(pList->pPager, pWal->hdr.aSalt);
-    }
+    if( pWal->nCkpt==0 ) sqlite3_randomness(8, pWal->hdr.aSalt);
     memcpy(&aWalHdr[16], pWal->hdr.aSalt, 8);
     walChecksumBytes(1, aWalHdr, WAL_HDRSIZE-2*4, 0, aCksum);
     sqlite3Put4byte(&aWalHdr[24], aCksum[0]);
index 5627a19d354f3acbd2a271550e486c641f068461..964946e788021fac4af805929d8453075137f9c0 100644 (file)
@@ -315,9 +315,6 @@ set pragma_def {
   NAME: soft_heap_limit
 
   NAME: threads
-
-  NAME: pager_ota_mode
-  IF:   defined(SQLITE_ENABLE_OTA)
 }
 
 # Open the output file