/ Check-in [48d201cd]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Remove the experimental sqlite3_transaction_save() and restore() APIs.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | ota-update
Files: files | file ages | folders
SHA1: 48d201cd8b68c0377cf8a2cc6439b893f9462fe2
User & Date: dan 2014-09-15 19:34:04
Context
2014-09-16
20:02
Clarify the effects of the pager_ota_mode pragma. Add tests and fixes for the same. check-in: decaccc3 user: dan tags: ota-update
2014-09-15
19:34
Remove the experimental sqlite3_transaction_save() and restore() APIs. check-in: 48d201cd user: dan tags: ota-update
16:57
Merge latest trunk fixes into this branch. check-in: 5efafef5 user: dan tags: ota-update
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/ota/ota1.test.

   215    215       }
   216    216       3 {
   217    217         CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
   218    218         CREATE INDEX i1 ON t1(b);
   219    219         CREATE INDEX i2 ON t1(c, b);
   220    220         CREATE INDEX i3 ON t1(c, b, c);
   221    221       }
          222  +    4 {
          223  +      CREATE TABLE t1(a INT PRIMARY KEY, b, c) WITHOUT ROWID;
          224  +      CREATE INDEX i1 ON t1(b);
          225  +      CREATE INDEX i2 ON t1(c, b);
          226  +      CREATE INDEX i3 ON t1(c, b, c);
          227  +    }
   222    228     } {
   223    229       reset_db
   224    230       execsql $schema
   225    231       execsql {
   226    232         INSERT INTO t1 VALUES(2, 'hello', 'world');
   227    233         INSERT INTO t1 VALUES(4, 'hello', 'planet');
   228    234         INSERT INTO t1 VALUES(6, 'hello', 'xyz');
................................................................................
   251    257     foreach {tn schema} {
   252    258       1 {
   253    259         CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d);
   254    260       }
   255    261       2 {
   256    262         CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d);
   257    263         CREATE INDEX i1 ON t1(d);
          264  +      CREATE INDEX i2 ON t1(d, c);
          265  +      CREATE INDEX i3 ON t1(d, c, b);
          266  +      CREATE INDEX i4 ON t1(b);
          267  +      CREATE INDEX i5 ON t1(c);
          268  +      CREATE INDEX i6 ON t1(c, b);
          269  +    }
          270  +    3 {
          271  +      CREATE TABLE t1(a PRIMARY KEY, b, c, d) WITHOUT ROWID;
          272  +      CREATE INDEX i1 ON t1(d);
   258    273         CREATE INDEX i2 ON t1(d, c);
   259    274         CREATE INDEX i3 ON t1(d, c, b);
   260    275         CREATE INDEX i4 ON t1(b);
   261    276         CREATE INDEX i5 ON t1(c);
   262    277         CREATE INDEX i6 ON t1(c, b);
   263    278       }
   264    279     } {

Changes to src/main.c.

  3469   3469   ** Return 1 if database is read-only or 0 if read/write.  Return -1 if
  3470   3470   ** no such database exists.
  3471   3471   */
  3472   3472   int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){
  3473   3473     Btree *pBt = sqlite3DbNameToBtree(db, zDbName);
  3474   3474     return pBt ? sqlite3BtreeIsReadonly(pBt) : -1;
  3475   3475   }
  3476         -
  3477         -int sqlite3_transaction_save(sqlite3 *db, void **ppState, int *pnState){
  3478         -  Pager *pPager = sqlite3BtreePager(db->aDb[0].pBt);
  3479         -  return sqlite3PagerSaveState(pPager, ppState, pnState);
  3480         -}
  3481         -
  3482         -int sqlite3_transaction_restore(sqlite3 *db, const void *pState, int nState){
  3483         -  Pager *pPager = sqlite3BtreePager(db->aDb[0].pBt);
  3484         -  return sqlite3PagerRestoreState(pPager, pState, nState);
  3485         -}
  3486         -
  3487         -

Changes to src/pager.c.

  7230   7230       if( rc==SQLITE_OK ){
  7231   7231         rc = sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags,
  7232   7232                              pPager->pageSize, (u8*)pPager->pTmpSpace);
  7233   7233         pPager->pWal = 0;
  7234   7234         pagerFixMaplimit(pPager);
  7235   7235       }
  7236   7236     }
  7237         -  return rc;
  7238         -}
  7239         -
  7240         -int sqlite3PagerSaveState(Pager *pPager, void **ppState, int *pnState){
  7241         -  int rc = SQLITE_OK;
  7242         -  *ppState = 0;
  7243         -  *pnState = 0;
  7244         -  if( pPager->pWal==0 || pPager->eState<PAGER_WRITER_LOCKED ){
  7245         -    rc = SQLITE_ERROR;
  7246         -  }else{
  7247         -    /* Flush all dirty pages to the wal. */
  7248         -    PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache);
  7249         -    rc = sqlite3WalFrames(pPager->pWal, 
  7250         -        pPager->pageSize, pList, 0, 0, pPager->walSyncFlags
  7251         -    );
  7252         -    if( rc==SQLITE_OK ){
  7253         -      rc = sqlite3WalSaveState(pPager->pWal, ppState, pnState);
  7254         -    }
  7255         -  }
  7256         -  return rc;
  7257         -}
  7258         -
  7259         -int sqlite3PagerRestoreState(Pager *pPager, const void *pState, int nState){
  7260         -  int rc = SQLITE_OK;
  7261         -  if( pPager->pWal==0 
  7262         -   || pPager->eState<PAGER_WRITER_LOCKED 
  7263         -   || sqlite3PcacheDirtyList(pPager->pPCache)
  7264         -  ){
  7265         -    rc = SQLITE_ERROR;
  7266         -  }else{
  7267         -    sqlite3PcacheTruncate(pPager->pPCache, 1);
  7268         -    rc = sqlite3WalRestoreState(pPager->pWal, pState, nState);
  7269         -    pPager->eState = PAGER_WRITER_CACHEMOD;
  7270         -  }
  7271         -
  7272   7237     return rc;
  7273   7238   }
  7274   7239   
  7275   7240   #endif /* !SQLITE_OMIT_WAL */
  7276   7241   
  7277   7242   #ifdef SQLITE_ENABLE_ZIPVFS
  7278   7243   /*

Changes to src/pager.h.

   203    203     void disable_simulated_io_errors(void);
   204    204     void enable_simulated_io_errors(void);
   205    205   #else
   206    206   # define disable_simulated_io_errors()
   207    207   # define enable_simulated_io_errors()
   208    208   #endif
   209    209   
   210         -int sqlite3PagerSaveState(Pager *pPager, void **ppState, int *pnState);
   211         -int sqlite3PagerRestoreState(Pager *pPager, const void *pState, int nState);
   212         -
   213    210   int sqlite3PagerSetOtaMode(Pager *pPager, int bOta);
   214    211   
   215    212   #endif /* _PAGER_H_ */

Changes to src/pragma.c.

   478    478     { /* zName:     */ "writable_schema",
   479    479       /* ePragTyp:  */ PragTyp_FLAG,
   480    480       /* ePragFlag: */ 0,
   481    481       /* iArg:      */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
   482    482   #endif
   483    483   };
   484    484   /* Number of pragmas: 59 on by default, 72 total. */
   485         -/* Number of pragmas: 58 on by default, 71 total. */
   486    485   /* End of the automatically generated pragma table.
   487    486   ***************************************************************************/
   488    487   
   489    488   /*
   490    489   ** Interpret the given string as a safety level.  Return 0 for OFF,
   491    490   ** 1 for ON or NORMAL and 2 for FULL.  Return 1 for an empty or 
   492    491   ** unrecognized string argument.  The FULL option is disallowed

Changes to src/prepare.c.

   792    792     const char **pzTail       /* OUT: End of parsed string */
   793    793   ){
   794    794     int rc;
   795    795     rc = sqlite3LockAndPrepare(db,zSql,nBytes,1,0,ppStmt,pzTail);
   796    796     assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 );  /* VERIFY: F13021 */
   797    797     return rc;
   798    798   }
          799  +
   799    800   
   800    801   #ifndef SQLITE_OMIT_UTF16
   801    802   /*
   802    803   ** Compile the UTF-16 encoded SQL statement zSql into a statement handle.
   803    804   */
   804    805   static int sqlite3Prepare16(
   805    806     sqlite3 *db,              /* Database handle. */ 

Changes to src/sqlite.h.in.

  7460   7460     int bDelete,                    /* Zero for insert, non-zero for delete */
  7461   7461     const char *zIndex,             /* Index to write to */
  7462   7462     sqlite3_stmt**,                 /* OUT: New statement handle */
  7463   7463     const char ***pazColl,          /* OUT: Collation sequences for each column */
  7464   7464     int **paiCol, int *pnCol        /* OUT: See above */
  7465   7465   );
  7466   7466   
  7467         -/*
  7468         -** This function is used to save the state of an ongoing WAL mode write 
  7469         -** transaction on the "main" database of the supplied database handle.
  7470         -**
  7471         -** If successful, SQLITE_OK is returned and output variable (*ppState)
  7472         -** is set to point to a buffer containing the transaction state data. 
  7473         -** (*pnState) is set to the size of that buffer in bytes. Otherwise, if
  7474         -** an error occurs, an SQLite error code is returned and both output
  7475         -** variables are zeroed.
  7476         -**
  7477         -** A transaction state may be saved if: 
  7478         -**
  7479         -**   * the transaction does not contain any schema modifications.
  7480         -**   * there are no open sub-transactions.
  7481         -*/
  7482         -int sqlite3_transaction_save(sqlite3 *db, void **ppState, int *pnState);
  7483         -
  7484         -int sqlite3_transaction_restore(sqlite3 *db, const void *pState, int nState);
  7485         -
  7486   7467   /*
  7487   7468   ** Undo the hack that converts floating point types to integer for
  7488   7469   ** builds on processors without floating point support.
  7489   7470   */
  7490   7471   #ifdef SQLITE_OMIT_FLOATING_POINT
  7491   7472   # undef double
  7492   7473   #endif
  7493   7474   
  7494   7475   #ifdef __cplusplus
  7495   7476   }  /* End of the 'extern "C"' block */
  7496   7477   #endif
  7497   7478   #endif /* _SQLITE3_H_ */

Changes to src/test1.c.

  6493   6493     return TCL_OK;
  6494   6494    sql_error:
  6495   6495     Tcl_AppendResult(interp, "sql error: ", sqlite3_errmsg(db), 0);
  6496   6496     return TCL_ERROR;
  6497   6497   }
  6498   6498   
  6499   6499   
  6500         -/*
  6501         -** tclcmd: sqlite3_transaction_save DB
  6502         -*/
  6503         -static int testTransactionSave(
  6504         -  void * clientData,
  6505         -  Tcl_Interp *interp,
  6506         -  int objc,
  6507         -  Tcl_Obj *CONST objv[]
  6508         -){
  6509         -  void *pState;
  6510         -  int nState;
  6511         -  sqlite3 *db;
  6512         -  int rc;
  6513         -
  6514         -  if( objc!=2 ){
  6515         -    Tcl_WrongNumArgs(interp, 1, objv, "DB");
  6516         -    return TCL_ERROR;
  6517         -  }
  6518         -  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
  6519         -
  6520         -  rc = sqlite3_transaction_save(db, &pState, &nState);
  6521         -  if( rc==SQLITE_OK ){
  6522         -    Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pState, nState));
  6523         -  }else{
  6524         -    Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
  6525         -    return TCL_ERROR;
  6526         -  }
  6527         -
  6528         -  sqlite3_free(pState);
  6529         -  return TCL_OK;
  6530         -}
  6531         -
  6532         -/*
  6533         -** tclcmd: sqlite3_transaction_restore DB BLOB
  6534         -*/
  6535         -static int testTransactionRestore(
  6536         -  void * clientData,
  6537         -  Tcl_Interp *interp,
  6538         -  int objc,
  6539         -  Tcl_Obj *CONST objv[]
  6540         -){
  6541         -  void *pState;
  6542         -  int nState;
  6543         -  sqlite3 *db;
  6544         -  int rc;
  6545         -
  6546         -  if( objc!=3 ){
  6547         -    Tcl_WrongNumArgs(interp, 1, objv, "DB BLOB");
  6548         -    return TCL_ERROR;
  6549         -  }
  6550         -  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
  6551         -  pState = (void*)Tcl_GetByteArrayFromObj(objv[2], &nState);
  6552         -
  6553         -  rc = sqlite3_transaction_restore(db, pState, nState);
  6554         -  if( rc==SQLITE_OK ){
  6555         -    Tcl_ResetResult(interp);
  6556         -  }else{
  6557         -    Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
  6558         -    return TCL_ERROR;
  6559         -  }
  6560         -
  6561         -  return TCL_OK;
  6562         -}
  6563         -
  6564   6500   #ifdef SQLITE_USER_AUTHENTICATION
  6565   6501   #include "sqlite3userauth.h"
  6566   6502   /*
  6567   6503   ** tclcmd:  sqlite3_user_authenticate DB USERNAME PASSWORD
  6568   6504   */
  6569   6505   static int test_user_authenticate(
  6570   6506     ClientData clientData, /* Unused */
................................................................................
  6920   6856        { "sqlite3_test_control", test_test_control },
  6921   6857   #if SQLITE_OS_UNIX
  6922   6858        { "getrusage", test_getrusage },
  6923   6859   #endif
  6924   6860        { "load_static_extension", tclLoadStaticExtensionCmd },
  6925   6861        { "sorter_test_fakeheap", sorter_test_fakeheap },
  6926   6862        { "sorter_test_sort4_helper", sorter_test_sort4_helper },
  6927         -     { "sqlite3_transaction_save",    testTransactionSave },
  6928         -     { "sqlite3_transaction_restore", testTransactionRestore },
  6929   6863   #ifdef SQLITE_USER_AUTHENTICATION
  6930   6864        { "sqlite3_user_authenticate", test_user_authenticate, 0 },
  6931   6865        { "sqlite3_user_add",          test_user_add,          0 },
  6932   6866        { "sqlite3_user_change",       test_user_change,       0 },
  6933   6867        { "sqlite3_user_delete",       test_user_delete,       0 },
  6934   6868   #endif
  6935   6869     };

Changes to src/wal.c.

  1042   1042   #endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
  1043   1043     }
  1044   1044   
  1045   1045   
  1046   1046     return rc;
  1047   1047   }
  1048   1048   
  1049         -static int walFileReadHdr(Wal *pWal, int *pbValid){
  1050         -  u8 aBuf[WAL_HDRSIZE];           /* Buffer to load WAL header into */
  1051         -  int rc;                         /* Return code */
  1052         -  u32 magic;                      /* Magic value read from WAL header */
  1053         -  int szPage;                     /* Page size according to the log */
  1054         -  u32 version;                    /* Magic value read from WAL header */
  1055         -
  1056         -  *pbValid = 0;
  1057         -
  1058         -  /* Read in the WAL header. */
  1059         -  rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0);
  1060         -  if( rc!=SQLITE_OK ){
  1061         -    return rc;
  1062         -  }
  1063         -
  1064         -  /* If the database page size is not a power of two, or is greater than
  1065         -  ** SQLITE_MAX_PAGE_SIZE, conclude that the WAL file contains no valid 
  1066         -  ** data. Similarly, if the 'magic' value is invalid, ignore the whole
  1067         -  ** WAL file.
  1068         -  */
  1069         -  magic = sqlite3Get4byte(&aBuf[0]);
  1070         -  szPage = sqlite3Get4byte(&aBuf[8]);
  1071         -  if( (magic&0xFFFFFFFE)!=WAL_MAGIC 
  1072         -      || szPage&(szPage-1) 
  1073         -      || szPage>SQLITE_MAX_PAGE_SIZE 
  1074         -      || szPage<512 
  1075         -  ){
  1076         -    return SQLITE_OK;
  1077         -  }
  1078         -
  1079         -  pWal->hdr.bigEndCksum = (u8)(magic&0x00000001);
  1080         -  pWal->szPage = szPage;
  1081         -  pWal->nCkpt = sqlite3Get4byte(&aBuf[12]);
  1082         -  memcpy(&pWal->hdr.aSalt, &aBuf[16], 8);
  1083         -
  1084         -  /* Verify that the WAL header checksum is correct */
  1085         -  walChecksumBytes(pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN, 
  1086         -      aBuf, WAL_HDRSIZE-2*4, 0, pWal->hdr.aFrameCksum
  1087         -  );
  1088         -  if( pWal->hdr.aFrameCksum[0]!=sqlite3Get4byte(&aBuf[24])
  1089         -      || pWal->hdr.aFrameCksum[1]!=sqlite3Get4byte(&aBuf[28])
  1090         -  ){
  1091         -    return SQLITE_OK;
  1092         -  }
  1093         -
  1094         -  /* Verify that the version number on the WAL format is one that
  1095         -  ** are able to understand */
  1096         -  version = sqlite3Get4byte(&aBuf[4]);
  1097         -  if( version!=WAL_MAX_VERSION ){
  1098         -    return SQLITE_CANTOPEN_BKPT;
  1099         -  }
  1100         -
  1101         -  *pbValid = 1;
  1102         -  return SQLITE_OK;
  1103         -}
  1104         -
  1105   1049   
  1106   1050   /*
  1107   1051   ** Recover the wal-index by reading the write-ahead log file. 
  1108   1052   **
  1109   1053   ** This routine first tries to establish an exclusive lock on the
  1110   1054   ** wal-index to prevent other threads/processes from doing anything
  1111   1055   ** with the WAL or wal-index while recovery is running.  The
................................................................................
  1142   1086   
  1143   1087     rc = sqlite3OsFileSize(pWal->pWalFd, &nSize);
  1144   1088     if( rc!=SQLITE_OK ){
  1145   1089       goto recovery_error;
  1146   1090     }
  1147   1091   
  1148   1092     if( nSize>WAL_HDRSIZE ){
         1093  +    u8 aBuf[WAL_HDRSIZE];         /* Buffer to load WAL header into */
  1149   1094       u8 *aFrame = 0;               /* Malloc'd buffer to load entire frame */
  1150   1095       int szFrame;                  /* Number of bytes in buffer aFrame[] */
  1151   1096       u8 *aData;                    /* Pointer to data part of aFrame buffer */
  1152   1097       int iFrame;                   /* Index of last frame read */
  1153   1098       i64 iOffset;                  /* Next offset to read from log file */
  1154   1099       int szPage;                   /* Page size according to the log */
         1100  +    u32 magic;                    /* Magic value read from WAL header */
         1101  +    u32 version;                  /* Magic value read from WAL header */
  1155   1102       int isValid;                  /* True if this frame is valid */
  1156   1103   
  1157         -    rc = walFileReadHdr(pWal, &isValid);
  1158         -    if( rc!=SQLITE_OK ) goto recovery_error;
  1159         -    if( isValid==0 ) goto finished;
  1160         -    szPage = pWal->szPage;
         1104  +    /* Read in the WAL header. */
         1105  +    rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0);
         1106  +    if( rc!=SQLITE_OK ){
         1107  +      goto recovery_error;
         1108  +    }
         1109  +
         1110  +    /* If the database page size is not a power of two, or is greater than
         1111  +    ** SQLITE_MAX_PAGE_SIZE, conclude that the WAL file contains no valid 
         1112  +    ** data. Similarly, if the 'magic' value is invalid, ignore the whole
         1113  +    ** WAL file.
         1114  +    */
         1115  +    magic = sqlite3Get4byte(&aBuf[0]);
         1116  +    szPage = sqlite3Get4byte(&aBuf[8]);
         1117  +    if( (magic&0xFFFFFFFE)!=WAL_MAGIC 
         1118  +     || szPage&(szPage-1) 
         1119  +     || szPage>SQLITE_MAX_PAGE_SIZE 
         1120  +     || szPage<512 
         1121  +    ){
         1122  +      goto finished;
         1123  +    }
         1124  +    pWal->hdr.bigEndCksum = (u8)(magic&0x00000001);
         1125  +    pWal->szPage = szPage;
         1126  +    pWal->nCkpt = sqlite3Get4byte(&aBuf[12]);
         1127  +    memcpy(&pWal->hdr.aSalt, &aBuf[16], 8);
         1128  +
         1129  +    /* Verify that the WAL header checksum is correct */
         1130  +    walChecksumBytes(pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN, 
         1131  +        aBuf, WAL_HDRSIZE-2*4, 0, pWal->hdr.aFrameCksum
         1132  +    );
         1133  +    if( pWal->hdr.aFrameCksum[0]!=sqlite3Get4byte(&aBuf[24])
         1134  +     || pWal->hdr.aFrameCksum[1]!=sqlite3Get4byte(&aBuf[28])
         1135  +    ){
         1136  +      goto finished;
         1137  +    }
         1138  +
         1139  +    /* Verify that the version number on the WAL format is one that
         1140  +    ** are able to understand */
         1141  +    version = sqlite3Get4byte(&aBuf[4]);
         1142  +    if( version!=WAL_MAX_VERSION ){
         1143  +      rc = SQLITE_CANTOPEN_BKPT;
         1144  +      goto finished;
         1145  +    }
  1161   1146   
  1162   1147       /* Malloc a buffer to read frames into. */
  1163   1148       szFrame = szPage + WAL_FRAME_HDRSIZE;
  1164   1149       aFrame = (u8 *)sqlite3_malloc(szFrame);
  1165   1150       if( !aFrame ){
  1166   1151         rc = SQLITE_NOMEM;
  1167   1152         goto recovery_error;
................................................................................
  1829   1814     if( rx ){
  1830   1815       sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName);
  1831   1816     }
  1832   1817   }
  1833   1818   
  1834   1819   /*
  1835   1820   ** Close a connection to a log file.
         1821  +**
         1822  +** If parameter zBuf is not NULL, attempt to obtain an exclusive lock 
         1823  +** and run a checkpoint.
  1836   1824   */
  1837   1825   int sqlite3WalClose(
  1838   1826     Wal *pWal,                      /* Wal to close */
  1839   1827     int sync_flags,                 /* Flags to pass to OsSync() (or 0) */
  1840   1828     int nBuf,
  1841   1829     u8 *zBuf                        /* Buffer of at least nBuf bytes */
  1842   1830   ){
................................................................................
  3092   3080   ** heap-memory for the wal-index. Otherwise, if the argument is NULL or the
  3093   3081   ** WAL module is using shared-memory, return false. 
  3094   3082   */
  3095   3083   int sqlite3WalHeapMemory(Wal *pWal){
  3096   3084     return (pWal && pWal->exclusiveMode==WAL_HEAPMEMORY_MODE );
  3097   3085   }
  3098   3086   
  3099         -/*
  3100         -** Save current transaction state.
  3101         -**
  3102         -** The transaction state consists of a series of 32-bit big-endian integers:
  3103         -**
  3104         -**     * initial number of frames in WAL file.
  3105         -**     * initial checksum values (2 integers).
  3106         -**     * current number of frames.
  3107         -**     * current checksum values (2 integers).
  3108         -*/
  3109         -int sqlite3WalSaveState(Wal *pWal, void **ppState, int *pnState){
  3110         -  int rc = SQLITE_OK;
  3111         -
  3112         -  *ppState = 0;
  3113         -  *pnState = 0;
  3114         -  if( pWal->writeLock==0 ){
  3115         -    /* Must be in a write transaction to call this function. */
  3116         -    rc = SQLITE_ERROR;
  3117         -  }else{
  3118         -    WalIndexHdr *pOrig = (WalIndexHdr*)walIndexHdr(pWal);
  3119         -    int nBuf = 6 * 4;             /* Bytes of space to allocate */
  3120         -    u8 *aBuf;
  3121         -
  3122         -    aBuf = sqlite3_malloc(nBuf);
  3123         -    if( aBuf==0 ){
  3124         -      rc = SQLITE_NOMEM;
  3125         -    }else{
  3126         -      sqlite3Put4byte(&aBuf[0], pOrig->mxFrame);
  3127         -      sqlite3Put4byte(&aBuf[4], pOrig->aFrameCksum[0]);
  3128         -      sqlite3Put4byte(&aBuf[8], pOrig->aFrameCksum[1]);
  3129         -      sqlite3Put4byte(&aBuf[12], pWal->hdr.mxFrame);
  3130         -      sqlite3Put4byte(&aBuf[16], pWal->hdr.aFrameCksum[0]);
  3131         -      sqlite3Put4byte(&aBuf[20], pWal->hdr.aFrameCksum[1]);
  3132         -      *ppState = (void*)aBuf;
  3133         -      *pnState = nBuf;
  3134         -    }
  3135         -  }
  3136         -
  3137         -  return rc;
  3138         -}
  3139         -
  3140         -static int walUndoNoop(void *pUndoCtx, Pgno pgno){
  3141         -  UNUSED_PARAMETER(pUndoCtx);
  3142         -  UNUSED_PARAMETER(pgno);
  3143         -  return SQLITE_OK;
  3144         -}
  3145         -
  3146         -/*
  3147         -** If possible, restore the state of the curent transaction to that 
  3148         -** described by the second and third arguments.
  3149         -*/
  3150         -int sqlite3WalRestoreState(Wal *pWal, const void *pState, int nState){
  3151         -  int rc = SQLITE_OK;
  3152         -
  3153         -  if( pWal->writeLock==0 ){
  3154         -    /* Must have opened a write transaction to call this */
  3155         -    rc = SQLITE_ERROR;
  3156         -  }else{
  3157         -    u8 *aBuf = (u8*)pState;
  3158         -    int szFrame;                    /* Size of each frame in WAL file */
  3159         -    u8 *aFrame = 0;                 /* Buffer to read data into */
  3160         -    u8 *aData;                      /* Data part of aFrame[] buffer */
  3161         -    u32 mxFrame;                    /* Maximum frame following restoration */
  3162         -    int i;                          /* Iterator variable */
  3163         -
  3164         -    WalIndexHdr *pOrig = (WalIndexHdr*)walIndexHdr(pWal);
  3165         -
  3166         -    /* Check that no dirty pages have been written to the WAL file since
  3167         -    ** the current transaction was opened.  */
  3168         -    if( pOrig->mxFrame!=pWal->hdr.mxFrame 
  3169         -     || pOrig->aFrameCksum[0]!=pWal->hdr.aFrameCksum[0] 
  3170         -     || pOrig->aFrameCksum[1]!=pWal->hdr.aFrameCksum[1] 
  3171         -    ){
  3172         -      rc = SQLITE_ERROR;
  3173         -    }
  3174         -
  3175         -    /* Check that the WAL file is in the same state that it was when the
  3176         -    ** transaction was saved. If not, return SQLITE_MISMATCH - cannot 
  3177         -    ** resume this transaction  */
  3178         -    if( rc==SQLITE_OK && (
  3179         -          pWal->hdr.mxFrame!=sqlite3Get4byte(&aBuf[0])
  3180         -       || pWal->hdr.aFrameCksum[0]!=sqlite3Get4byte(&aBuf[4])
  3181         -       || pWal->hdr.aFrameCksum[1]!=sqlite3Get4byte(&aBuf[8])
  3182         -    )){
  3183         -      rc = SQLITE_MISMATCH;
  3184         -    }
  3185         -
  3186         -    if( rc==SQLITE_OK && pWal->readLock==0 ){
  3187         -      int cnt = 0;
  3188         -      walUnlockShared(pWal, WAL_READ_LOCK(0));
  3189         -      pWal->readLock = -1;
  3190         -      do{
  3191         -        int notUsed;
  3192         -        rc = walTryBeginRead(pWal, &notUsed, 1, ++cnt);
  3193         -      }while( rc==WAL_RETRY );
  3194         -      
  3195         -      if( rc==SQLITE_OK ){
  3196         -        int bValid;
  3197         -        rc = walFileReadHdr(pWal, &bValid);
  3198         -        if( rc==SQLITE_OK && bValid==0 ) rc = SQLITE_MISMATCH;
  3199         -        pWal->hdr.szPage = (u16)((pWal->szPage&0xff00) | (pWal->szPage>>16));
  3200         -      }
  3201         -    }
  3202         -
  3203         -    /* Malloc a buffer to read frames into. */
  3204         -    if( rc==SQLITE_OK ){
  3205         -      szFrame = pWal->szPage + WAL_FRAME_HDRSIZE;
  3206         -      aFrame = (u8*)sqlite3_malloc(szFrame);
  3207         -      if( !aFrame ){
  3208         -        rc = SQLITE_NOMEM;
  3209         -      }else{
  3210         -        aData = &aFrame[WAL_FRAME_HDRSIZE];
  3211         -      }
  3212         -    }
  3213         -
  3214         -    mxFrame = sqlite3Get4byte(&aBuf[12]);
  3215         -    for(i=pWal->hdr.mxFrame+1; rc==SQLITE_OK && i<=mxFrame; i++){
  3216         -      sqlite3_int64 iOff = walFrameOffset(i, pWal->szPage);
  3217         -      rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOff);
  3218         -      if( rc==SQLITE_OK ){
  3219         -        u32 iPg;
  3220         -        u32 dummy;
  3221         -        if( 0==walDecodeFrame(pWal, &iPg, &dummy, aData, aFrame) ){
  3222         -          rc = SQLITE_MISMATCH;
  3223         -        }else{
  3224         -          rc = walIndexAppend(pWal, i, iPg);
  3225         -          if( iPg>pWal->hdr.nPage ) pWal->hdr.nPage = iPg;
  3226         -        }
  3227         -        pWal->hdr.mxFrame = i;
  3228         -      }
  3229         -    }
  3230         -    sqlite3_free(aFrame);
  3231         -
  3232         -    if( rc==SQLITE_OK ){
  3233         -      assert( pWal->hdr.mxFrame==mxFrame );
  3234         -      if( pWal->hdr.aFrameCksum[0]!=sqlite3Get4byte(&aBuf[16])
  3235         -       || pWal->hdr.aFrameCksum[1]!=sqlite3Get4byte(&aBuf[20])
  3236         -      ){
  3237         -        rc = SQLITE_MISMATCH;
  3238         -      }
  3239         -    }
  3240         -
  3241         -
  3242         -    if( rc!=SQLITE_OK ){
  3243         -      sqlite3WalUndo(pWal, walUndoNoop, 0);
  3244         -    }
  3245         -  }
  3246         -
  3247         -  return rc;
  3248         -}
  3249         -
  3250   3087   #ifdef SQLITE_ENABLE_ZIPVFS
  3251   3088   /*
  3252   3089   ** If the argument is not NULL, it points to a Wal object that holds a
  3253   3090   ** read-lock. This function returns the database page-size if it is known,
  3254   3091   ** or zero if it is not (or if pWal is NULL).
  3255   3092   */
  3256   3093   int sqlite3WalFramesize(Wal *pWal){
  3257   3094     assert( pWal==0 || pWal->readLock>=0 );
  3258   3095     return (pWal ? pWal->szPage : 0);
  3259   3096   }
  3260   3097   #endif
  3261   3098   
  3262   3099   #endif /* #ifndef SQLITE_OMIT_WAL */

Changes to src/wal.h.

   122    122   
   123    123   /* Return true if the argument is non-NULL and the WAL module is using
   124    124   ** heap-memory for the wal-index. Otherwise, if the argument is NULL or the
   125    125   ** WAL module is using shared-memory, return false. 
   126    126   */
   127    127   int sqlite3WalHeapMemory(Wal *pWal);
   128    128   
   129         -int sqlite3WalSaveState(Wal *pWal, void **ppState, int *pnState);
   130         -int sqlite3WalRestoreState(Wal *pWal, const void *pState, int nState);
   131         -
   132    129   #ifdef SQLITE_ENABLE_ZIPVFS
   133    130   /* If the WAL file is not empty, return the number of bytes of content
   134    131   ** stored in each frame (i.e. the db page-size when the WAL was created).
   135    132   */
   136    133   int sqlite3WalFramesize(Wal *pWal);
   137    134   #endif
   138    135   
   139    136   #endif /* ifndef SQLITE_OMIT_WAL */
   140    137   #endif /* _WAL_H_ */