-C Add\sthe\ssqlite3_log_hook()\sinterface\sfor\sscheduling\scheckpoints.
-D 2010-04-19T18:03:52
+C Use\sthe\sread\sand\swrite\sversion\sfields\sof\sthe\sdatabase\sheader\sto\smark\sa\sdatabase\sas\soperating\sin\swal-mode.
+D 2010-04-20T18:53:15
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in 4f2f967b7e58a35bb74fb7ec8ae90e0f4ca7868b
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
F src/backup.c e86634da8c48357a759694c9c7c471125cd8d5a8
F src/bitvec.c 06ad2c36a9c3819c0b9cbffec7b15f58d5d834e0
F src/btmutex.c 96a12f50f7a17475155971a241d85ec5171573ff
-F src/btree.c 01559397cbd4a5aa62a822e8ca9ac94b6db14743
-F src/btree.h ad6cff92286f9b02ec32f0b97136e9a544249f37
+F src/btree.c 013cf019484e309e909a667654612b38a02dc2b6
+F src/btree.h dd83041eda10c17daf023257c1fc883b5f71f85a
F src/btreeInt.h 22447d259639271774a931cbf66aa55112846681
F src/build.c 11100b66fb97638d2d874c1d34d8db90650bb1d7
F src/callback.c 908f3e0172c3d4058f4ca0acd42c637c52e9669f
F src/os_os2.c 75a8c7b9a00a2cf1a65f9fa4afbc27d46634bb2f
F src/os_unix.c 5bf0015cebe2f21635da2af983c348eb88b3b4c1
F src/os_win.c 1c7453c2df4dab26d90ff6f91272aea18bcf7053
-F src/pager.c f9ad51dfa617131240ae77545c0083118324fc81
-F src/pager.h aeaee9ceb4a4a6d15c2163ef4e11a7590fd54b59
+F src/pager.c 1dcf76bead8f1b51809bd8189ef9b02f2c94dc7f
+F src/pager.h cee4487ab4f0911dd9f22a40e3cd55afdb7ef444
F src/parse.y ace5c7a125d9f2a410e431ee3209034105045f7e
F src/pcache.c ace8f6a5ecd4711cc66a1b23053be7109bd437cf
F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050
F src/pcache1.c 6dc1871ce8ead9187161c370a58cd06c84221f76
-F src/pragma.c f12cb58a8aa0d80cfed282ef87a285ed71beb793
+F src/pragma.c bae3ce82ca6d0ac5d3ca3e46b286856d1f0ddd70
F src/prepare.c fd1398cb1da54385ba5bd68d93928f10d10a1d9c
F src/printf.c 5f5b65a83e63f2096a541a340722a509fa0240a7
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685
F src/util.c 32aebf04c10e51ad3977a928b7416bed671b620b
F src/vacuum.c b1d542c8919d4d11119f78069e1906a1ad07e0ee
-F src/vdbe.c 2e2aaa765de667dd15e0462cf853efd1b2f97998
+F src/vdbe.c 304851b32c5f918a7ce92e4e9f94fbde0b604b21
F src/vdbe.h 471f6a3dcec4817ca33596fe7f6654d56c0e75f3
F src/vdbeInt.h 19ebc8c2a2e938340051ee65af3f377fb99102d1
F src/vdbeapi.c 466044df5bc916f778833e927165fd02cdef6086
F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
F test/vtab_shared.test 0eff9ce4f19facbe0a3e693f6c14b80711a4222d
-F test/wal.test a56ff378f58b145fd3bf38c277fbfe792cd47bdd
+F test/wal.test 273c0006e75c99cb34d0659851e7103fd4748c20
F test/walcrash.test 45cfbab30bb7cbe0b2e9d5cabe90dbcad10cb89b
F test/walhook.test 76a559e262f0715c470bade4a8d8333035f8ee47
+F test/walmode.test cd6ee20f08af2d81fddc049f8d7e387a807f067e
F test/walslow.test 38076d5fad49e3678027be0f8110e6a32d531dc2
F test/walthread.test 27e44ee6fd02f1f494a24f999c97086af3ab739d
F test/where.test de337a3fe0a459ec7c93db16a519657a90552330
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 9d51c3b754f0b94fea5ef3d669ad583b93b2b024
-R 8eb45c9f56fe0d743248bffdfb606bc1
+P 9bda601455705475075e33bfa85687bce34b15ff
+R b30f3db6dd942a33d471d74ec2e33c70
U dan
-Z e82f118f370901abf724c6ac84b89351
+Z d82da3172ce11d2f9fc95cc996cdb180
-9bda601455705475075e33bfa85687bce34b15ff
\ No newline at end of file
+96bef18c1411c3e0348295886f105e1646c46320
\ No newline at end of file
if( memcmp(page1, zMagicHeader, 16)!=0 ){
goto page1_init_failed;
}
- if( page1[18]>1 ){
+ if( page1[18]>2 ){
pBt->readOnly = 1;
}
- if( page1[19]>1 ){
+ if( page1[19]>2 ){
goto page1_init_failed;
}
+ /* If the write version is set to 2, turn on write-ahead logging mode. */
+ if( page1[19]==2 ){
+ int isOpen = 0;
+ rc = sqlite3PagerOpenLog(pBt->pPager, &isOpen);
+ if( rc!=SQLITE_OK ){
+ goto page1_init_failed;
+ }else if( isOpen==0 ){
+ releasePage(pPage1);
+ return SQLITE_OK;
+ }
+ }
+
/* 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.
** The original design allowed these amounts to vary, but as of
pCur->isIncrblobHandle = 1;
}
#endif
+
+/*
+** Set both the "read version" (single byte at byte offset 18) and
+** "write version" (single byte at byte offset 19) fields in the database
+** header to iVersion.
+*/
+int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){
+ BtShared *pBt = pBtree->pBt;
+ int rc; /* Return code */
+
+ assert( pBtree->inTrans==TRANS_WRITE );
+ assert( pBt->pPage1 );
+ assert( iVersion==1 || iVersion==2 );
+
+ rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
+ if( rc==SQLITE_OK ){
+ u8 *aData = pBt->pPage1->aData;
+ aData[18] = (u8)iVersion;
+ aData[19] = (u8)iVersion;
+ }
+
+ return rc;
+}
void sqlite3BtreeCacheOverflow(BtCursor *);
void sqlite3BtreeClearCursor(BtCursor *);
+int sqlite3BtreeSetVersion(Btree *pBt, int iVersion);
+
#ifndef NDEBUG
int sqlite3BtreeCursorIsValid(BtCursor*);
#endif
/* This branch may be executed with Pager.journalMode==MEMORY if
** a hot-journal was just rolled back. In this case the journal
** file should be closed and deleted. If this connection writes to
- ** the database file, it will do so using an in-memory journal. */
+ ** the database file, it will do so using an in-memory journal.
+ */
assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE
|| pPager->journalMode==PAGER_JOURNALMODE_MEMORY
+ || pPager->journalMode==PAGER_JOURNALMODE_WAL
);
sqlite3OsClose(pPager->jfd);
if( !pPager->tempFile ){
return rc;
}
-/*
-** Open a connection to the write-ahead log file for pager pPager. If
-** the log connection is already open, this function is a no-op.
-*/
-static int pagerOpenLog(Pager *pPager){
- if( !pPager->pLog ){
- int rc; /* Return code */
-
- /* Before opening the log file, obtain a SHARED lock on the database
- ** file. This lock will not be released until after the log file
- ** connection has been closed. The purpose of this lock is to stop
- ** any other process from unlinking the log or log-summary files while
- ** this connection still has them open. An EXCLUSIVE lock on the
- ** database file is required to unlink either of those two files.
- */
- assert( pPager->state==PAGER_UNLOCK );
- rc = pager_wait_on_lock(pPager, SHARED_LOCK);
- if( rc!=SQLITE_OK ){
- assert( pPager->state==PAGER_UNLOCK );
- return pager_error(pPager, rc);
- }
- assert( pPager->state>=SHARED_LOCK );
-
- /* Open the connection to the log file. If this operation fails,
- ** (e.g. due to malloc() failure), unlock the database file and
- ** return an error code.
- */
- rc = sqlite3LogOpen(pPager->pVfs, pPager->zFilename, &pPager->pLog);
- if( rc!=SQLITE_OK ){
- osUnlock(pPager->fd, SQLITE_LOCK_NONE);
- pPager->state = PAGER_UNLOCK;
- return rc;
- }
- }else{
- /* If the log file was already open, check that the pager is still holding
- ** the required SHARED lock on the database file.
- */
-#ifdef SQLITE_DEBUG
- int locktype;
- sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_LOCKSTATE, &locktype);
- assert( locktype==SQLITE_LOCK_SHARED );
-#endif
- pPager->state = PAGER_SHARED;
- }
-
- return SQLITE_OK;
-}
-
/*
** This function is called to obtain a shared lock on the database file.
pager_reset(pPager);
}
-
- if( pPager->journalMode==PAGER_JOURNALMODE_WAL ){
+ if( pagerUseLog(pPager) ){
int changed = 0; /* True if the cache must be flushed */
- /* Open the log file, if it is not already open. */
- rc = pagerOpenLog(pPager);
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
/* Open a log snapshot to read from. */
rc = sqlite3LogOpenSnapshot(pPager->pLog, &changed);
if( rc==SQLITE_OK ){
}
rc = sqlite3PagerPagecount(pPager, &dummy);
}
+ pPager->state = PAGER_SHARED;
+
}else if( pPager->state==PAGER_UNLOCK || isErrorReset ){
sqlite3_vfs * const pVfs = pPager->pVfs;
int isHotJournal = 0;
}
}
assert( pPager->exclusiveMode || pPager->state==PAGER_SHARED );
+
+ if( pPager->journalMode==PAGER_JOURNALMODE_WAL ){
+ pPager->journalMode = PAGER_JOURNALMODE_DELETE;
+ }
}
failed:
if( rc==SQLITE_OK ){
pPager->dbOrigSize = pPager->dbSize;
pPager->state = PAGER_RESERVED;
+ pPager->journalOff = 0;
}
}else{
/* Obtain a RESERVED lock on the database file. If the exFlag parameter
}
if( !isOpen(pPager->jfd)
&& pPager->journalMode!=PAGER_JOURNALMODE_OFF
- && pPager->journalMode!=PAGER_JOURNALMODE_WAL
+ && !pagerUseLog(pPager)
){
assert( pPager->useJournal );
rc = pager_open_journal(pPager);
** 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 is disallowed
+** 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
|| eMode==PAGER_JOURNALMODE_WAL
|| eMode==PAGER_JOURNALMODE_MEMORY );
assert( PAGER_JOURNALMODE_QUERY<0 );
- if( eMode>=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
sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
}
- /* Switching into WAL mode can only take place when no
- ** locks are held on the database file.
- */
- if( eMode==PAGER_JOURNALMODE_WAL && pPager->state!=PAGER_UNLOCK ){
- return (int)pPager->journalMode;
- }
-
pPager->journalMode = (u8)eMode;
}
return (int)pPager->journalMode;
return sqlite3LogCallback(pPager->pLog);
}
+/*
+** Open a connection to the write-ahead log file for pager pPager. If
+** the log connection is already open, this function is a no-op.
+**
+** The caller must be holding a SHARED lock on the database file to call
+** this function.
+*/
+int sqlite3PagerOpenLog(Pager *pPager, int *pisOpen){
+ int rc = SQLITE_OK; /* Return code */
+
+#ifdef SQLITE_DEBUG
+ int locktype;
+ sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_LOCKSTATE, &locktype);
+ assert( locktype==SQLITE_LOCK_SHARED );
+ assert( pPager->state>=PAGER_SHARED );
+#endif
+
+ if( !pPager->pLog ){
+
+ /* Open the connection to the log file. If this operation fails,
+ ** (e.g. due to malloc() failure), unlock the database file and
+ ** return an error code.
+ */
+ rc = sqlite3LogOpen(pPager->pVfs, pPager->zFilename, &pPager->pLog);
+ if( rc==SQLITE_OK ){
+ pPager->journalMode = PAGER_JOURNALMODE_WAL;
+ }
+ }else{
+ *pisOpen = 1;
+ }
+
+ return rc;
+}
+
+
+/*
+** This function is called to close the connection to the log file prior
+** to switching from WAL to rollback mode.
+**
+** Before closing the log file, this function attempts to take an
+** EXCLUSIVE lock on the database file. If this cannot be obtained, an
+** error (SQLITE_BUSY) is returned and the log connection is not closed.
+** If successful, the EXCLUSIVE lock is not released before returning.
+*/
+int sqlite3PagerCloseLog(Pager *pPager){
+ int rc = SQLITE_OK;
+ if( pPager->pLog ){
+
+ /* Try to obtain an EXCLUSIVE lock on the database file. */
+ rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
+
+ /* If the EXCLUSIVE lock was obtained, checkpoint and close the log. */
+ if( rc==SQLITE_OK ){
+ rc = sqlite3LogClose(pPager->pLog, pPager->fd,
+ (pPager->noSync ? 0 : pPager->sync_flags),
+ (u8*)pPager->pTmpSpace
+ );
+ pPager->pLog = 0;
+ }
+
+ /* Make sure the EXCLUSIVE lock has not been lost somehow */
+#ifdef SQLITE_DEBUG
+ {
+ int locktype;
+ sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_LOCKSTATE, &locktype);
+ assert( locktype==SQLITE_LOCK_EXCLUSIVE );
+ }
+#endif
+
+ }
+ return rc;
+}
+
#endif /* SQLITE_OMIT_DISKIO */
int sqlite3PagerCheckpoint(Pager *pPager);
int sqlite3PagerLogCallback(Pager *pPager);
+int sqlite3PagerOpenLog(Pager *pPager, int *pisOpen);
+int sqlite3PagerCloseLog(Pager *pPager);
/* Functions used to query pager state and configuration. */
u8 sqlite3PagerIsreadonly(Pager*);
}
#endif
+
+/*
+** Parameter eMode must be one of the PAGER_JOURNALMODE_XXX constants
+** defined in pager.h. This function returns the associated lowercase
+** journal-mode name.
+*/
+const char *sqlite3JournalModename(int eMode){
+ static char * const azModeName[] = {
+ "delete", "persist", "off", "truncate", "memory", "wal"
+ };
+ assert( PAGER_JOURNALMODE_DELETE==0 );
+ assert( PAGER_JOURNALMODE_PERSIST==1 );
+ assert( PAGER_JOURNALMODE_OFF==2 );
+ assert( PAGER_JOURNALMODE_TRUNCATE==3 );
+ assert( PAGER_JOURNALMODE_MEMORY==4 );
+ assert( PAGER_JOURNALMODE_WAL==5 );
+ assert( eMode>=0 && eMode<=ArraySize(azModeName) );
+
+ if( eMode==ArraySize(azModeName) ) return 0;
+ return azModeName[eMode];
+}
+
/*
** Process a pragma statement.
**
** PRAGMA [database.]journal_mode = (delete|persist|off|truncate|memory)
*/
if( sqlite3StrICmp(zLeft,"journal_mode")==0 ){
- int eMode;
- static char * const azModeName[] = {
- "delete", "persist", "off", "truncate", "memory", "wal"
- };
+ int eMode; /* One of the PAGER_JOURNALMODE_XXX symbols */
+
+ sqlite3VdbeSetNumCols(v, 1);
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "journal_mode", SQLITE_STATIC);
if( zRight==0 ){
eMode = PAGER_JOURNALMODE_QUERY;
}else{
+ const char *zMode;
int n = sqlite3Strlen30(zRight);
- eMode = sizeof(azModeName)/sizeof(azModeName[0]) - 1;
- while( eMode>=0 && sqlite3StrNICmp(zRight, azModeName[eMode], n)!=0 ){
- eMode--;
+ for(eMode=0; (zMode = sqlite3JournalModename(eMode)); eMode++){
+ if( sqlite3StrNICmp(zRight, zMode, n)==0 ) break;
+ }
+ if( !zMode ){
+ eMode = PAGER_JOURNALMODE_QUERY;
}
}
if( pId2->n==0 && eMode==PAGER_JOURNALMODE_QUERY ){
** the journal-mode of the main database).
*/
eMode = db->dfltJournalMode;
+ sqlite3VdbeAddOp2(v, OP_String8, 0, 1);
+ sqlite3VdbeChangeP4(v, -1, sqlite3JournalModename(eMode), P4_STATIC);
}else{
- Pager *pPager;
- if( pId2->n==0 ){
+ int ii;
+
+ if( pId2->n==0 && eMode!=PAGER_JOURNALMODE_WAL ){
/* This indicates that no database name was specified as part
** of the PRAGMA command. In this case the journal-mode must be
** set on all attached databases, as well as the main db file.
**
** Also, the sqlite3.dfltJournalMode variable is set so that
** any subsequently attached databases also use the specified
- ** journal mode.
+ ** journal mode. Except, the default journal mode is never set
+ ** to WAL.
*/
- int ii;
- assert(pDb==&db->aDb[0]);
- for(ii=1; ii<db->nDb; ii++){
- if( db->aDb[ii].pBt ){
- pPager = sqlite3BtreePager(db->aDb[ii].pBt);
- sqlite3PagerJournalMode(pPager, eMode);
- }
- }
db->dfltJournalMode = (u8)eMode;
}
- pPager = sqlite3BtreePager(pDb->pBt);
- eMode = sqlite3PagerJournalMode(pPager, eMode);
+
+ for(ii=db->nDb-1; ii>=0; ii--){
+ if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){
+ sqlite3VdbeUsesBtree(v, ii);
+ sqlite3VdbeAddOp3(v, OP_JournalMode, ii, 1, eMode);
+ }
+ }
}
- 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 );
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "journal_mode", SQLITE_STATIC);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0,
- azModeName[eMode], P4_STATIC);
+
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
}else
}
/* Opcode: Checkpoint P1 * * * *
+**
+** Checkpoint database P1. This is a no-op if P1 is not currently in
+** WAL mode.
*/
case OP_Checkpoint: {
Btree *pBt; /* Btree to checkpoint */
break;
};
+/* Opcode: JournalMode P1 P2 P3 * *
+**
+** Change the journal mode of database P1 to P3. P3 must be one of the
+** PAGER_JOURNALMODE_XXX values. If changing between the various rollback
+** modes (delete, truncate, persist, off and memory), this is a simple
+** operation. No IO is required.
+**
+** If changing into or out of WAL mode the procedure is more complicated.
+**
+** Write a string containing the final journal-mode to register P2.
+*/
+case OP_JournalMode: {
+ Btree *pBt; /* Btree to change journal mode of */
+ Pager *pPager; /* Pager associated with pBt */
+ int eNew = pOp->p3; /* New journal mode */
+
+ assert( eNew==PAGER_JOURNALMODE_DELETE
+ || eNew==PAGER_JOURNALMODE_TRUNCATE
+ || eNew==PAGER_JOURNALMODE_PERSIST
+ || eNew==PAGER_JOURNALMODE_OFF
+ || eNew==PAGER_JOURNALMODE_MEMORY
+ || eNew==PAGER_JOURNALMODE_WAL
+ || eNew==PAGER_JOURNALMODE_QUERY
+ );
+ assert( pOp->p1>=0 && pOp->p1<db->nDb );
+ assert( (p->btreeMask & (1<<pOp->p1))!=0 );
+
+ pBt = db->aDb[pOp->p1].pBt;
+ pPager = sqlite3BtreePager(pBt);
+
+ if( eNew!=PAGER_JOURNALMODE_QUERY ){
+ int eOld = sqlite3PagerJournalMode(pPager, PAGER_JOURNALMODE_QUERY);
+ if( (eNew!=eOld)
+ && (eOld==PAGER_JOURNALMODE_WAL || eNew==PAGER_JOURNALMODE_WAL)
+ ){
+ if( !db->autoCommit || db->activeVdbeCnt>1 ){
+ rc = SQLITE_ERROR;
+ sqlite3SetString(&p->zErrMsg, db,
+ "cannot change %s wal mode from within a transaction",
+ (eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of")
+ );
+ }else{
+
+ /* If leaving WAL mode, close the log file. If successful, the call to
+ ** PagerCloseLog() checkpoints and deletes the write-ahead-log file.
+ ** An EXCLUSIVE lock is still held on the database file after returning.
+ */
+ if( eOld==PAGER_JOURNALMODE_WAL ){
+ rc = sqlite3PagerCloseLog(pPager);
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
+ sqlite3PagerJournalMode(pPager, eNew);
+ }else{
+ sqlite3PagerJournalMode(pPager, PAGER_JOURNALMODE_DELETE);
+ }
+
+ /* Open a transaction on the database file. Regardless of the journal
+ ** mode, this transaction always uses a rollback journal.
+ */
+ assert( sqlite3BtreeIsInTrans(pBt)==0 );
+ rc = sqlite3BtreeBeginTrans(pBt, 2);
+ assert( rc==SQLITE_OK || eOld!=PAGER_JOURNALMODE_WAL );
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
+ rc = sqlite3BtreeSetVersion(pBt, (eNew==PAGER_JOURNALMODE_WAL ? 2 : 1));
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
+ }
+ }
+ }
+
+ eNew = sqlite3PagerJournalMode(pPager, eNew);
+ pOut = &aMem[pOp->p2];
+ pOut->flags = MEM_Str|MEM_Static|MEM_Term;
+ pOut->z = sqlite3JournalModename(eNew);
+ pOut->n = sqlite3Strlen30(pOut->z);
+ pOut->enc = SQLITE_UTF8;
+ sqlite3VdbeChangeEncoding(pOut, encoding);
+ break;
+};
+
#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
/* Opcode: Vacuum * * * * *
**
proc sqlite3_wal {args} {
eval sqlite3 $args
+ [lindex $args 0] eval { PRAGMA page_size = 1024 }
[lindex $args 0] eval { PRAGMA journal_mode = wal }
[lindex $args 0] eval { PRAGMA synchronous = normal }
[lindex $args 0] function blob blob
execsql { PRAGMA synchronous = normal }
execsql { PRAGMA journal_mode = wal }
} {wal}
+do_test wal-0.2 {
+ file size test.db
+} {1024}
do_test wal-1.0 {
execsql {
BEGIN;
CREATE TABLE t1(a, b);
}
- list [file exists test.db-journal] [file exists test.db-wal]
-} {0 1}
+ list [file exists test.db-journal] \
+ [file exists test.db-wal] \
+ [file size test.db]
+} {0 1 1024}
do_test wal-1.1 {
execsql COMMIT
list [file exists test.db-journal] [file exists test.db-wal]
foreach pgsz {512 1024 2048 4096} {
file delete -force test.db test.db-wal
do_test wal-6.$sector.$pgsz.1 {
- sqlite3_wal db test.db -vfs devsym
+ sqlite3 db test.db -vfs devsym
execsql "
- PRAGMA page_size = $pgsz ;
+ PRAGMA page_size = $pgsz;
+ PRAGMA journal_mode = wal;
"
execsql "
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES(1, 2);
}
list [file size test.db] [file size test.db-wal]
-} [list 0 [log_file_size 3 1024]]
+} [list 1024 [log_file_size 3 1024]]
do_test wal-7.2 {
execsql { PRAGMA checkpoint }
list [file size test.db] [file size test.db-wal]
#
do_test wal-8.1 {
reopen_db
+ catch { db close }
+ file delete -force test.db test.db-wal
+
+ sqlite3 db test.db
+ db function blob blob
execsql {
PRAGMA auto_vacuum = 1;
+ PRAGMA journal_mode = wal;
PRAGMA auto_vacuum;
}
-} {1}
+} {wal 1}
do_test wal-8.2 {
execsql {
PRAGMA page_size = 1024;
do_test wal-9.1 {
reopen_db
execsql {
- PRAGMA page_size = 1024;
CREATE TABLE t1(x PRIMARY KEY);
INSERT INTO t1 VALUES(blob(900));
INSERT INTO t1 VALUES(blob(900));
INSERT INTO t1 SELECT blob(900) FROM t1; /* 256 */
}
file size test.db
-} 0
+} 1024
do_test wal-9.2 {
sqlite3_wal db2 test.db
execsql {PRAGMA integrity_check } db2
CREATE TABLE t1(x PRIMARY KEY);
}
list [expr [file size test.db]/1024] [expr [file size test.db-wal]/1044]
-} {0 3}
+} {1 3}
do_test wal-11.2 {
execsql { PRAGMA checkpoint }
list [expr [file size test.db]/1024] [file size test.db-wal]
SELECT count(*) FROM t1;
}
list [expr [file size test.db]/1024] [file size test.db-wal]
-} [list 37 [log_file_size 35 1024]]
+} [list 37 [log_file_size 37 1024]]
do_test wal-11.11 {
execsql {
SELECT count(*) FROM t1;
} {32 16}
do_test wal-11.12 {
list [expr [file size test.db]/1024] [file size test.db-wal]
-} [list 37 [log_file_size 35 1024]]
+} [list 37 [log_file_size 37 1024]]
do_test wal-11.13 {
execsql {
INSERT INTO t1 VALUES( blob(900) );
} {17 ok}
do_test wal-11.14 {
list [expr [file size test.db]/1024] [file size test.db-wal]
-} [list 37 [log_file_size 35 1024]]
+} [list 37 [log_file_size 37 1024]]
#-------------------------------------------------------------------------
INSERT INTO t1 VALUES('A', 1);
}
list [expr [file size test.db]/1024] [file size test.db-wal]
-} [list 0 [log_file_size 5 1024]]
+} [list 1 [log_file_size 5 1024]]
do_test wal-12.2 {
db close
- sqlite3_wal db test.db
+ sqlite3 db test.db
execsql {
+ PRAGMA synchronous = normal;
UPDATE t1 SET y = 0 WHERE x = 'A';
}
list [expr [file size test.db]/1024] [expr [file size test.db-wal]/1044]
file copy -force test.db test2.db
file copy -force test.db-wal test2.db-wal
sqlite3_wal db2 test2.db
-breakpoint
execsql { SELECT * FROM t2 } db2
} {B 1}
db2 close
} {B 2}
db2 close
-
finish_test
--- /dev/null
+# 2010 April 19
+#
+# The author disclaims copyright to this source code. In place of
+# a legal notice, here is a blessing:
+#
+# May you do good and not evil.
+# May you find forgiveness for yourself and forgive others.
+# May you share freely, never taking more than you give.
+#
+#***********************************************************************
+# This file implements regression tests for SQLite library. The
+# focus of this file is testing the operation of the library in
+# "PRAGMA journal_mode=WAL" mode.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+do_test walmode-1.1 {
+ execsql {
+ PRAGMA journal_mode = wal;
+ }
+} {wal}
+
+finish_test