aboutsummaryrefslogtreecommitdiff
path: root/src/pager.c
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2010-06-11 17:01:24 +0000
committerdrh <drh@noemail.net>2010-06-11 17:01:24 +0000
commit0b9b4301b886153ab88df439ae26f3cc20916ee9 (patch)
treef655857bcdf80ca7a85ea47a6f9eacc38e71f4fd /src/pager.c
parent5130c31b0c2cd11a34573898e95c7778c87e165c (diff)
downloadsqlite-0b9b4301b886153ab88df439ae26f3cc20916ee9.tar.gz
sqlite-0b9b4301b886153ab88df439ae26f3cc20916ee9.zip
Refactor and simplify the logic used to change journalmode.
FossilOrigin-Name: 95cc3f6fdec5494560c3cd4439d06870d1c62506
Diffstat (limited to 'src/pager.c')
-rw-r--r--src/pager.c98
1 files changed, 68 insertions, 30 deletions
diff --git a/src/pager.c b/src/pager.c
index 9e1ea7aa8..2b102fbea 100644
--- a/src/pager.c
+++ b/src/pager.c
@@ -5815,9 +5815,8 @@ int sqlite3PagerLockingMode(Pager *pPager, int eMode){
}
/*
-** Get/set the journal-mode for this pager. Parameter eMode must be one of:
+** Set the journal-mode for this pager. Parameter eMode must be one of:
**
-** PAGER_JOURNALMODE_QUERY
** PAGER_JOURNALMODE_DELETE
** PAGER_JOURNALMODE_TRUNCATE
** PAGER_JOURNALMODE_PERSIST
@@ -5825,56 +5824,95 @@ int sqlite3PagerLockingMode(Pager *pPager, int eMode){
** PAGER_JOURNALMODE_MEMORY
** PAGER_JOURNALMODE_WAL
**
-** If the parameter is not _QUERY, then the journal_mode is set to the
-** value specified if the change is allowed. The change may be disallowed
-** for the following reasons:
+** The journalmode is set to the value specified if the change is allowed.
+** The change may be disallowed for the following reasons:
**
** * An in-memory database can only have its journal_mode set to _OFF
** or _MEMORY.
**
-** * The journal mode may not be changed while a transaction is active.
+** * Temporary databases cannot have _WAL journalmode.
**
** The returned indicate the current (possibly updated) journal-mode.
*/
-int sqlite3PagerJournalMode(Pager *pPager, int eMode){
- assert( eMode==PAGER_JOURNALMODE_QUERY
- || eMode==PAGER_JOURNALMODE_DELETE
+int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){
+ u8 eOld = pPager->journalMode; /* Prior journalmode */
+
+ /* The eMode parameter is always valid */
+ assert( eMode==PAGER_JOURNALMODE_DELETE
|| eMode==PAGER_JOURNALMODE_TRUNCATE
|| eMode==PAGER_JOURNALMODE_PERSIST
|| eMode==PAGER_JOURNALMODE_OFF
|| eMode==PAGER_JOURNALMODE_WAL
|| eMode==PAGER_JOURNALMODE_MEMORY );
- assert( PAGER_JOURNALMODE_QUERY<0 );
- if( eMode==PAGER_JOURNALMODE_WAL
- && pPager->journalMode==PAGER_JOURNALMODE_DELETE
- ){
- pPager->journalMode = PAGER_JOURNALMODE_WAL;
- }else if( eMode>=0
- && (pPager->tempFile==0 || eMode!=PAGER_JOURNALMODE_WAL)
- && (!MEMDB || eMode==PAGER_JOURNALMODE_MEMORY||eMode==PAGER_JOURNALMODE_OFF)
- && !pPager->dbModified
- && (!isOpen(pPager->jfd) || 0==pPager->journalOff)
- ){
- if( isOpen(pPager->jfd) ){
- sqlite3OsClose(pPager->jfd);
+ /* Do not allow the journalmode of a TEMP database to be changed to WAL
+ */
+ if( pPager->tempFile && eMode==PAGER_JOURNALMODE_WAL ){
+ assert( eOld!=PAGER_JOURNALMODE_WAL );
+ eMode = eOld;
+ }
+
+ /* Do allow the journalmode of an in-memory database to be set to
+ ** anything other than MEMORY or OFF
+ */
+ if( MEMDB ){
+ assert( eOld==PAGER_JOURNALMODE_MEMORY || eOld==PAGER_JOURNALMODE_OFF );
+ if( eMode!=PAGER_JOURNALMODE_MEMORY && eMode!=PAGER_JOURNALMODE_OFF ){
+ eMode = eOld;
}
- assert( (PAGER_JOURNALMODE_TRUNCATE & 1)==1 );
- assert( (PAGER_JOURNALMODE_PERSIST & 1)==1 );
- assert( (PAGER_JOURNALMODE_DELETE & 1)==0 );
- assert( (PAGER_JOURNALMODE_MEMORY & 1)==0 );
- assert( (PAGER_JOURNALMODE_OFF & 1)==0 );
- if( (pPager->journalMode & 1)==1 && (eMode & 1)==0
- && !pPager->exclusiveMode ){
- sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
+ }
+
+ if( eMode!=eOld ){
+ /* When changing between rollback modes, close the journal file prior
+ ** to the change. But when changing from a rollback mode to WAL, keep
+ ** the journal open since there is a rollback-style transaction in play
+ ** used to convert the version numbers in the btree header.
+ */
+ if( isOpen(pPager->jfd) && eMode!=PAGER_JOURNALMODE_WAL ){
+ sqlite3OsClose(pPager->jfd);
}
+ /* Change the journal mode. */
pPager->journalMode = (u8)eMode;
+
+ /* When transistioning from TRUNCATE or PERSIST to any other journal
+ ** mode (and we are not in locking_mode=EXCLUSIVE) then delete the
+ ** journal file.
+ */
+ assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 );
+ assert( (PAGER_JOURNALMODE_PERSIST & 5)==1 );
+ assert( (PAGER_JOURNALMODE_DELETE & 5)!=1 );
+ assert( (PAGER_JOURNALMODE_MEMORY & 5)!=1 );
+ assert( (PAGER_JOURNALMODE_OFF & 5)!=1 );
+ assert( (PAGER_JOURNALMODE_WAL & 5)!=1 );
+ if( (eOld & 5)==1 && (eMode & 5)!=1 && !pPager->exclusiveMode ){
+ sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
+ }
}
+
+ /* Return the new journal mode */
return (int)pPager->journalMode;
}
/*
+** Return the current journal mode.
+*/
+int sqlite3PagerGetJournalMode(Pager *pPager){
+ return (int)pPager->journalMode;
+}
+
+/*
+** Return TRUE if the pager is in a state where it is OK to change the
+** journalmode. Journalmode changes can only happen when the database
+** is unmodified.
+*/
+int sqlite3PagerOkToChangeJournalMode(Pager *pPager){
+ if( pPager->dbModified ) return 0;
+ if( isOpen(pPager->jfd) && pPager->journalOff>0 ) return 0;
+ return 1;
+}
+
+/*
** Get/set the size-limit used for persistent journal files.
**
** Setting the size limit to -1 means no limit is enforced.