Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add untested implementations of experimental APIs sqlite3_snapshot_get(), _open() and _free(). |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | snapshot-get |
Files: | files | file ages | folders |
SHA1: |
0715eb00aa8891400cd50a15509d3d7b |
User & Date: | dan 2015-12-05 20:51:54 |
Context
2015-12-07
| ||
14:33 | Add tests for snapshot_get(), _open() and _free(). check-in: 502cc6f3 user: dan tags: snapshot-get | |
2015-12-05
| ||
20:51 | Add untested implementations of experimental APIs sqlite3_snapshot_get(), _open() and _free(). check-in: 0715eb00 user: dan tags: snapshot-get | |
2015-12-04
| ||
13:44 | Remove the dependence on "exec ls -U" from the vtabH.test module, as the -U option to "ls" is not universally available. check-in: 4ecbc75b user: drh tags: trunk | |
Changes
Changes to src/main.c.
3862 3862 (void)SQLITE_MISUSE_BKPT; 3863 3863 return -1; 3864 3864 } 3865 3865 #endif 3866 3866 pBt = sqlite3DbNameToBtree(db, zDbName); 3867 3867 return pBt ? sqlite3BtreeIsReadonly(pBt) : -1; 3868 3868 } 3869 + 3870 +#ifdef SQLITE_ENABLE_SNAPSHOT 3871 +/* 3872 +** Obtain a snapshot handle for the snapshot of database zDb currently 3873 +** being read by handle db. 3874 +*/ 3875 +int sqlite3_snapshot_get( 3876 + sqlite3 *db, 3877 + const char *zDb, 3878 + sqlite3_snapshot **ppSnapshot 3879 +){ 3880 + int rc = SQLITE_ERROR; 3881 +#ifndef SQLITE_OMIT_WAL 3882 + int iDb; 3883 + 3884 +#ifdef SQLITE_ENABLE_API_ARMOR 3885 + if( !sqlite3SafetyCheckOk(db) ){ 3886 + return SQLITE_MISUSE_BKPT; 3887 + } 3888 +#endif 3889 + sqlite3_mutex_enter(db->mutex); 3890 + 3891 + iDb = sqlite3FindDbName(db, zDb); 3892 + if( iDb==0 || iDb>1 ){ 3893 + Btree *pBt = db->aDb[iDb].pBt; 3894 + if( 0!=sqlite3BtreeIsInReadTrans(pBt) 3895 + && 0==sqlite3BtreeIsInTrans(pBt) 3896 + ){ 3897 + rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot); 3898 + } 3899 + } 3900 + 3901 + sqlite3_mutex_leave(db->mutex); 3902 +#endif /* SQLITE_OMIT_WAL */ 3903 + return rc; 3904 +} 3905 + 3906 +/* 3907 +** Open a read-transaction on the snapshot idendified by pSnapshot. 3908 +*/ 3909 +int sqlite3_snapshot_open( 3910 + sqlite3 *db, 3911 + const char *zDb, 3912 + sqlite3_snapshot *pSnapshot 3913 +){ 3914 + int rc = SQLITE_ERROR; 3915 +#ifndef SQLITE_OMIT_WAL 3916 + 3917 +#ifdef SQLITE_ENABLE_API_ARMOR 3918 + if( !sqlite3SafetyCheckOk(db) ){ 3919 + return SQLITE_MISUSE_BKPT; 3920 + } 3921 +#endif 3922 + sqlite3_mutex_enter(db->mutex); 3923 + if( db->autoCommit==0 ){ 3924 + int iDb; 3925 + iDb = sqlite3FindDbName(db, zDb); 3926 + if( iDb==0 || iDb>1 ){ 3927 + Btree *pBt = db->aDb[iDb].pBt; 3928 + if( 0==sqlite3BtreeIsInReadTrans(pBt) ){ 3929 + rc = sqlite3PagerSnapshotOpen(sqlite3BtreePager(pBt), pSnapshot); 3930 + if( rc==SQLITE_OK ){ 3931 + rc = sqlite3BtreeBeginTrans(pBt, 0); 3932 + sqlite3PagerSnapshotOpen(sqlite3BtreePager(pBt), 0); 3933 + } 3934 + } 3935 + } 3936 + } 3937 + 3938 + sqlite3_mutex_leave(db->mutex); 3939 +#endif /* SQLITE_OMIT_WAL */ 3940 + return rc; 3941 +} 3942 + 3943 +/* 3944 +** Free a snapshot handle obtained from sqlite3_snapshot_get(). 3945 +*/ 3946 +void sqlite3_snapshot_free(sqlite3_snapshot *pSnapshot){ 3947 + sqlite3_free(pSnapshot); 3948 +} 3949 +#endif /* SQLITE_ENABLE_SNAPSHOT */ 3950 +
Changes to src/pager.c.
7297 7297 pPager->pWal = 0; 7298 7298 pagerFixMaplimit(pPager); 7299 7299 } 7300 7300 } 7301 7301 return rc; 7302 7302 } 7303 7303 7304 +#ifdef SQLITE_ENABLE_SNAPSHOT 7305 +/* 7306 +** If this is a WAL database, obtain a snapshot handle for the snapshot 7307 +** currently open. Otherwise, return an error. 7308 +*/ 7309 +int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot){ 7310 + int rc = SQLITE_ERROR; 7311 + if( pPager->pWal ){ 7312 + rc = sqlite3WalSnapshotGet(pPager->pWal, ppSnapshot); 7313 + } 7314 + return rc; 7315 +} 7316 + 7317 +/* 7318 +** If this is a WAL database, store a pointer to pSnapshot. Next time a 7319 +** read transaction is opened, attempt to read from the snapshot it 7320 +** identifies. If this is not a WAL database, return an error. 7321 +*/ 7322 +int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot){ 7323 + int rc = SQLITE_OK; 7324 + if( pPager->pWal ){ 7325 + sqlite3WalSnapshotOpen(pPager->pWal, pSnapshot); 7326 + }else{ 7327 + rc = SQLITE_ERROR; 7328 + } 7329 + return rc; 7330 +} 7331 +#endif /* SQLITE_ENABLE_SNAPSHOT */ 7304 7332 #endif /* !SQLITE_OMIT_WAL */ 7305 7333 7306 7334 #ifdef SQLITE_ENABLE_ZIPVFS 7307 7335 /* 7308 7336 ** A read-lock must be held on the pager when this function is called. If 7309 7337 ** the pager is in WAL mode and the WAL file currently contains one or more 7310 7338 ** frames, return the size in bytes of the page images stored within the
Changes to src/pager.h.
164 164 165 165 #ifndef SQLITE_OMIT_WAL 166 166 int sqlite3PagerCheckpoint(Pager *pPager, int, int*, int*); 167 167 int sqlite3PagerWalSupported(Pager *pPager); 168 168 int sqlite3PagerWalCallback(Pager *pPager); 169 169 int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen); 170 170 int sqlite3PagerCloseWal(Pager *pPager); 171 +# ifdef SQLITE_ENABLE_SNAPSHOT 172 + int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot); 173 + int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot); 174 +# endif 171 175 #endif 172 176 173 177 #ifdef SQLITE_ENABLE_ZIPVFS 174 178 int sqlite3PagerWalFramesize(Pager *pPager); 175 179 #endif 176 180 177 181 /* Functions used to query pager state and configuration. */
Changes to src/sqlite.h.in.
7874 7874 ** Otherwise, if no error occurs, SQLITE_OK is returned. 7875 7875 ** 7876 7876 ** This function does not set the database handle error code or message 7877 7877 ** returned by the sqlite3_errcode() and sqlite3_errmsg() functions. 7878 7878 */ 7879 7879 int sqlite3_db_cacheflush(sqlite3*); 7880 7880 7881 +/* 7882 +** CAPI3REF: Open old database snapshots. 7883 +** 7884 +** The second argument passed to sqlite3_snapshot_get() must be the name 7885 +** of a database file attached to the database handle passed as the first. 7886 +** The database handle must have an open read transaction on the named 7887 +** database, which must be in wal mode. 7888 +** 7889 +** If successful, sqlite3_snapshot_get() sets *ppSnapshot to point to a new 7890 +** snapshot handle that may be used with sqlite3_snapshot_open() and returns 7891 +** SQLITE_OK. 7892 +** 7893 +** If the specified database does not exist, or is not a wal mode database, 7894 +** or the database handle does not have an open read transaction on it, 7895 +** SQLITE_ERROR is returned. If any other error occurs, for example an IO 7896 +** error or an OOM condition, the corresponding SQLite error code is 7897 +** returned. 7898 +*/ 7899 +typedef struct sqlite3_snapshot sqlite3_snapshot; 7900 +int sqlite3_snapshot_get(sqlite3*, const char*, sqlite3_snapshot **ppSnapshot); 7901 +int sqlite3_snapshot_open(sqlite3*, const char*, sqlite3_snapshot*); 7902 +void sqlite3_snapshot_free(sqlite3_snapshot*); 7903 + 7881 7904 /* 7882 7905 ** Undo the hack that converts floating point types to integer for 7883 7906 ** builds on processors without floating point support. 7884 7907 */ 7885 7908 #ifdef SQLITE_OMIT_FLOATING_POINT 7886 7909 # undef double 7887 7910 #endif 7888 7911 7889 7912 #ifdef __cplusplus 7890 7913 } /* End of the 'extern "C"' block */ 7891 7914 #endif 7892 7915 #endif /* _SQLITE3_H_ */
Changes to src/test1.c.
2264 2264 Tcl_WrongNumArgs(interp, 1, objv, ""); 2265 2265 return TCL_ERROR; 2266 2266 } 2267 2267 pVfs->xCurrentTimeInt64(pVfs, &t); 2268 2268 Tcl_SetObjResult(interp, Tcl_NewWideIntObj(t)); 2269 2269 return TCL_OK; 2270 2270 } 2271 + 2272 +/* 2273 +** Usage: sqlite3_snapshot_get DB DBNAME 2274 +*/ 2275 +static int test_snapshot_get( 2276 + void * clientData, 2277 + Tcl_Interp *interp, 2278 + int objc, 2279 + Tcl_Obj *CONST objv[] 2280 +){ 2281 + int rc; 2282 + sqlite3 *db; 2283 + char *zName; 2284 + sqlite3_snapshot *pSnapshot = 0; 2285 + 2286 + if( objc!=3 ){ 2287 + Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME"); 2288 + return TCL_ERROR; 2289 + } 2290 + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 2291 + zName = Tcl_GetString(objv[2]); 2292 + 2293 + rc = sqlite3_snapshot_get(db, zName, &pSnapshot); 2294 + if( rc!=SQLITE_OK ){ 2295 + Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); 2296 + return TCL_ERROR; 2297 + }else{ 2298 + char zBuf[100]; 2299 + if( sqlite3TestMakePointerStr(interp, zBuf, pSnapshot) ) return TCL_ERROR; 2300 + Tcl_SetObjResult(interp, Tcl_NewStringObj(zBuf, -1)); 2301 + } 2302 + return TCL_OK; 2303 +} 2304 + 2305 +/* 2306 +** Usage: sqlite3_snapshot_open DB DBNAME SNAPSHOT 2307 +*/ 2308 +static int test_snapshot_open( 2309 + void * clientData, 2310 + Tcl_Interp *interp, 2311 + int objc, 2312 + Tcl_Obj *CONST objv[] 2313 +){ 2314 + int rc; 2315 + sqlite3 *db; 2316 + char *zName; 2317 + sqlite3_snapshot *pSnapshot; 2318 + 2319 + if( objc!=4 ){ 2320 + Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME SNAPSHOT"); 2321 + return TCL_ERROR; 2322 + } 2323 + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 2324 + zName = Tcl_GetString(objv[2]); 2325 + pSnapshot = (sqlite3_snapshot*)sqlite3TestTextToPtr(Tcl_GetString(objv[3])); 2326 + 2327 + rc = sqlite3_snapshot_open(db, zName, pSnapshot); 2328 + if( rc!=SQLITE_OK ){ 2329 + Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); 2330 + return TCL_ERROR; 2331 + } 2332 + return TCL_OK; 2333 +} 2334 + 2335 +/* 2336 +** Usage: sqlite3_snapshot_free SNAPSHOT 2337 +*/ 2338 +static int test_snapshot_free( 2339 + void * clientData, 2340 + Tcl_Interp *interp, 2341 + int objc, 2342 + Tcl_Obj *CONST objv[] 2343 +){ 2344 + sqlite3_snapshot *pSnapshot; 2345 + if( objc!=2 ){ 2346 + Tcl_WrongNumArgs(interp, 1, objv, "SNAPSHOT"); 2347 + return TCL_ERROR; 2348 + } 2349 + pSnapshot = (sqlite3_snapshot*)sqlite3TestTextToPtr(Tcl_GetString(objv[1])); 2350 + sqlite3_snapshot_free(pSnapshot); 2351 + return TCL_OK; 2352 +} 2271 2353 2272 2354 /* 2273 2355 ** Usage: sqlite3_next_stmt DB STMT 2274 2356 ** 2275 2357 ** Return the next statment in sequence after STMT. 2276 2358 */ 2277 2359 static int test_next_stmt( ................................................................................ 7079 7161 { "sqlite3_stmt_scanstatus", test_stmt_scanstatus, 0 }, 7080 7162 { "sqlite3_stmt_scanstatus_reset", test_stmt_scanstatus_reset, 0 }, 7081 7163 #endif 7082 7164 #ifdef SQLITE_ENABLE_SQLLOG 7083 7165 { "sqlite3_config_sqllog", test_config_sqllog, 0 }, 7084 7166 #endif 7085 7167 { "vfs_current_time_int64", vfsCurrentTimeInt64, 0 }, 7168 +#ifdef SQLITE_ENABLE_SNAPSHOT 7169 + { "sqlite3_snapshot_get", test_snapshot_get, 0 }, 7170 + { "sqlite3_snapshot_open", test_snapshot_open, 0 }, 7171 + { "sqlite3_snapshot_free", test_snapshot_free, 0 }, 7172 +#endif 7086 7173 }; 7087 7174 static int bitmask_size = sizeof(Bitmask)*8; 7088 7175 static int longdouble_size = sizeof(LONGDOUBLE_TYPE); 7089 7176 int i; 7090 7177 extern int sqlite3_sync_count, sqlite3_fullsync_count; 7091 7178 extern int sqlite3_opentemp_count; 7092 7179 extern int sqlite3_like_count;
Changes to src/wal.c.
430 430 WalIndexHdr hdr; /* Wal-index header for current transaction */ 431 431 u32 minFrame; /* Ignore wal frames before this one */ 432 432 const char *zWalName; /* Name of WAL file */ 433 433 u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ 434 434 #ifdef SQLITE_DEBUG 435 435 u8 lockError; /* True if a locking error has occurred */ 436 436 #endif 437 +#ifdef SQLITE_ENABLE_SNAPSHOT 438 + WalIndexHdr *pSnapshot; 439 +#endif 437 440 }; 438 441 439 442 /* 440 443 ** Candidate values for Wal.exclusiveMode. 441 444 */ 442 445 #define WAL_NORMAL_MODE 0 443 446 #define WAL_EXCLUSIVE_MODE 1 ................................................................................ 2143 2146 */ 2144 2147 static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ 2145 2148 volatile WalCkptInfo *pInfo; /* Checkpoint information in wal-index */ 2146 2149 u32 mxReadMark; /* Largest aReadMark[] value */ 2147 2150 int mxI; /* Index of largest aReadMark[] value */ 2148 2151 int i; /* Loop counter */ 2149 2152 int rc = SQLITE_OK; /* Return code */ 2153 + int mxFrame; /* Wal frame to lock to */ 2150 2154 2151 2155 assert( pWal->readLock<0 ); /* Not currently locked */ 2152 2156 2153 2157 /* Take steps to avoid spinning forever if there is a protocol error. 2154 2158 ** 2155 2159 ** Circumstances that cause a RETRY should only last for the briefest 2156 2160 ** instances of time. No I/O or other system calls are done while the ................................................................................ 2206 2210 } 2207 2211 if( rc!=SQLITE_OK ){ 2208 2212 return rc; 2209 2213 } 2210 2214 } 2211 2215 2212 2216 pInfo = walCkptInfo(pWal); 2213 - if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame ){ 2217 + if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame 2218 +#ifdef SQLITE_ENABLE_SNAPSHOT 2219 + && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0 2220 + || 0==memcmp(&pWal->hdr, pWal->pSnapshot, sizeof(WalIndexHdr))) 2221 +#endif 2222 + ){ 2214 2223 /* The WAL has been completely backfilled (or it is empty). 2215 2224 ** and can be safely ignored. 2216 2225 */ 2217 2226 rc = walLockShared(pWal, WAL_READ_LOCK(0)); 2218 2227 walShmBarrier(pWal); 2219 2228 if( rc==SQLITE_OK ){ 2220 2229 if( memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) ){ ................................................................................ 2244 2253 /* If we get this far, it means that the reader will want to use 2245 2254 ** the WAL to get at content from recent commits. The job now is 2246 2255 ** to select one of the aReadMark[] entries that is closest to 2247 2256 ** but not exceeding pWal->hdr.mxFrame and lock that entry. 2248 2257 */ 2249 2258 mxReadMark = 0; 2250 2259 mxI = 0; 2260 + mxFrame = pWal->hdr.mxFrame; 2261 +#ifdef SQLITE_ENABLE_SNAPSHOT 2262 + if( pWal->pSnapshot ) mxFrame = pWal->pSnapshot->mxFrame; 2263 +#endif 2251 2264 for(i=1; i<WAL_NREADER; i++){ 2252 2265 u32 thisMark = pInfo->aReadMark[i]; 2253 - if( mxReadMark<=thisMark && thisMark<=pWal->hdr.mxFrame ){ 2266 + if( mxReadMark<=thisMark && thisMark<=mxFrame ){ 2254 2267 assert( thisMark!=READMARK_NOT_USED ); 2255 2268 mxReadMark = thisMark; 2256 2269 mxI = i; 2257 2270 } 2258 2271 } 2259 2272 /* There was once an "if" here. The extra "{" is to preserve indentation. */ 2260 2273 { 2261 2274 if( (pWal->readOnly & WAL_SHM_RDONLY)==0 2262 - && (mxReadMark<pWal->hdr.mxFrame || mxI==0) 2275 + && (mxReadMark<mxFrame || mxI==0) 2263 2276 ){ 2264 2277 for(i=1; i<WAL_NREADER; i++){ 2265 2278 rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1); 2266 2279 if( rc==SQLITE_OK ){ 2267 - mxReadMark = pInfo->aReadMark[i] = pWal->hdr.mxFrame; 2280 + mxReadMark = pInfo->aReadMark[i] = mxFrame; 2268 2281 mxI = i; 2269 2282 walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); 2270 2283 break; 2271 2284 }else if( rc!=SQLITE_BUSY ){ 2272 2285 return rc; 2273 2286 } 2274 2287 } ................................................................................ 2345 2358 ** Pager layer will use this to know that is cache is stale and 2346 2359 ** needs to be flushed. 2347 2360 */ 2348 2361 int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ 2349 2362 int rc; /* Return code */ 2350 2363 int cnt = 0; /* Number of TryBeginRead attempts */ 2351 2364 2365 +#ifdef SQLITE_ENABLE_SNAPSHOT 2366 + int bChanged = 0; 2367 + WalIndexHdr *pSnapshot = pWal->pSnapshot; 2368 + if( pSnapshot && memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))){ 2369 + bChanged = 1; 2370 + } 2371 +#endif 2372 + 2352 2373 do{ 2353 2374 rc = walTryBeginRead(pWal, pChanged, 0, ++cnt); 2354 2375 }while( rc==WAL_RETRY ); 2355 2376 testcase( (rc&0xff)==SQLITE_BUSY ); 2356 2377 testcase( (rc&0xff)==SQLITE_IOERR ); 2357 2378 testcase( rc==SQLITE_PROTOCOL ); 2358 2379 testcase( rc==SQLITE_OK ); 2380 + 2381 +#ifdef SQLITE_ENABLE_SNAPSHOT 2382 + if( rc==SQLITE_OK ){ 2383 + if( pSnapshot && memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr)) ){ 2384 + volatile WalCkptInfo *pInfo = walCkptInfo(pWal); 2385 + rc = walLockShared(pWal, WAL_READ_LOCK(0)); 2386 + if( rc==SQLITE_OK ){ 2387 + if( pInfo->nBackfill<=pSnapshot->mxFrame 2388 + && pSnapshot->aSalt[0]==pWal->hdr.aSalt[0] 2389 + && pSnapshot->aSalt[1]==pWal->hdr.aSalt[1] 2390 + ){ 2391 + assert( pWal->readLock>0 ); 2392 + assert( pInfo->aReadMark[pWal->readLock]<=pSnapshot->mxFrame ); 2393 + memcpy(&pWal->hdr, pSnapshot, sizeof(WalIndexHdr)); 2394 + *pChanged = bChanged; 2395 + }else{ 2396 + rc = SQLITE_BUSY_SNAPSHOT; 2397 + } 2398 + walUnlockShared(pWal, WAL_READ_LOCK(0)); 2399 + } 2400 + if( rc!=SQLITE_OK ){ 2401 + sqlite3WalEndReadTransaction(pWal); 2402 + } 2403 + } 2404 + } 2405 +#endif 2359 2406 return rc; 2360 2407 } 2361 2408 2362 2409 /* 2363 2410 ** Finish with a read transaction. All this does is release the 2364 2411 ** read-lock. 2365 2412 */ ................................................................................ 3161 3208 ** heap-memory for the wal-index. Otherwise, if the argument is NULL or the 3162 3209 ** WAL module is using shared-memory, return false. 3163 3210 */ 3164 3211 int sqlite3WalHeapMemory(Wal *pWal){ 3165 3212 return (pWal && pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ); 3166 3213 } 3167 3214 3215 +#ifdef SQLITE_ENABLE_SNAPSHOT 3216 +int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot){ 3217 + int rc = SQLITE_OK; 3218 + WalIndexHdr *pRet; 3219 + 3220 + assert( pWal->readLock>=0 && pWal->writeLock==0 ); 3221 + 3222 + pRet = (WalIndexHdr*)sqlite3_malloc(sizeof(WalIndexHdr)); 3223 + if( pRet==0 ){ 3224 + rc = SQLITE_NOMEM; 3225 + }else{ 3226 + memcpy(pRet, &pWal->hdr, sizeof(WalIndexHdr)); 3227 + *ppSnapshot = (sqlite3_snapshot*)pRet; 3228 + } 3229 + 3230 + return rc; 3231 +} 3232 + 3233 +void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot){ 3234 + pWal->pSnapshot = (WalIndexHdr*)pSnapshot; 3235 +} 3236 +#endif /* SQLITE_ENABLE_SNAPSHOT */ 3237 + 3168 3238 #ifdef SQLITE_ENABLE_ZIPVFS 3169 3239 /* 3170 3240 ** If the argument is not NULL, it points to a Wal object that holds a 3171 3241 ** read-lock. This function returns the database page-size if it is known, 3172 3242 ** or zero if it is not (or if pWal is NULL). 3173 3243 */ 3174 3244 int sqlite3WalFramesize(Wal *pWal){ 3175 3245 assert( pWal==0 || pWal->readLock>=0 ); 3176 3246 return (pWal ? pWal->szPage : 0); 3177 3247 } 3178 3248 #endif 3179 3249 3180 3250 #endif /* #ifndef SQLITE_OMIT_WAL */
Changes to src/wal.h.
121 121 int sqlite3WalExclusiveMode(Wal *pWal, int op); 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 + 129 +#ifdef SQLITE_ENABLE_SNAPSHOT 130 +int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot); 131 +void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot); 132 +#endif 128 133 129 134 #ifdef SQLITE_ENABLE_ZIPVFS 130 135 /* If the WAL file is not empty, return the number of bytes of content 131 136 ** stored in each frame (i.e. the db page-size when the WAL was created). 132 137 */ 133 138 int sqlite3WalFramesize(Wal *pWal); 134 139 #endif 135 140 136 141 #endif /* ifndef SQLITE_OMIT_WAL */ 137 142 #endif /* _WAL_H_ */