]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add SQLITE_ENABLE_OTA pre-processor directives so that this branch may be compiled...
authordan <dan@noemail.net>
Sat, 22 Nov 2014 09:09:50 +0000 (09:09 +0000)
committerdan <dan@noemail.net>
Sat, 22 Nov 2014 09:09:50 +0000 (09:09 +0000)
FossilOrigin-Name: 600cefdd4d29c1de4d107fa7ddeb76a18edce4f5

14 files changed:
ext/ota/sqlite3ota.c
manifest
manifest.uuid
src/main.c
src/pager.c
src/pragma.c
src/sqlite.h.in
src/sqliteInt.h
src/test_config.c
src/trigger.c
src/vdbeblob.c
src/wal.c
test/ota.test
tool/mkpragmatab.tcl

index 8613c179f633421bdf41de2375e45d91c2b4590b..6c3c99434e6e39f29e528a7d36ea2ee9b30ebf0c 100644 (file)
@@ -17,6 +17,8 @@
 #include <unistd.h>
 
 #include "sqlite3.h"
+
+#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_OTA)
 #include "sqlite3ota.h"
 
 
@@ -1662,12 +1664,18 @@ static int test_sqlite3ota(
   return TCL_OK;
 }
 
+
 int SqliteOta_Init(Tcl_Interp *interp){ 
   Tcl_CreateObjCommand(interp, "sqlite3ota", test_sqlite3ota, 0, 0);
   return TCL_OK;
 }
-
 #endif                  /* ifdef SQLITE_TEST */
+#else   /* !SQLITE_CORE || SQLITE_ENABLE_OTA */
+# ifdef SQLITE_TEST
+#include <tcl.h>
+int SqliteOta_Init(Tcl_Interp *interp){ return TCL_OK; }
+# endif
+#endif 
 
 
 
index bb2073b96b5c92c433901444278b8fe84a4a8da5..5d142cd5c1f0d600012cfec1be169733c26a4723 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Merge\slatest\strunk\schanges\swith\sthis\sbranch.
-D 2014-11-21T14:37:24.898
+C Add\sSQLITE_ENABLE_OTA\spre-processor\sdirectives\sso\sthat\sthis\sbranch\smay\sbe\scompiled\swith\sor\swithout\sOTA.
+D 2014-11-22T09:09:50.320
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in a226317fdf3f4c895fb3cfedc355b4d0868ce1fb
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -135,7 +135,7 @@ F ext/ota/ota7.test 1fe2c5761705374530e29f70c39693076028221a
 F ext/ota/ota8.test cd70e63a0c29c45c0906692827deafa34638feda
 F ext/ota/ota9.test d9ad30ccb4e08f878e382876fe67752309538af9
 F ext/ota/otafault.test be02466863015a583cc0ceb6aca871a5e6f7a71b
-F ext/ota/sqlite3ota.c 07ef7b72358ed422b69a10e4702ab131041e2896
+F ext/ota/sqlite3ota.c accfada2ab182dc52225e7345f656520a4e8db22
 F ext/ota/sqlite3ota.h 04577b00c456aacb99be9c8b55572a6e3ca9aa27
 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
 F ext/rtree/rtree.c 57bec53e1a677ab74217fe1f20a58c3a47261d6b
@@ -209,7 +209,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
 F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e
 F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770
 F src/loadext.c de741e66e5ddc1598d904d7289239696e40ed994
-F src/main.c e2adfa1e7bef8b553a1e7c250cc02bcb109d15f2
+F src/main.c cd819123ed552a15c37bd2fd5360db25015dc461
 F src/malloc.c 740db54387204c9a2eb67c6d98e68b08e9ef4eab
 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
 F src/mem1.c faf615aafd8be74a71494dfa027c113ea5c6615f
@@ -230,13 +230,13 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
 F src/os_unix.c fb587121840f690101336879adfa6d0b2cd0e8c7
 F src/os_win.c a9e500dd963fb1f67d7860e58b5772abe6123862
 F src/os_win.h 09e751b20bbc107ffbd46e13555dc73576d88e21
-F src/pager.c c2a4795e65b5794248dadd7c8bb65a8d9145995e
+F src/pager.c 9fe27a768be53dbe0a818ae10791dc36100a0e76
 F src/pager.h c6157af66a9999797629968921133f67716f8f9f
 F src/parse.y 5dfead8aed90cb0c7c1115898ee2266804daff45
 F src/pcache.c ace1b67632deeaa84859b4c16c27711dfb7db3d4
 F src/pcache.h b44658c9c932d203510279439d891a2a83e12ba8
 F src/pcache1.c facbdd3ecc09c8f750089d941305694301328e98
-F src/pragma.c 272b122a873fc756e999c319f8e81de55ef39d5c
+F src/pragma.c 8e0087a5ae6e60ac9ed48df19025cb423e3c8c34
 F src/prepare.c b7b7bf020bd4c962f7c8aed5a3c542c7dfe9f9c7
 F src/printf.c 9e75a6a0b55bf61cfff7d7e19d89834a1b938236
 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
@@ -244,10 +244,10 @@ F src/resolve.c 4965007d6497b6a4d7a6d98751cc39712885f952
 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
 F src/select.c 428165951748151e87a15295b7357221433e311b
 F src/shell.c bc28d5992109717c87804e2eb1a08a7c8cc7a2fd
-F src/sqlite.h.in 972125a6b4ea1891d2428cc55302c71f0fb1adb3
+F src/sqlite.h.in f60a24616a6a7e622266e723ed141f0c6131514e
 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
 F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
-F src/sqliteInt.h d96b5f3ee07d35b52aa54a279028105b33a9592c
+F src/sqliteInt.h 32d7becef5cbd9a1118608921ec99f00f96c6e5d
 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
 F src/status.c 81712116e826b0089bb221b018929536b2b5406f
 F src/table.c f142bba7903e93ca8d113a5b8877a108ad1a27dc
@@ -266,7 +266,7 @@ F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12
 F src/test_backup.c 3875e899222b651e18b662f86e0e50daa946344e
 F src/test_blob.c 1f2e3e25255b731c4fcf15ee7990d06347cb6c09
 F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f
-F src/test_config.c 035c17a173937d019b8dfc1d524f9d3fc8123504
+F src/test_config.c 7d50e35f5e94235863c9bac448f63b0d141119e5
 F src/test_demovfs.c 69b2085076654ebc18014cbc6386f04409c959a9
 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
 F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f
@@ -300,7 +300,7 @@ F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
 F src/threads.c 6de09362b657f19ba83e5fa521ee715787ce9fee
 F src/tokenize.c cc9016e5007fc5e76789079616d2f26741bcc689
-F src/trigger.c eb921d1292aca83d515bde5881df71df91d962d6
+F src/trigger.c 6dcdf46a21acf4d4e011c809b2c971e63f797a1a
 F src/update.c 3c4ecc282accf12d39edb8d524cf089645e55a13
 F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
 F src/util.c 3b627daa45c7308c1e36e3dbaa3f9ce7e5c7fa73
@@ -310,12 +310,12 @@ F src/vdbe.h 6fc69d9c5e146302c56e163cb4b31d1ee64a18c3
 F src/vdbeInt.h 9bb69ff2447c34b6ccc58b34ec35b615f86ead78
 F src/vdbeapi.c 07acb615d1e4170e71fc1b0d087f3c53a1ad8e83
 F src/vdbeaux.c 5ce4f414147a3bc3cbcf00ec57f2606c25791629
-F src/vdbeblob.c 845c24601a4f107f4829725fa0c672b93b816bab
+F src/vdbeblob.c 317c71482ed73b0966db2d1c4e20839be3e9fe79
 F src/vdbemem.c 31d8eabb0cd78bfeab4e5124c7363c3e9e54db9f
 F src/vdbesort.c 87f3923483113d1c95d84640becb4e4946f27d9a
 F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010
 F src/vtab.c 2a30791bbd7926b589401bd09c3abb33de563793
-F src/wal.c e8fe2d73c40066872f97db5809ea62f285175825
+F src/wal.c d5c581b635951cf5513ec9699d118b32323443f3
 F src/wal.h 0d3ba0c3f1b4c25796cb213568a84b9f9063f465
 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804
 F src/where.c e275cb74731a3351a9da6ba8280bd5054db6192d
@@ -777,7 +777,7 @@ F test/orderby5.test 8f08a54836d21fb7c70245360751aedd1c2286fb
 F test/orderby6.test 8b38138ab0972588240b3fca0985d2e400432859
 F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da
 F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3
-F test/ota.test d81a211dfbdf9fe02b5ad50c86f8a5df924391f5
+F test/ota.test 3a8d97cbf8f7210dc6a638797c4e4cd674036927
 F test/ovfl.test 4f7ca651cba5c059a12d8c67dddd49bec5747799
 F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa
 F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71
@@ -1200,7 +1200,7 @@ F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6
 F tool/mkautoconfamal.sh 5dc5010e2e748a9e1bba67baca5956a2c2deda7b
 F tool/mkkeywordhash.c dfff09dbbfaf950e89af294f48f902181b144670
 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
-F tool/mkpragmatab.tcl 22c85e67987ad7d2e8789c48506ec95b99a90c08
+F tool/mkpragmatab.tcl 7c9f48bfe61ba0e4018868bf34b2450026c24ae1
 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
 F tool/mksqlite3c-noext.tcl 88a1e3b0c769773fb7a9ebb363ffc603a4ac21d8
 F tool/mksqlite3c.tcl e72c0c97fe1a105fa9616483e652949be2199fe6
@@ -1236,7 +1236,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 14139542b68fbf01632a1b149cd6fca4bb01efa6 b1e6c02f8b9a2afaa12ac15a33e3f698c3be27d6
-R 0115f003ae5ca012270e27f3f42f3f8e
+P 7ef44c5b5bd30bcc4ef59ed172b9ce9ac6a843f6
+R a969a1e9314cd2ef179f3839efd0b8ec
 U dan
-Z 7ed6e391881cc7d739c6ad1cb9d3b777
+Z bba2f4cd69d571c58d439710133b8bb2
index ab5ea12dd744c41f5f37676a53e288976e8bb3ec..3c2a061073e6326cc958209e164e0bcb70550adc 100644 (file)
@@ -1 +1 @@
-7ef44c5b5bd30bcc4ef59ed172b9ce9ac6a843f6
\ No newline at end of file
+600cefdd4d29c1de4d107fa7ddeb76a18edce4f5
\ No newline at end of file
index 2ba085d9ea80141ab3c48186dedc396b9c59c413..12dd56e2a1f60f246be0a769dda8f973b030a78a 100644 (file)
@@ -1960,6 +1960,7 @@ int sqlite3_wal_checkpoint_v2(
 #endif
 }
 
+#ifdef SQLITE_ENABLE_OTA
 /*
 ** Open an incremental checkpoint handle.
 */
@@ -1984,6 +1985,7 @@ int sqlite3_ckpt_open(
   sqlite3_mutex_leave(db->mutex);
   return rc;
 }
+#endif /* SQLITE_ENABLE_OTA */
 
 
 /*
index db511c3f20dc28f14070d637f2249a0f6f0660d8..3508a9f937c2cb74f8da5af04345c91f5519969b 100644 (file)
@@ -642,7 +642,9 @@ 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
@@ -716,6 +718,16 @@ 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 
@@ -2029,7 +2041,7 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){
     if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
   }
 
-  if( !pPager->exclusiveMode && !pPager->otaMode
+  if( !pPager->exclusiveMode && !PagerOtaMode(pPager)
    && (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0))
   ){
     rc2 = pagerUnlockDb(pPager, SHARED_LOCK);
@@ -3985,7 +3997,7 @@ int sqlite3PagerClose(Pager *pPager){
   pPager->exclusiveMode = 0;
 #ifndef SQLITE_OMIT_WAL
   sqlite3WalClose(pPager->pWal, 
-      pPager->ckptSyncFlags, pPager->pageSize, (pPager->otaMode?0:pTmp)
+      pPager->ckptSyncFlags, pPager->pageSize, (PagerOtaMode(pPager)?0:pTmp)
   );
   pPager->pWal = 0;
 #endif
@@ -5191,7 +5203,7 @@ int sqlite3PagerSharedLock(Pager *pPager){
     ** mode. Otherwise, the following function call is a no-op.
     */
     rc = pagerOpenWalIfPresent(pPager);
-    if( rc==SQLITE_OK && pPager->otaMode ){
+    if( rc==SQLITE_OK && PagerOtaMode(pPager) ){
       int nWal = sqlite3Strlen30(pPager->zWal);
       pPager->zWal[nWal-3] = 'o';
       rc = pagerOpenWalInternal(pPager, 0);
@@ -5205,13 +5217,15 @@ int sqlite3PagerSharedLock(Pager *pPager){
   if( pagerUseWal(pPager) ){
     assert( rc==SQLITE_OK );
     rc = pagerBeginReadTransaction(pPager);
-    if( rc==SQLITE_OK && pPager->otaMode==1 ){
+    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
       }
     }
   }
@@ -7105,7 +7119,7 @@ void sqlite3PagerClearCache(Pager *pPager){
 */
 int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){
   int rc = SQLITE_OK;
-  if( pPager->pWal && pPager->otaMode==0 ){
+  if( pPager->pWal && PagerOtaMode(pPager)==0 ){
     rc = sqlite3WalCheckpoint(pPager->pWal, eMode,
         pPager->xBusyHandler, pPager->pBusyHandlerArg,
         pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
@@ -7172,7 +7186,7 @@ static int pagerOpenWal(Pager *pPager){
   */
   if( rc==SQLITE_OK ){
     rc = sqlite3WalOpen(pPager->pVfs,
-        pPager->fd, pPager->zWal, pPager->exclusiveMode || pPager->otaMode,
+        pPager->fd, pPager->zWal, pPager->exclusiveMode || PagerOtaMode(pPager),
         pPager->journalSizeLimit, &pPager->pWal
     );
   }
@@ -7181,6 +7195,14 @@ static int pagerOpenWal(Pager *pPager){
   return rc;
 }
 
+/*
+** Open the WAL file if it is not open. If it is already open, set *pbOpen
+** to 1 before returning. Return SQLITE_OK if successful, or an SQLite error
+** code otherwise.
+**
+** The difference between this function and sqlite3PagerOpenWal() is that
+** PagerOpenWal() does not open the WAL file if the pager is in OTA mode.
+*/
 static int pagerOpenWalInternal(
   Pager *pPager,                  /* Pager object */
   int *pbOpen                     /* OUT: Set to true if call is a no-op */
@@ -7230,7 +7252,7 @@ int sqlite3PagerOpenWal(
   Pager *pPager,                  /* Pager object */
   int *pbOpen                     /* OUT: Set to true if call is a no-op */
 ){
-  if( pPager->otaMode ) return SQLITE_CANTOPEN;
+  if( PagerOtaMode(pPager) ) return SQLITE_CANTOPEN_BKPT;
   return pagerOpenWalInternal(pPager, pbOpen);
 }
 
@@ -7287,7 +7309,7 @@ int sqlite3PagerCloseWal(Pager *pPager){
 ** of pseudo-random data.
 */
 void sqlite3PagerWalSalt(Pager *pPager, u32 *aSalt){
-  if( pPager->otaMode ){
+  if( PagerOtaMode(pPager) ){
     memcpy(aSalt, pPager->dbFileVers, 8);
   }else{
     sqlite3_randomness(8, aSalt);
@@ -7310,6 +7332,7 @@ int sqlite3PagerWalFramesize(Pager *pPager){
 }
 #endif
 
+#ifdef SQLITE_ENABLE_OTA
 /*
 ** Set or clear the "OTA mode" flag.
 */
@@ -7341,5 +7364,6 @@ int sqlite3PagerWalCheckpointStart(
     );
   }
 }
+#endif /* !SQLITE_ENABLE_OTA */
 
 #endif /* SQLITE_OMIT_DISKIO */
index 5b89237014c94e54f3bdd4cf006e24b275fab6b0..140d496abb15c39eabf466cfac363e5f175d65f9 100644 (file)
@@ -310,10 +310,12 @@ static const struct sPragmaNames {
     /* ePragFlag: */ 0,
     /* iArg:      */ 0 },
 #endif
+#if defined(SQLITE_ENABLE_OTA)
   { /* zName:     */ "ota_mode",
     /* ePragTyp:  */ PragTyp_FLAG,
     /* ePragFlag: */ 0,
     /* iArg:      */ SQLITE_OtaMode },
+#endif
 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
   { /* zName:     */ "page_count",
     /* ePragTyp:  */ PragTyp_PAGE_COUNT,
@@ -324,10 +326,12 @@ 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,
@@ -481,7 +485,7 @@ static const struct sPragmaNames {
     /* iArg:      */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
 #endif
 };
-/* Number of pragmas: 59 on by default, 72 total. */
+/* Number of pragmas: 57 on by default, 72 total. */
 /* End of the automatically generated pragma table.
 ***************************************************************************/
 
@@ -896,6 +900,7 @@ void sqlite3Pragma(
   ** 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 );
@@ -916,6 +921,7 @@ void sqlite3Pragma(
     }
     break;
   }
+#endif /* SQLITE_ENABLE_OTA */
 
 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
   /*
index e5e98d2a8add55abd0a2b82cf640327347c9af97..2d8d5fd773fa39d52ba831b120833f1509e21a9f 100644 (file)
@@ -7445,62 +7445,6 @@ int sqlite3_vtab_on_conflict(sqlite3 *);
 /* #define SQLITE_ABORT 4  // Also an error code */
 #define SQLITE_REPLACE  5
 
-/*
-** Allocate a statement handle that may be used to write directly to an
-** index b-tree. This allows the user to create a corrupt database. Once
-** the statement handle is allocated, it may be used with the same APIs
-** as any statement handle created with sqlite3_prepare().
-**
-** The statement writes to the index specified by parameter zIndex, which
-** must be in the "main" database. If argument bDelete is false, then each
-** time the statement is sqlite3_step()ed, an entry is inserted into the
-** b-tree index. If it is true, then an entry may be deleted (or may not, if 
-** the specified key is not found) each time the statement is 
-** sqlite3_step()ed.
-**
-** If statement compilation is successful, *ppStmt is set to point to the 
-** new statement handle and SQLITE_OK is returned. Otherwise, if an error
-** occurs, *ppStmt is set to NULL and an error code returned. An error
-** message may be left in the database handle in this case.
-**
-** If statement compilation succeeds, output variable *pnCol is set to the
-** total number of columns in the index, including the primary key columns
-** at the end. Variable *paiCol is set to point to an array *pnCol entries 
-** in size. Each entry is the table column index, numbered from zero from left 
-** to right, of the corresponding index column. For example, if:
-**
-**       CREATE TABLE t1(a, b, c, d);
-**       CREATE INDEX i1 ON t1(b, c);
-**
-** then *pnCol is 3 and *paiCol points to an array containing {1, 2, -1}.
-** If table t1 had an explicit INTEGER PRIMARY KEY, then the "-1" in the
-** *paiCol array would be replaced by its column index. Or if:
-**
-**       CREATE TABLE t2(a, b, c, d, PRIMARY KEY(d, c)) WITHOUT ROWID;
-**       CREATE INDEX i2 ON t2(a);
-**
-** then (*pnCol) is 3 and *paiCol points to an array containing {0, 3, 2}.
-**
-** The lifetime of the array is the same as that of the statement handle -
-** it is automatically freed when the statement handle is passed to
-** sqlite3_finalize().
-**
-** The statement has (*pnCol) SQL variables that values may be bound to.
-** They correspond to the values used to create the index key that is
-** inserted or deleted when the statement is stepped.
-**
-** If the index is a UNIQUE index, the usual checking and error codes apply
-** to insert operations.
-*/
-int sqlite3_index_writer(
-  sqlite3 *db, 
-  int bDelete,                    /* Zero for insert, non-zero for delete */
-  const char *zIndex,             /* Index to write to */
-  sqlite3_stmt**,                 /* OUT: New statement handle */
-  const char ***pazColl,          /* OUT: Collation sequences for each column */
-  int **paiCol, int *pnCol        /* OUT: See above */
-);
-
 /*
 ** CAPI3REF: Prepared Statement Scan Status Opcodes
 ** KEYWORDS: {scanstatus options}
@@ -7594,6 +7538,66 @@ SQLITE_EXPERIMENTAL int sqlite3_stmt_scanstatus(
 */
 SQLITE_EXPERIMENTAL void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
 
+/*
+** Allocate a statement handle that may be used to write directly to an
+** index b-tree. This allows the user to create a corrupt database. Once
+** the statement handle is allocated, it may be used with the same APIs
+** as any statement handle created with sqlite3_prepare().
+**
+** The statement writes to the index specified by parameter zIndex, which
+** must be in the "main" database. If argument bDelete is false, then each
+** time the statement is sqlite3_step()ed, an entry is inserted into the
+** b-tree index. If it is true, then an entry may be deleted (or may not, if 
+** the specified key is not found) each time the statement is 
+** sqlite3_step()ed.
+**
+** If statement compilation is successful, *ppStmt is set to point to the 
+** new statement handle and SQLITE_OK is returned. Otherwise, if an error
+** occurs, *ppStmt is set to NULL and an error code returned. An error
+** message may be left in the database handle in this case.
+**
+** If statement compilation succeeds, output variable *pnCol is set to the
+** total number of columns in the index, including the primary key columns
+** at the end. Variable *paiCol is set to point to an array *pnCol entries 
+** in size. Each entry is the table column index, numbered from zero from left 
+** to right, of the corresponding index column. For example, if:
+**
+**       CREATE TABLE t1(a, b, c, d);
+**       CREATE INDEX i1 ON t1(b, c);
+**
+** then *pnCol is 3 and *paiCol points to an array containing {1, 2, -1}.
+** If table t1 had an explicit INTEGER PRIMARY KEY, then the "-1" in the
+** *paiCol array would be replaced by its column index. Or if:
+**
+**       CREATE TABLE t2(a, b, c, d, PRIMARY KEY(d, c)) WITHOUT ROWID;
+**       CREATE INDEX i2 ON t2(a);
+**
+** then (*pnCol) is 3 and *paiCol points to an array containing {0, 3, 2}.
+**
+** The lifetime of the array is the same as that of the statement handle -
+** it is automatically freed when the statement handle is passed to
+** sqlite3_finalize().
+**
+** The statement has (*pnCol) SQL variables that values may be bound to.
+** They correspond to the values used to create the index key that is
+** inserted or deleted when the statement is stepped.
+**
+** If the index is a UNIQUE index, the usual checking and error codes apply
+** to insert operations.
+**
+** This API is only available if SQLITE_ENABLE_OTA is defined at compile
+** time. It is intended for use by the OTA extension only. As such, it is 
+** subject to change or removal at any point.
+*/
+int sqlite3_index_writer(
+  sqlite3 *db, 
+  int bDelete,                    /* Zero for insert, non-zero for delete */
+  const char *zIndex,             /* Index to write to */
+  sqlite3_stmt**,                 /* OUT: New statement handle */
+  const char ***pazColl,          /* OUT: Collation sequence for each column */
+  int **paiCol, int *pnCol        /* OUT: See above */
+);
+
 /*
 ** Incremental checkpoint API.
 **
@@ -7622,9 +7626,13 @@ SQLITE_EXPERIMENTAL void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
 ** The contents of this buffer may be passed to a later call to
 ** sqlite3_ckpt_open() to restart the checkpoint. The second output variable 
 ** is set to the size of the buffer in bytes.
+**
+** These APIs are only available if SQLITE_ENABLE_OTA is defined at compile
+** time. They are intended for use by the OTA extension only. As such, they 
+** are subject to change or removal at any point.
 */
 typedef struct sqlite3_ckpt sqlite3_ckpt;
-int sqlite3_ckpt_open(sqlite3*, unsigned char *a, int n, sqlite3_ckpt **ppCkpt);
+int sqlite3_ckpt_open(sqlite3*, unsigned char*, int n, sqlite3_ckpt **ppCkpt);
 int sqlite3_ckpt_step(sqlite3_ckpt*);
 int sqlite3_ckpt_close(sqlite3_ckpt*, unsigned char **pa, int *pn);
 
index 8bc737d199c36ad762a8b7807e42da7387b0d537..b89214354e442f61c76d377d8f075dc464ed9654 100644 (file)
@@ -1196,8 +1196,11 @@ struct sqlite3 {
 #define SQLITE_QueryOnly      0x02000000  /* Disable database changes */
 #define SQLITE_VdbeEQP        0x04000000  /* Debug EXPLAIN QUERY PLAN */
 
-#define SQLITE_OtaMode        0x08000000  /* True in "ota mode" */
-
+#ifdef SQLITE_ENABLE_OTA
+# define SQLITE_OtaMode       0x08000000  /* True in "ota mode" */
+#else
+# define SQLITE_OtaMode       0x00000000
+#endif
 
 /*
 ** Bits of the sqlite3.dbOptFlags field that are used by the
index 834113b33b14beb4dcc4f15ae6c8d3f9acc2abce..93f60838388a5ac27e6486cfa883c3b1aa621f26 100644 (file)
@@ -430,6 +430,12 @@ Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY);
   Tcl_SetVar2(interp, "sqlite_options", "or_opt", "1", TCL_GLOBAL_ONLY);
 #endif
 
+#ifdef SQLITE_ENABLE_OTA
+  Tcl_SetVar2(interp, "sqlite_options", "ota", "1", TCL_GLOBAL_ONLY);
+#else
+  Tcl_SetVar2(interp, "sqlite_options", "ota", "0", TCL_GLOBAL_ONLY);
+#endif
+
 #ifdef SQLITE_OMIT_PAGER_PRAGMAS
   Tcl_SetVar2(interp, "sqlite_options", "pager_pragmas", "0", TCL_GLOBAL_ONLY);
 #else
index f837e23b5ad639852475d2c6c5f99db0c59d457c..44b9b89fcc5a6b9585101721166443e68e607c66 100644 (file)
@@ -50,7 +50,7 @@ void sqlite3DeleteTriggerStep(sqlite3 *db, TriggerStep *pTriggerStep){
 Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){
   Schema * const pTmpSchema = pParse->db->aDb[1].pSchema;
   Trigger *pList = 0;                  /* List of triggers to return */
-  int bOta = !!(pParse->db->flags & SQLITE_OtaMode);
+  const int bOta = !!(pParse->db->flags & SQLITE_OtaMode);
 
   if( pParse->disableTriggers ){
     return 0;
index 8565844f214ddef4d87d432b884e2d13f132e961..e033468e96a79cbfb3306b739f5ba1997ede0ef5 100644 (file)
@@ -467,6 +467,11 @@ int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){
   return rc;
 }
 
+#ifdef SQLITE_ENABLE_OTA
+/*
+** Allocate and populate the output arrays returned by the 
+** sqlite3_index_writer() function.
+*/
 static int indexWriterOutputVars(
   sqlite3 *db,
   Index *pIdx,
@@ -529,7 +534,10 @@ static int indexWriterOutputVars(
   return SQLITE_OK;
 }
 
-
+/*
+** Prepare and return an SQL statement handle that can be used to write
+** directly to an index b-tree.
+*/
 int sqlite3_index_writer(
   sqlite3 *db, 
   int bDelete,
@@ -634,5 +642,6 @@ index_writer_out:
   sqlite3_mutex_leave(db->mutex);
   return rc;
 }
+#endif /* SQLITE_ENABLE_OTA */
 
 #endif /* #ifndef SQLITE_OMIT_INCRBLOB */
index ba86d84b73311afe2bcd7d893eced2b18a4f5ee0..bb8c0f806e0a094ef4f99e0c807c97777c6f9a11 100644 (file)
--- a/src/wal.c
+++ b/src/wal.c
@@ -483,7 +483,14 @@ struct WalIterator {
 };
 
 /*
-** walCheckpoint
+** An object of the following type is used to store state information for
+** an ongoing checkpoint operation. For normal checkpoints, the instance 
+** is allocated on the stack by the walCheckpoint() function. For the special
+** incremental checkpoints performed by OTA clients, it is allocated in
+** heap memory by sqlite3WalCheckpointStart().
+**
+** See the implementations of walCheckpointStart(), walCheckpointStep() and 
+** walCheckpointFinalize() for further details.
 */
 typedef struct WalCkpt WalCkpt;
 struct WalCkpt {
@@ -1642,8 +1649,15 @@ static int walPagesize(Wal *pWal){
   return (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16);
 }
 
+/*
+** Initialize the contents of the WalCkpt object indicated by the final
+** argument and begin a checkpoint operation. The CKPT lock must already
+** be held when this function is called.
+**
+** Return SQLITE_OK if successful or an error code otherwise.
+*/
 static int walCheckpointStart(
-  Wal *pWal, 
+  Wal *pWal,                      /* Wal connection */
   u8 *aBuf,                       /* Page-sized temporary buffer */
   int nBuf,                       /* Size of aBuf[] in bytes */
   int (*xBusy)(void*),            /* Function to call when busy (or NULL) */
@@ -1655,7 +1669,6 @@ static int walCheckpointStart(
   int i;                          /* Iterator variable */
 
   memset(p, 0, sizeof(WalCkpt));
-
   if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
     return SQLITE_CORRUPT_BKPT;
   }
@@ -1729,6 +1742,12 @@ static int walCheckpointStart(
   return rc;
 }
 
+/*
+** Attempt to copy the next frame from the wal file to the database file. If
+** there are no more frames to copy to the database file return SQLITE_DONE.
+** If the frame is successfully copied, return SQLITE_OK. Or, if an error
+** occurs, return an SQLite error code.
+*/
 static int walCheckpointStep(WalCkpt *p){
   u32 iDbpage = 0;                /* Next database page to write */
   u32 iFrame = 0;                 /* Wal frame containing data for iDbpage */
@@ -1760,6 +1779,16 @@ static int walCheckpointStep(WalCkpt *p){
   return rc;
 }
 
+/*
+** The current round of checkpointing work using the object indicated by
+** the only argument is now finished. If no error occcurred, this function
+** saves the results to shared memory (i.e. updates the WalCkptInfo.nBackfill
+** variable), and truncates and syncs the database file as required.
+**
+** All dynamic resources currently held by the WalCkpt object are released. 
+** It is the responsibility of the caller to delete the WalCkpt itself if
+** required.
+*/
 static int walCheckpointFinalize(WalCkpt *p){
   if( p->pIter ){
     int rc = p->rc;
@@ -1780,9 +1809,15 @@ static int walCheckpointFinalize(WalCkpt *p){
         p->pInfo->nBackfill = p->mxSafeFrame;
       }
       p->rc = rc;
-    }else if( rc==SQLITE_OK && p->sync_flags ){
-      /* If work was not completed, but no error has occured. */
-      p->rc = sqlite3OsSync(pWal->pDbFd, p->sync_flags);
+    }else{
+#ifdef SQLITE_ENABLE_OTA
+      if( rc==SQLITE_OK && p->sync_flags ){
+        /* If work was not completed, but no error has occured. */
+        p->rc = sqlite3OsSync(pWal->pDbFd, p->sync_flags);
+      }
+#else
+      assert( rc!=SQLITE_OK );
+#endif
     }
 
     /* Release the reader lock held while backfilling */
@@ -1846,7 +1881,6 @@ static int walCheckpoint(
   /* Step the checkpoint object until it reports something other than 
   ** SQLITE_OK.  */
   while( SQLITE_OK==(rc = walCheckpointStep(&sC)) );
-  if( rc==SQLITE_DONE ) rc = SQLITE_OK;
   rc = walCheckpointFinalize(&sC);
 
   /* If this is an SQLITE_CHECKPOINT_RESTART operation, and the entire wal
@@ -1893,8 +1927,8 @@ static void walLimitSize(Wal *pWal, i64 nMax){
 /*
 ** Close a connection to a log file.
 **
-** If parameter zBuf is not NULL, attempt to obtain an exclusive lock 
-** and run a checkpoint.
+** If parameter zBuf is not NULL, also attempt to obtain an exclusive 
+** lock and run a checkpoint.
 */
 int sqlite3WalClose(
   Wal *pWal,                      /* Wal to close */
@@ -1914,7 +1948,10 @@ int sqlite3WalClose(
     **
     ** The EXCLUSIVE lock is not released before returning.
     */
-    if( zBuf ){
+#ifdef SQLITE_ENABLE_OTA
+    if( zBuf )          /* In non-OTA builds, zBuf is always non-NULL */
+#endif
+    {
       rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE);
       if( rc==SQLITE_OK ){
         if( pWal->exclusiveMode==WAL_NORMAL_MODE ){
@@ -3071,6 +3108,11 @@ int sqlite3WalCheckpoint(
   return (rc==SQLITE_OK && eMode!=eMode2 ? SQLITE_BUSY : rc);
 }
 
+#ifdef SQLITE_ENABLE_OTA
+
+/*
+** Step the checkpoint object passed as the first argument.
+*/
 int sqlite3_ckpt_step(sqlite3_ckpt *pCkpt){
   int rc;
   WalCkpt *p = (WalCkpt*)pCkpt;
@@ -3080,6 +3122,14 @@ int sqlite3_ckpt_step(sqlite3_ckpt *pCkpt){
   return rc;
 }
 
+/*
+** Close the checkpoint object passed as the first argument. If the checkpoint
+** was completed, zero the two output variables. Otherwise, set *paState to
+** point to a buffer containing data that may be passed to a subsequent 
+** call to ckpt_open() to resume the checkpoint. In this case *pnState is
+** set to the size of the buffer in bytes. The buffer should be eventually
+** freed by the caller using sqlite3_free().
+*/
 int sqlite3_ckpt_close(sqlite3_ckpt *pCkpt, u8 **paState, int *pnState){
   int rc;
   WalCkpt *p = (WalCkpt*)pCkpt;
@@ -3192,6 +3242,25 @@ int sqlite3WalCheckpointStart(
   return rc;
 }
 
+/*
+** Unless the wal file is empty, check that the 8 bytes of salt stored in
+** the wal header are identical to those in the buffer indicated by the
+** second argument. If they are not, return SQLITE_BUSY_SNAPSHOT. Otherwise,
+** if the buffers match or the WAL file is empty, return SQLITE_OK.
+*/
+int sqlite3WalCheckSalt(Wal *pWal, sqlite3_file *pFd){
+  int rc = SQLITE_OK;
+  if( pWal->hdr.mxFrame>0 ){
+    u8 aData[16];
+    rc = sqlite3OsRead(pFd, aData, sizeof(aData), 24);
+    if( rc==SQLITE_OK && memcmp(pWal->hdr.aSalt, aData, 8) ){
+      rc = SQLITE_BUSY_SNAPSHOT;
+    }
+  }
+  return rc;
+}
+#endif /* SQLITE_ENABLE_OTA */
+
 /* Return the value to pass to a sqlite3_wal_hook callback, the
 ** number of frames in the WAL at the point of the last commit since
 ** sqlite3WalCallback() was called.  If no commits have occurred since
@@ -3276,24 +3345,6 @@ int sqlite3WalHeapMemory(Wal *pWal){
   return (pWal && pWal->exclusiveMode==WAL_HEAPMEMORY_MODE );
 }
 
-/*
-** Unless the wal file is empty, check that the 8 bytes of salt stored in
-** the wal header are identical to those in the buffer indicated by the
-** second argument. If they are not, return SQLITE_BUSY_SNAPSHOT. Otherwise,
-** if the buffers match or the WAL file is empty, return SQLITE_OK.
-*/
-int sqlite3WalCheckSalt(Wal *pWal, sqlite3_file *pFd){
-  int rc = SQLITE_OK;
-  if( pWal->hdr.mxFrame>0 ){
-    u8 aData[16];
-    rc = sqlite3OsRead(pFd, aData, sizeof(aData), 24);
-    if( rc==SQLITE_OK && memcmp(pWal->hdr.aSalt, aData, 8) ){
-      rc = SQLITE_BUSY_SNAPSHOT;
-    }
-  }
-  return rc;
-}
-
 #ifdef SQLITE_ENABLE_ZIPVFS
 /*
 ** If the argument is not NULL, it points to a Wal object that holds a
index 676666d91f4ca2bd32174e188c97494e5f727a05..9dc01c2b3a7b87043151cdfd021a9f3d882a02b2 100644 (file)
@@ -11,6 +11,8 @@
 set testdir [file dirname $argv0]
 source $testdir/permutations.test
 
-run_test_suite ota
+ifcapable !ota { finish_test ; return }
 
+run_test_suite ota
 finish_test
+
index 613b565553707e0a3993d5310eb5f930748e66a3..3c36a6c0117c3201123781af5f5c3c8f945668c8 100644 (file)
@@ -298,10 +298,12 @@ set pragma_def {
   NAME: threads
 
   NAME: pager_ota_mode
+  IF:   defined(SQLITE_ENABLE_OTA)
 
   NAME: ota_mode
   TYPE: FLAG
   ARG:  SQLITE_OtaMode
+  IF:   defined(SQLITE_ENABLE_OTA)
 }
 fconfigure stdout -translation lf
 set name {}