From: dan Date: Sat, 7 Feb 2015 19:17:36 +0000 (+0000) Subject: Remove "PRAGMA pager_ota_mode". X-Git-Tag: version-3.8.11~252^2~48^2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dd0ad3785b8124abdd23e9b97be8b8b971b4fdaa;p=thirdparty%2Fsqlite.git Remove "PRAGMA pager_ota_mode". FossilOrigin-Name: 8ac58e46782bd6b81c06fdf1cb5b316b8a4e1ddf --- diff --git a/ext/ota/README.txt b/ext/ota/README.txt index 943d1822af..42ac29064c 100644 --- a/ext/ota/README.txt +++ b/ext/ota/README.txt @@ -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. diff --git a/ext/ota/ota1.test b/ext/ota/ota1.test index afb5fd5865..265a3d2a2f 100644 --- a/ext/ota/ota1.test +++ b/ext/ota/ota1.test @@ -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 index 3c273e348a..0000000000 --- a/ext/ota/ota2.test +++ /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 index a12cbd8b7b..0000000000 --- a/ext/ota/ota4.test +++ /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 - diff --git a/ext/ota/ota6.test b/ext/ota/ota6.test index f15873629c..8027f36c5f 100644 --- a/ext/ota/ota6.test +++ b/ext/ota/ota6.test @@ -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 - diff --git a/ext/ota/sqlite3ota.c b/ext/ota/sqlite3ota.c index 20b9ede75b..2e23d5658c 100644 --- a/ext/ota/sqlite3ota.c +++ b/ext/ota/sqlite3ota.c @@ -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; inShm; 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; + } +} + /**************************************************************************/ diff --git a/manifest b/manifest index 4d69256b43..93b2368df6 100644 --- 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 diff --git a/manifest.uuid b/manifest.uuid index 67420b8cdc..78b4daf1f5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c3931db560ab4a2601c7f7318fb02c8d5e6862b1 \ No newline at end of file +8ac58e46782bd6b81c06fdf1cb5b316b8a4e1ddf \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 7cc35505f6..4b8e31d513 100644 --- a/src/pager.c +++ b/src/pager.c @@ -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. diff --git a/src/pager.h b/src/pager.h index 289ef9d42b..10df8e0deb 100644 --- a/src/pager.h +++ b/src/pager.h @@ -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_ */ diff --git a/src/pragma.c b/src/pragma.c index d4c5ba51dc..ac217d4597 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -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 diff --git a/src/pragma.h b/src/pragma.h index b2cf43911b..c9ae8e6eb8 100644 --- a/src/pragma.h +++ b/src/pragma.h @@ -28,24 +28,23 @@ #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. */ diff --git a/src/wal.c b/src/wal.c index bf2ef44a46..fb51ac9fd2 100644 --- 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]); diff --git a/tool/mkpragmatab.tcl b/tool/mkpragmatab.tcl index 5627a19d35..964946e788 100644 --- a/tool/mkpragmatab.tcl +++ b/tool/mkpragmatab.tcl @@ -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