aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/btree.c10
-rw-r--r--src/main.c4
-rw-r--r--src/os_unix.c11
-rw-r--r--src/pager.c219
-rw-r--r--src/pragma.c12
-rw-r--r--src/sqliteInt.h2
-rw-r--r--src/test_config.c6
-rw-r--r--src/vdbe.c5
-rw-r--r--src/vdbeapi.c8
-rw-r--r--src/wal.c4
-rw-r--r--src/wal.h17
11 files changed, 204 insertions, 94 deletions
diff --git a/src/btree.c b/src/btree.c
index e60754e58..eace01fff 100644
--- a/src/btree.c
+++ b/src/btree.c
@@ -2261,6 +2261,15 @@ static int lockBtree(BtShared *pBt){
if( memcmp(page1, zMagicHeader, 16)!=0 ){
goto page1_init_failed;
}
+
+#ifdef SQLITE_OMIT_WAL
+ if( page1[18]>1 ){
+ pBt->readOnly = 1;
+ }
+ if( page1[19]>1 ){
+ goto page1_init_failed;
+ }
+#else
if( page1[18]>2 ){
pBt->readOnly = 1;
}
@@ -2287,6 +2296,7 @@ static int lockBtree(BtShared *pBt){
}
rc = SQLITE_NOTADB;
}
+#endif
/* The maximum embedded fraction must be exactly 25%. And the minimum
** embedded fraction must be 12.5% for both leaf-data and non-leaf-data.
diff --git a/src/main.c b/src/main.c
index c723a4ef5..57ea9736a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1195,6 +1195,7 @@ void *sqlite3_wal_hook(
int(*xCallback)(void *, sqlite3*, const char*, int),
void *pArg /* First argument passed to xCallback() */
){
+#ifndef SQLITE_OMIT_WAL
void *pRet;
sqlite3_mutex_enter(db->mutex);
pRet = db->pWalArg;
@@ -1202,6 +1203,9 @@ void *sqlite3_wal_hook(
db->pWalArg = pArg;
sqlite3_mutex_leave(db->mutex);
return pRet;
+#else
+ return 0;
+#endif
}
/*
diff --git a/src/os_unix.c b/src/os_unix.c
index f37afa1f1..b2c22c365 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -4562,6 +4562,8 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){
return 0;
}
+#ifndef SQLITE_OMIT_WAL
+
/* Forward reference */
typedef struct unixShm unixShm;
typedef struct unixShmFile unixShmFile;
@@ -5334,6 +5336,15 @@ static int unixShmDelete(sqlite3_vfs *pVfs, const char *zName){
return pVfs->xDelete(pVfs, zName, 0);
}
+#else
+# define unixShmOpen 0
+# define unixShmSize 0
+# define unixShmGet 0
+# define unixShmRelease 0
+# define unixShmLock 0
+# define unixShmClose 0
+# define unixShmDelete 0
+#endif /* #ifndef SQLITE_OMIT_WAL */
/*
************************ End of sqlite3_vfs methods ***************************
diff --git a/src/pager.c b/src/pager.c
index ee0c575a5..00d07caff 100644
--- a/src/pager.c
+++ b/src/pager.c
@@ -399,7 +399,9 @@ struct Pager {
char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */
PCache *pPCache; /* Pointer to page cache object */
sqlite3_backup *pBackup; /* Pointer to list of ongoing backup processes */
+#ifndef SQLITE_OMIT_WAL
Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */
+#endif
};
/*
@@ -1192,9 +1194,16 @@ static int addToSavepointBitvecs(Pager *pPager, Pgno pgno){
** Return true if this pager uses a write-ahead log instead of the usual
** rollback journal. Otherwise false.
*/
+#ifndef SQLITE_OMIT_WAL
static int pagerUseWal(Pager *pPager){
return (pPager->pWal!=0);
}
+#else
+# define pagerUseWal(x) 0
+# define pagerRollbackWal(x) 0
+# define pagerWalFrames(v,w,x,y,z) 0
+# define pagerOpenWalIfPresent(z) SQLITE_OK
+#endif
/*
** Unlock the database file. This function is a no-op if the pager
@@ -2242,6 +2251,7 @@ static int readDbPage(PgHdr *pPg){
return rc;
}
+#ifndef SQLITE_OMIT_WAL
/*
** This function is invoked once for each page that has already been
** written into the log file when a WAL transaction is rolled back.
@@ -2312,6 +2322,115 @@ static int pagerRollbackWal(Pager *pPager){
}
/*
+** This function is a wrapper around sqlite3WalFrames(). As well as logging
+** the contents of the list of pages headed by pList (connected by pDirty),
+** this function notifies any active backup processes that the pages have
+** changed.
+*/
+static int pagerWalFrames(
+ Pager *pPager, /* Pager object */
+ PgHdr *pList, /* List of frames to log */
+ Pgno nTruncate, /* Database size after this commit */
+ int isCommit, /* True if this is a commit */
+ int sync_flags /* Flags to pass to OsSync() (or 0) */
+){
+ int rc; /* Return code */
+
+ assert( pPager->pWal );
+ rc = sqlite3WalFrames(pPager->pWal,
+ pPager->pageSize, pList, nTruncate, isCommit, sync_flags
+ );
+ if( rc==SQLITE_OK && pPager->pBackup ){
+ PgHdr *p;
+ for(p=pList; p; p=p->pDirty){
+ sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData);
+ }
+ }
+ return rc;
+}
+
+/*
+** Open a WAL snapshot on the log file this pager is connected to.
+*/
+static int pagerOpenSnapshot(Pager *pPager){
+ int rc; /* Return code */
+ int changed = 0; /* True if cache must be reset */
+
+ assert( pagerUseWal(pPager) );
+
+ rc = sqlite3WalOpenSnapshot(pPager->pWal, &changed);
+ if( rc==SQLITE_OK ){
+ int dummy;
+ if( changed ){
+ pager_reset(pPager);
+ assert( pPager->errCode || pPager->dbSizeValid==0 );
+ }
+ rc = sqlite3PagerPagecount(pPager, &dummy);
+ }
+ pPager->state = PAGER_SHARED;
+
+ return rc;
+}
+
+/*
+** Check if the *-wal file that corresponds to the database opened by pPager
+** exists. Assuming no error occurs, set *pExists to 1 if the file exists,
+** or 0 otherwise and return SQLITE_OK. If an IO or OOM error occurs, return
+** an SQLite error code.
+*/
+static int pagerHasWAL(Pager *pPager, int *pExists){
+ int rc; /* Return code */
+
+ if( !pPager->tempFile ){
+ char *zWal = sqlite3_mprintf("%s-wal", pPager->zFilename);
+ if( !zWal ){
+ rc = SQLITE_NOMEM;
+ }else{
+ rc = sqlite3OsAccess(pPager->pVfs, zWal, SQLITE_ACCESS_EXISTS, pExists);
+ sqlite3_free(zWal);
+ }
+ }else{
+ rc = SQLITE_OK;
+ *pExists = 0;
+ }
+ return rc;
+}
+
+/*
+** Check if the *-wal file that corresponds to the database opened by pPager
+** exists. If it does, open the pager in WAL mode. Otherwise, if no error
+** occurs, make sure Pager.journalMode is not set to PAGER_JOURNALMODE_WAL.
+** If an IO or OOM error occurs, return an SQLite error code.
+**
+** If the WAL file is opened, also open a snapshot (read transaction).
+**
+** The caller must hold a SHARED lock on the database file to call this
+** function. Because an EXCLUSIVE lock on the db file is required to delete
+** a WAL, this ensures there is no race condition between the xAccess()
+** below and an xDelete() being executed by some other connection.
+*/
+static int pagerOpenWalIfPresent(Pager *pPager){
+ int rc = SQLITE_OK;
+ if( !pPager->tempFile ){
+ int isWal; /* True if WAL file exists */
+ rc = pagerHasWAL(pPager, &isWal);
+ if( rc==SQLITE_OK ){
+ if( isWal ){
+ pager_reset(pPager);
+ rc = sqlite3PagerOpenWal(pPager, 0);
+ if( rc==SQLITE_OK ){
+ rc = pagerOpenSnapshot(pPager);
+ }
+ }else if( pPager->journalMode==PAGER_JOURNALMODE_WAL ){
+ pPager->journalMode = PAGER_JOURNALMODE_DELETE;
+ }
+ }
+ }
+ return rc;
+}
+#endif
+
+/*
** Playback savepoint pSavepoint. Or, if pSavepoint==NULL, then playback
** the entire master journal file. The case pSavepoint==NULL occurs when
** a ROLLBACK TO command is invoked on a SAVEPOINT that is a transaction
@@ -2934,10 +3053,12 @@ int sqlite3PagerClose(Pager *pPager){
sqlite3BeginBenignMalloc();
pPager->errCode = 0;
pPager->exclusiveMode = 0;
+#ifndef SQLITE_OMIT_WAL
sqlite3WalClose(pPager->pWal, pPager->fd,
(pPager->noSync ? 0 : pPager->sync_flags), pTmp
);
pPager->pWal = 0;
+#endif
pager_reset(pPager);
if( MEMDB ){
pager_unlock(pPager);
@@ -3281,34 +3402,6 @@ static int subjournalPage(PgHdr *pPg){
}
/*
-** This function is a wrapper around sqlite3WalFrames(). As well as logging
-** the contents of the list of pages headed by pList (connected by pDirty),
-** this function notifies any active backup processes that the pages have
-** changed.
-*/
-static int pagerWalFrames(
- Pager *pPager, /* Pager object */
- PgHdr *pList, /* List of frames to log */
- Pgno nTruncate, /* Database size after this commit */
- int isCommit, /* True if this is a commit */
- int sync_flags /* Flags to pass to OsSync() (or 0) */
-){
- int rc; /* Return code */
-
- assert( pPager->pWal );
- rc = sqlite3WalFrames(pPager->pWal,
- pPager->pageSize, pList, nTruncate, isCommit, sync_flags
- );
- if( rc==SQLITE_OK && pPager->pBackup ){
- PgHdr *p;
- for(p=pList; p; p=p->pDirty){
- sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData);
- }
- }
- return rc;
-}
-
-/*
** This function is called by the pcache layer when it has reached some
** soft memory limit. The first argument is a pointer to a Pager object
** (cast as a void*). The pager is always 'purgeable' (not an in-memory
@@ -3820,55 +3913,6 @@ static int hasHotJournal(Pager *pPager, int *pExists){
}
/*
-** Check if the *-wal file that corresponds to the database opened by pPager
-** exists. Assuming no error occurs, set *pExists to 1 if the file exists,
-** or 0 otherwise and return SQLITE_OK. If an IO or OOM error occurs, return
-** an SQLite error code.
-**
-** The caller must hold a SHARED lock on the database file to call this
-** function. Because an EXCLUSIVE lock on the db file is required to delete
-** a WAL, this ensures there is no race condition between the xAccess()
-** below and an xDelete() being executed by some other connection.
-*/
-static int pagerHasWAL(Pager *pPager, int *pExists){
- int rc; /* Return code */
-
- if( !pPager->tempFile ){
- char *zWal = sqlite3_mprintf("%s-wal", pPager->zFilename);
- if( !zWal ){
- rc = SQLITE_NOMEM;
- }else{
- rc = sqlite3OsAccess(pPager->pVfs, zWal, SQLITE_ACCESS_EXISTS, pExists);
- sqlite3_free(zWal);
- }
- }else{
- rc = SQLITE_OK;
- *pExists = 0;
- }
- return rc;
-}
-
-static int pagerOpenSnapshot(Pager *pPager){
- int rc; /* Return code */
- int changed = 0; /* True if cache must be reset */
-
- assert( pagerUseWal(pPager) );
-
- rc = sqlite3WalOpenSnapshot(pPager->pWal, &changed);
- if( rc==SQLITE_OK ){
- int dummy;
- if( changed ){
- pager_reset(pPager);
- assert( pPager->errCode || pPager->dbSizeValid==0 );
- }
- rc = sqlite3PagerPagecount(pPager, &dummy);
- }
- pPager->state = PAGER_SHARED;
-
- return rc;
-}
-
-/*
** This function is called to obtain a shared lock on the database file.
** It is illegal to call sqlite3PagerAcquire() until after this function
** has been successfully called. If a shared-lock is already held when
@@ -3926,7 +3970,6 @@ int sqlite3PagerSharedLock(Pager *pPager){
}else if( pPager->state==PAGER_UNLOCK || isErrorReset ){
sqlite3_vfs * const pVfs = pPager->pVfs;
int isHotJournal = 0;
- int isWal = 0;
assert( !MEMDB );
assert( sqlite3PcacheRefCount(pPager->pPCache)==0 );
if( pPager->noReadlock ){
@@ -4081,19 +4124,10 @@ int sqlite3PagerSharedLock(Pager *pPager){
}
assert( pPager->exclusiveMode || pPager->state==PAGER_SHARED );
- rc = pagerHasWAL(pPager, &isWal);
- if( rc!=SQLITE_OK ){
- goto failed;
- }
- if( isWal ){
- pager_reset(pPager);
- rc = sqlite3PagerOpenWal(pPager, 0);
- if( rc==SQLITE_OK ){
- rc = pagerOpenSnapshot(pPager);
- }
- }else if( pPager->journalMode==PAGER_JOURNALMODE_WAL ){
- pPager->journalMode = PAGER_JOURNALMODE_DELETE;
- }
+ /* If there is a WAL file in the file-system, open this database in WAL
+ ** mode. Otherwise, the following function call is a no-op.
+ */
+ rc = pagerOpenWalIfPresent(pPager);
}
failed:
@@ -5789,6 +5823,7 @@ sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){
return &pPager->pBackup;
}
+#ifndef SQLITE_OMIT_WAL
/*
** This function is called when the user invokes "PRAGMA checkpoint".
*/
@@ -5836,7 +5871,6 @@ int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen){
return rc;
}
-
/*
** This function is called to close the connection to the log file prior
** to switching from WAL to rollback mode.
@@ -5881,5 +5915,6 @@ int sqlite3PagerCloseWal(Pager *pPager){
}
return rc;
}
+#endif
#endif /* SQLITE_OMIT_DISKIO */
diff --git a/src/pragma.c b/src/pragma.c
index da6a6807f..263b7fc0c 100644
--- a/src/pragma.c
+++ b/src/pragma.c
@@ -265,7 +265,10 @@ static const char *actionName(u8 action){
*/
const char *sqlite3JournalModename(int eMode){
static char * const azModeName[] = {
- "delete", "persist", "off", "truncate", "memory", "wal"
+ "delete", "persist", "off", "truncate", "memory"
+#ifndef SQLITE_OMIT_WAL
+ , "wal"
+#endif
};
assert( PAGER_JOURNALMODE_DELETE==0 );
assert( PAGER_JOURNALMODE_PERSIST==1 );
@@ -1397,10 +1400,17 @@ void sqlite3Pragma(
}else
#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
+#ifndef SQLITE_OMIT_WAL
+ /*
+ ** PRAGMA [database.]checkpoint
+ **
+ ** Checkpoint the database.
+ */
if( sqlite3StrICmp(zLeft, "checkpoint")==0 ){
sqlite3VdbeUsesBtree(v, iDb);
sqlite3VdbeAddOp3(v, OP_Checkpoint, iDb, 0, 0);
}else
+#endif
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
/*
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 54effce12..28268104c 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -823,8 +823,10 @@ struct sqlite3 {
void (*xRollbackCallback)(void*); /* Invoked at every commit. */
void *pUpdateArg;
void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64);
+#ifndef SQLITE_OMIT_WAL
int (*xWalCallback)(void *, sqlite3 *, const char *, int);
void *pWalArg;
+#endif
void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*);
void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*);
void *pCollNeededArg;
diff --git a/src/test_config.c b/src/test_config.c
index 8544ee535..092d6a222 100644
--- a/src/test_config.c
+++ b/src/test_config.c
@@ -499,6 +499,12 @@ Tcl_SetVar2(interp, "sqlite_options", "long_double",
Tcl_SetVar2(interp, "sqlite_options", "vtab", "1", TCL_GLOBAL_ONLY);
#endif
+#ifdef SQLITE_OMIT_WAL
+ Tcl_SetVar2(interp, "sqlite_options", "wal", "0", TCL_GLOBAL_ONLY);
+#else
+ Tcl_SetVar2(interp, "sqlite_options", "wal", "1", TCL_GLOBAL_ONLY);
+#endif
+
#ifdef SQLITE_OMIT_WSD
Tcl_SetVar2(interp, "sqlite_options", "wsd", "0", TCL_GLOBAL_ONLY);
#else
diff --git a/src/vdbe.c b/src/vdbe.c
index c6a38c5ba..c040fb8d2 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -5186,6 +5186,7 @@ case OP_AggFinal: {
break;
}
+#ifndef SQLITE_OMIT_WAL
/* Opcode: Checkpoint P1 * * * *
**
** Checkpoint database P1. This is a no-op if P1 is not currently in
@@ -5200,6 +5201,7 @@ case OP_Checkpoint: {
rc = sqlite3PagerCheckpoint(sqlite3BtreePager(pBt));
break;
};
+#endif
/* Opcode: JournalMode P1 P2 P3 * *
**
@@ -5234,6 +5236,8 @@ case OP_JournalMode: { /* out2-prerelease */
pBt = db->aDb[pOp->p1].pBt;
pPager = sqlite3BtreePager(pBt);
+
+#ifndef SQLITE_OMIT_WAL
zFilename = sqlite3PagerFilename(pPager);
pVfs = sqlite3PagerVfs(pPager);
@@ -5282,6 +5286,7 @@ case OP_JournalMode: { /* out2-prerelease */
}
}
}
+#endif /* ifndef SQLITE_OMIT_WAL */
eNew = sqlite3PagerJournalMode(pPager, eNew);
pOut = &aMem[pOp->p2];
diff --git a/src/vdbeapi.c b/src/vdbeapi.c
index 12100ce56..5aec7ca0f 100644
--- a/src/vdbeapi.c
+++ b/src/vdbeapi.c
@@ -306,9 +306,14 @@ void sqlite3_result_error_nomem(sqlite3_context *pCtx){
pCtx->s.db->mallocFailed = 1;
}
+/*
+** This function is called after a transaction has been committed. It
+** invokes callbacks registered with sqlite3_wal_hook() as required.
+*/
static int doWalCallbacks(sqlite3 *db){
- int i;
int rc = SQLITE_OK;
+#ifndef SQLITE_OMIT_WAL
+ int i;
for(i=0; i<db->nDb; i++){
Btree *pBt = db->aDb[i].pBt;
if( pBt ){
@@ -320,6 +325,7 @@ static int doWalCallbacks(sqlite3 *db){
}
}
}
+#endif
return rc;
}
diff --git a/src/wal.c b/src/wal.c
index d406383a2..146675ad6 100644
--- a/src/wal.c
+++ b/src/wal.c
@@ -13,6 +13,8 @@
** This file contains the implementation of a write-ahead log file used in
** "journal_mode=wal" mode.
*/
+#ifndef SQLITE_OMIT_WAL
+
#include "wal.h"
@@ -1271,6 +1273,7 @@ int sqlite3WalCheckpoint(
int isChanged = 0; /* True if a new wal-index header is loaded */
assert( pWal->lockState==SQLITE_SHM_UNLOCK );
+ assert( pWal->pWiData==0 );
/* Get the CHECKPOINT lock */
do {
@@ -1315,3 +1318,4 @@ int sqlite3WalCallback(Wal *pWal){
}
return (int)ret;
}
+#endif /* #ifndef SQLITE_OMIT_WAL */
diff --git a/src/wal.h b/src/wal.h
index 1c787d8dc..fde28d479 100644
--- a/src/wal.h
+++ b/src/wal.h
@@ -19,6 +19,22 @@
#include "sqliteInt.h"
+#ifdef SQLITE_OMIT_WAL
+# define sqlite3WalOpen(x,y,z) 0
+# define sqlite3WalClose(w,x,y,z) 0
+# define sqlite3WalOpenSnapshot(y,z) 0
+# define sqlite3WalCloseSnapshot(z)
+# define sqlite3WalRead(w,x,y,z) 0
+# define sqlite3WalDbsize(y,z)
+# define sqlite3WalWriteLock(y,z) 0
+# define sqlite3WalUndo(x,y,z) 0
+# define sqlite3WalSavepoint(z) 0
+# define sqlite3WalSavepointUndo(y,z) 0
+# define sqlite3WalFrames(u,v,w,x,y,z) 0
+# define sqlite3WalCheckpoint(u,v,w,x,y,z) 0
+# define sqlite3WalCallback(z) 0
+#else
+
/* Connection to a write-ahead log (WAL) file.
** There is one object of this type for each pager.
*/
@@ -79,4 +95,5 @@ int sqlite3WalCheckpoint(
*/
int sqlite3WalCallback(Wal *pWal);
+#endif /* ifndef SQLITE_OMIT_WAL */
#endif /* _WAL_H_ */