mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-01 06:27:03 +03:00
Add "pragma journal_mode=memory". Change the way rollback works for in-memory databases so that it reuses the journal_mode=memory code. (CVS 5830)
FossilOrigin-Name: 39ebf01addf9d0867daafd06a38719e725128f9c
This commit is contained in:
2
main.mk
2
main.mk
@ -57,6 +57,7 @@ LIBOBJ+= alter.o analyze.o attach.o auth.o \
|
|||||||
func.o global.o hash.o \
|
func.o global.o hash.o \
|
||||||
icu.o insert.o journal.o legacy.o loadext.o \
|
icu.o insert.o journal.o legacy.o loadext.o \
|
||||||
main.o malloc.o mem1.o mem2.o mem3.o mem4.o mem5.o mem6.o \
|
main.o malloc.o mem1.o mem2.o mem3.o mem4.o mem5.o mem6.o \
|
||||||
|
memjournal.o \
|
||||||
mutex.o mutex_noop.o mutex_os2.o mutex_unix.o mutex_w32.o \
|
mutex.o mutex_noop.o mutex_os2.o mutex_unix.o mutex_w32.o \
|
||||||
opcodes.o os.o os_os2.o os_unix.o os_win.o \
|
opcodes.o os.o os_os2.o os_unix.o os_win.o \
|
||||||
pager.o parse.o pcache.o pragma.o prepare.o printf.o \
|
pager.o parse.o pcache.o pragma.o prepare.o printf.o \
|
||||||
@ -104,6 +105,7 @@ SRC = \
|
|||||||
$(TOP)/src/mem4.c \
|
$(TOP)/src/mem4.c \
|
||||||
$(TOP)/src/mem5.c \
|
$(TOP)/src/mem5.c \
|
||||||
$(TOP)/src/mem6.c \
|
$(TOP)/src/mem6.c \
|
||||||
|
$(TOP)/src/memjournal.c \
|
||||||
$(TOP)/src/mutex.c \
|
$(TOP)/src/mutex.c \
|
||||||
$(TOP)/src/mutex.h \
|
$(TOP)/src/mutex.h \
|
||||||
$(TOP)/src/mutex_noop.c \
|
$(TOP)/src/mutex_noop.c \
|
||||||
|
38
manifest
38
manifest
@ -1,5 +1,5 @@
|
|||||||
C Fix\sa\stypo\sin\sdocumentation.\s\sTicket\s#3447.\s(CVS\s5829)
|
C Add\s"pragma\sjournal_mode=memory".\sChange\sthe\sway\srollback\sworks\sfor\sin-memory\sdatabases\sso\sthat\sit\sreuses\sthe\sjournal_mode=memory\scode.\s(CVS\s5830)
|
||||||
D 2008-10-17T15:10:37
|
D 2008-10-17T18:51:52
|
||||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||||
F Makefile.in 2014e5a4010ad5ebbcaedff98240b3d14ee83838
|
F Makefile.in 2014e5a4010ad5ebbcaedff98240b3d14ee83838
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@ -79,7 +79,7 @@ F ext/rtree/tkt3363.test 6662237ea75bb431cd5d262dfc9535e1023315fc
|
|||||||
F ext/rtree/viewrtree.tcl 09526398dae87a5a87c5aac2b3854dbaf8376869
|
F ext/rtree/viewrtree.tcl 09526398dae87a5a87c5aac2b3854dbaf8376869
|
||||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
|
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
|
||||||
F ltmain.sh 09fe5815427dc7d0abb188bbcdf0e34896577210
|
F ltmain.sh 09fe5815427dc7d0abb188bbcdf0e34896577210
|
||||||
F main.mk 725b8b0ee2c1a7e53adb172984c43165eca61be1
|
F main.mk c0baa7e57584ce3666a854015ad8743c5fe38dec
|
||||||
F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a
|
F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a
|
||||||
F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
|
F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
|
||||||
F mkextw.sh 4123480947681d9b434a5e7b1ee08135abe409ac
|
F mkextw.sh 4123480947681d9b434a5e7b1ee08135abe409ac
|
||||||
@ -138,12 +138,12 @@ F src/os_common.h 24525d8b7bce66c374dfc1810a6c9043f3359b60
|
|||||||
F src/os_os2.c 24221ff5ab20cf3472e3ec7eec595f759de55298
|
F src/os_os2.c 24221ff5ab20cf3472e3ec7eec595f759de55298
|
||||||
F src/os_unix.c 5e3b3c9a54546249c1317cff5343e965192f7f2b
|
F src/os_unix.c 5e3b3c9a54546249c1317cff5343e965192f7f2b
|
||||||
F src/os_win.c 13bed718f62d64031b17bb3685adcf994dbf0232
|
F src/os_win.c 13bed718f62d64031b17bb3685adcf994dbf0232
|
||||||
F src/pager.c d98f56128e849083f2f612196efebd982c491fea
|
F src/pager.c fd11076a5a2f46a831688f036f03c57bd730dff5
|
||||||
F src/pager.h 9c1917be28fff58118e1fe0ddbc7adfb8dd4f44d
|
F src/pager.h 4a57b219c0765fe1870238064e3f46e4eb2cf5af
|
||||||
F src/parse.y f4620f42b5e0141e20243b5f963d0fc9c180ab9b
|
F src/parse.y f4620f42b5e0141e20243b5f963d0fc9c180ab9b
|
||||||
F src/pcache.c f8d7beceba164a34441ac37e88abb3a404f968a7
|
F src/pcache.c 5b80676e664019c1ebc8356cc25332dd69da6269
|
||||||
F src/pcache.h 974d8ba609c7069af7c050cd3de698cadd090405
|
F src/pcache.h 2caf2deb6cbaa75c423b8b96fc1411069ee77c75
|
||||||
F src/pragma.c f0f48d0d50e9d8fa785178fc2410244c06f6a287
|
F src/pragma.c 10d61f211d819acd97174a41acc56394bd5bde7e
|
||||||
F src/prepare.c c7e00ed1b0bdcf699b1aad651247d4dc3d281b0b
|
F src/prepare.c c7e00ed1b0bdcf699b1aad651247d4dc3d281b0b
|
||||||
F src/printf.c 785f87120589c1db672e37c6eb1087c456e6f84d
|
F src/printf.c 785f87120589c1db672e37c6eb1087c456e6f84d
|
||||||
F src/random.c a87afbd598aa877e23ac676ee92fd8ee5c786a51
|
F src/random.c a87afbd598aa877e23ac676ee92fd8ee5c786a51
|
||||||
@ -152,7 +152,7 @@ F src/select.c d910d7350df0d918e22286c5bfd39d4ea68ec813
|
|||||||
F src/shell.c d83b578a8ccdd3e0e7fef4388a0887ce9f810967
|
F src/shell.c d83b578a8ccdd3e0e7fef4388a0887ce9f810967
|
||||||
F src/sqlite.h.in ee95eeed2196e5fa98fdad007301b8d5d3733b6d
|
F src/sqlite.h.in ee95eeed2196e5fa98fdad007301b8d5d3733b6d
|
||||||
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
|
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
|
||||||
F src/sqliteInt.h 69ad0023756cc738d2a5f9def8a0b21d90350667
|
F src/sqliteInt.h e5e3909f565fb020a820ccce11abca040902f075
|
||||||
F src/sqliteLimit.h f435e728c6b620ef7312814d660a81f9356eb5c8
|
F src/sqliteLimit.h f435e728c6b620ef7312814d660a81f9356eb5c8
|
||||||
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
|
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
|
||||||
F src/table.c 22744786199c9195720c15a7a42cb97b2e2728d8
|
F src/table.c 22744786199c9195720c15a7a42cb97b2e2728d8
|
||||||
@ -393,7 +393,7 @@ F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
|
|||||||
F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
|
F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
|
||||||
F test/join5.test 86675fc2919269aa923c84dd00ee4249b97990fe
|
F test/join5.test 86675fc2919269aa923c84dd00ee4249b97990fe
|
||||||
F test/journal1.test 36f2d1bb9bf03f790f43fbdb439e44c0657fab19
|
F test/journal1.test 36f2d1bb9bf03f790f43fbdb439e44c0657fab19
|
||||||
F test/jrnlmode.test 54469696db41e185a37aed3b3848998cca4e0c37
|
F test/jrnlmode.test c2e8212a6f6d32f8fd8f869b93553154eaf2244c
|
||||||
F test/lastinsert.test 474d519c68cb79d07ecae56a763aa7f322c72f51
|
F test/lastinsert.test 474d519c68cb79d07ecae56a763aa7f322c72f51
|
||||||
F test/laststmtchanges.test 18ead86c8a87ade949a1d5658f6dc4bb111d1b02
|
F test/laststmtchanges.test 18ead86c8a87ade949a1d5658f6dc4bb111d1b02
|
||||||
F test/like.test fef924922828d5a2a5bff80b9bdd9ff57a1ca500
|
F test/like.test fef924922828d5a2a5bff80b9bdd9ff57a1ca500
|
||||||
@ -450,14 +450,14 @@ F test/nan.test c627d79b3d36ea892563fd67584b3e8a18f0618a
|
|||||||
F test/notnull.test 44d600f916b770def8b095a9962dbe3be5a70d82
|
F test/notnull.test 44d600f916b770def8b095a9962dbe3be5a70d82
|
||||||
F test/null.test a8b09b8ed87852742343b33441a9240022108993
|
F test/null.test a8b09b8ed87852742343b33441a9240022108993
|
||||||
F test/openv2.test f5dd6b23e4dce828eb211649b600763c42a668df
|
F test/openv2.test f5dd6b23e4dce828eb211649b600763c42a668df
|
||||||
F test/pager.test 1e1832795e9e07a359c959ffdddcf7275a88f54c
|
F test/pager.test fd3f5009985728ef7bf0dfe32a1bbc112e6895c5
|
||||||
F test/pager2.test 070983b89a308adaba525a2f9c1ba0592c72fa3d
|
F test/pager2.test d84c59ae4a803e03d19d72cbb5b14c71850c6163
|
||||||
F test/pager3.test 2323bf27fd5bd887b580247e5bce500ceee994b4
|
F test/pager3.test 2323bf27fd5bd887b580247e5bce500ceee994b4
|
||||||
F test/pageropt.test 3ee6578891baaca967f0bd349e4abfa736229e1a
|
F test/pageropt.test 3ee6578891baaca967f0bd349e4abfa736229e1a
|
||||||
F test/pagesize.test 0d9ff3fedfce6e5ffe8fa7aca9b6d3433a2e843b
|
F test/pagesize.test 0d9ff3fedfce6e5ffe8fa7aca9b6d3433a2e843b
|
||||||
F test/pcache.test 515b4c26e9f57660357dfff5b6b697acac1abc5f
|
F test/pcache.test 515b4c26e9f57660357dfff5b6b697acac1abc5f
|
||||||
F test/pcache2.test e2260293e892190be65de89526dbc4f92c8b5a7c
|
F test/pcache2.test e2260293e892190be65de89526dbc4f92c8b5a7c
|
||||||
F test/permutations.test a80a319ed2e825fa828af086d322b47fc9d9c664
|
F test/permutations.test 3f24cf55e9646b138a6980f78f18190f318af9a3
|
||||||
F test/pragma.test 583937903d01cad823ae195573d90c02ea945717
|
F test/pragma.test 583937903d01cad823ae195573d90c02ea945717
|
||||||
F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47
|
F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47
|
||||||
F test/printf.test 262a5acd3158f788e9bdf7f18d718f3af32ff6ef
|
F test/printf.test 262a5acd3158f788e9bdf7f18d718f3af32ff6ef
|
||||||
@ -467,7 +467,7 @@ F test/quick.test 70695607082b3e1ca54023b2c856991604b07703
|
|||||||
F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6
|
F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6
|
||||||
F test/rdonly.test bd054831f8a3078e765a0657e247182486f0cb47
|
F test/rdonly.test bd054831f8a3078e765a0657e247182486f0cb47
|
||||||
F test/reindex.test 44edd3966b474468b823d481eafef0c305022254
|
F test/reindex.test 44edd3966b474468b823d481eafef0c305022254
|
||||||
F test/rollback.test d67022e8f99fdb1f115de7e8ea65139263b4bd40
|
F test/rollback.test 1f70ab4301d8d105d41438a436cad1fc8897f5e5
|
||||||
F test/rowid.test 1c8fc43c60d273e6ea44dfb992db587f3164312c
|
F test/rowid.test 1c8fc43c60d273e6ea44dfb992db587f3164312c
|
||||||
F test/rtree.test b85fd4f0861a40ca366ac195e363be2528dcfadf
|
F test/rtree.test b85fd4f0861a40ca366ac195e363be2528dcfadf
|
||||||
F test/safety.test b69e2b2dd5d52a3f78e216967086884bbc1a09c6
|
F test/safety.test b69e2b2dd5d52a3f78e216967086884bbc1a09c6
|
||||||
@ -633,7 +633,7 @@ F tool/memleak3.tcl 7707006ee908cffff210c98158788d85bb3fcdbf
|
|||||||
F tool/mkkeywordhash.c c219ee2b8b5b8e7011cccfa1caec62d9812e82e7
|
F tool/mkkeywordhash.c c219ee2b8b5b8e7011cccfa1caec62d9812e82e7
|
||||||
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x
|
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x
|
||||||
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
|
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
|
||||||
F tool/mksqlite3c.tcl 8aff2d49beb7d94a63841e86f3ffd4770e5054aa
|
F tool/mksqlite3c.tcl ab98a8321f292b4871e362bb4435be234993d46b
|
||||||
F tool/mksqlite3internalh.tcl 7b43894e21bcb1bb39e11547ce7e38a063357e87
|
F tool/mksqlite3internalh.tcl 7b43894e21bcb1bb39e11547ce7e38a063357e87
|
||||||
F tool/omittest.tcl 27d6f6e3b1e95aeb26a1c140e6eb57771c6d794a
|
F tool/omittest.tcl 27d6f6e3b1e95aeb26a1c140e6eb57771c6d794a
|
||||||
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
|
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
|
||||||
@ -648,7 +648,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
|||||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
P 8065a92f705dfa04863ba4a828f5bd2803901be8
|
P 5ce2ddffea807d45318619cc9e259a99dfa14346
|
||||||
R 4bd0b87e5fdde7ed86abc759091ffc21
|
R d3d208ea9f507cd99d0a55a9424ad33c
|
||||||
U drh
|
U danielk1977
|
||||||
Z 9251407651b2b71ae84b77628eaaa866
|
Z e1e732a777069a84074d19c41d686a93
|
||||||
|
@ -1 +1 @@
|
|||||||
5ce2ddffea807d45318619cc9e259a99dfa14346
|
39ebf01addf9d0867daafd06a38719e725128f9c
|
681
src/pager.c
681
src/pager.c
@ -18,7 +18,7 @@
|
|||||||
** file simultaneously, or one process from reading the database while
|
** file simultaneously, or one process from reading the database while
|
||||||
** another is writing.
|
** another is writing.
|
||||||
**
|
**
|
||||||
** @(#) $Id: pager.c,v 1.497 2008/10/07 11:51:20 danielk1977 Exp $
|
** @(#) $Id: pager.c,v 1.498 2008/10/17 18:51:52 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef SQLITE_OMIT_DISKIO
|
#ifndef SQLITE_OMIT_DISKIO
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
@ -309,11 +309,7 @@ static const unsigned char aJournalMagic[] = {
|
|||||||
*/
|
*/
|
||||||
static int pageInStatement(PgHdr *pPg){
|
static int pageInStatement(PgHdr *pPg){
|
||||||
Pager *pPager = pPg->pPager;
|
Pager *pPager = pPg->pPager;
|
||||||
if( MEMDB ){
|
return sqlite3BitvecTest(pPager->pInStmt, pPg->pgno);
|
||||||
return pPg->apSave[1]!=0;
|
|
||||||
}else{
|
|
||||||
return sqlite3BitvecTest(pPager->pInStmt, pPg->pgno);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -470,7 +466,7 @@ static u32 pager_set_pagehash(PgHdr *pPage){
|
|||||||
#define CHECK_PAGE(x) checkPage(x)
|
#define CHECK_PAGE(x) checkPage(x)
|
||||||
static void checkPage(PgHdr *pPg){
|
static void checkPage(PgHdr *pPg){
|
||||||
Pager *pPager = pPg->pPager;
|
Pager *pPager = pPg->pPager;
|
||||||
assert( !pPg->pageHash || pPager->errCode || MEMDB
|
assert( !pPg->pageHash || pPager->errCode
|
||||||
|| (pPg->flags&PGHDR_DIRTY) || pPg->pageHash==pager_pagehash(pPg) );
|
|| (pPg->flags&PGHDR_DIRTY) || pPg->pageHash==pager_pagehash(pPg) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -664,7 +660,7 @@ static int writeJournalHdr(Pager *pPager){
|
|||||||
** that garbage data is never appended to the journal file.
|
** that garbage data is never appended to the journal file.
|
||||||
*/
|
*/
|
||||||
assert(pPager->fd->pMethods||pPager->noSync);
|
assert(pPager->fd->pMethods||pPager->noSync);
|
||||||
if( (pPager->noSync)
|
if( (pPager->noSync) || (pPager->journalMode==PAGER_JOURNALMODE_MEMORY)
|
||||||
|| (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND)
|
|| (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND)
|
||||||
){
|
){
|
||||||
put32bits(&zHeader[sizeof(aJournalMagic)], 0xffffffff);
|
put32bits(&zHeader[sizeof(aJournalMagic)], 0xffffffff);
|
||||||
@ -796,7 +792,8 @@ static int writeMasterJournal(Pager *pPager, const char *zMaster){
|
|||||||
u32 cksum = 0;
|
u32 cksum = 0;
|
||||||
char zBuf[sizeof(aJournalMagic)+2*4];
|
char zBuf[sizeof(aJournalMagic)+2*4];
|
||||||
|
|
||||||
if( !zMaster || pPager->setMaster) return SQLITE_OK;
|
if( !zMaster || pPager->setMaster ) return SQLITE_OK;
|
||||||
|
if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ) return SQLITE_OK;
|
||||||
pPager->setMaster = 1;
|
pPager->setMaster = 1;
|
||||||
|
|
||||||
len = strlen(zMaster);
|
len = strlen(zMaster);
|
||||||
@ -880,50 +877,46 @@ static void pager_reset(Pager *pPager){
|
|||||||
*/
|
*/
|
||||||
static void pager_unlock(Pager *pPager){
|
static void pager_unlock(Pager *pPager){
|
||||||
if( !pPager->exclusiveMode ){
|
if( !pPager->exclusiveMode ){
|
||||||
if( !MEMDB ){
|
int rc = osUnlock(pPager->fd, NO_LOCK);
|
||||||
int rc = osUnlock(pPager->fd, NO_LOCK);
|
if( rc ) pPager->errCode = rc;
|
||||||
if( rc ) pPager->errCode = rc;
|
pPager->dbSize = -1;
|
||||||
pPager->dbSize = -1;
|
IOTRACE(("UNLOCK %p\n", pPager))
|
||||||
IOTRACE(("UNLOCK %p\n", pPager))
|
|
||||||
|
|
||||||
/* Always close the journal file when dropping the database lock.
|
/* Always close the journal file when dropping the database lock.
|
||||||
** Otherwise, another connection with journal_mode=delete might
|
** Otherwise, another connection with journal_mode=delete might
|
||||||
** delete the file out from under us.
|
** delete the file out from under us.
|
||||||
*/
|
*/
|
||||||
if( pPager->journalOpen ){
|
if( pPager->journalOpen ){
|
||||||
sqlite3OsClose(pPager->jfd);
|
sqlite3OsClose(pPager->jfd);
|
||||||
pPager->journalOpen = 0;
|
pPager->journalOpen = 0;
|
||||||
sqlite3BitvecDestroy(pPager->pInJournal);
|
sqlite3BitvecDestroy(pPager->pInJournal);
|
||||||
pPager->pInJournal = 0;
|
pPager->pInJournal = 0;
|
||||||
sqlite3BitvecDestroy(pPager->pAlwaysRollback);
|
sqlite3BitvecDestroy(pPager->pAlwaysRollback);
|
||||||
pPager->pAlwaysRollback = 0;
|
pPager->pAlwaysRollback = 0;
|
||||||
}
|
|
||||||
|
|
||||||
/* If Pager.errCode is set, the contents of the pager cache cannot be
|
|
||||||
** trusted. Now that the pager file is unlocked, the contents of the
|
|
||||||
** cache can be discarded and the error code safely cleared.
|
|
||||||
*/
|
|
||||||
if( pPager->errCode ){
|
|
||||||
if( rc==SQLITE_OK ) pPager->errCode = SQLITE_OK;
|
|
||||||
pager_reset(pPager);
|
|
||||||
if( pPager->stmtOpen ){
|
|
||||||
sqlite3OsClose(pPager->stfd);
|
|
||||||
sqlite3BitvecDestroy(pPager->pInStmt);
|
|
||||||
pPager->pInStmt = 0;
|
|
||||||
}
|
|
||||||
pPager->stmtOpen = 0;
|
|
||||||
pPager->stmtInUse = 0;
|
|
||||||
pPager->journalOff = 0;
|
|
||||||
pPager->journalStarted = 0;
|
|
||||||
pPager->stmtAutoopen = 0;
|
|
||||||
pPager->origDbSize = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !MEMDB || pPager->errCode==SQLITE_OK ){
|
/* If Pager.errCode is set, the contents of the pager cache cannot be
|
||||||
pPager->state = PAGER_UNLOCK;
|
** trusted. Now that the pager file is unlocked, the contents of the
|
||||||
pPager->changeCountDone = 0;
|
** cache can be discarded and the error code safely cleared.
|
||||||
|
*/
|
||||||
|
if( pPager->errCode ){
|
||||||
|
if( rc==SQLITE_OK ) pPager->errCode = SQLITE_OK;
|
||||||
|
pager_reset(pPager);
|
||||||
|
if( pPager->stmtOpen ){
|
||||||
|
sqlite3OsClose(pPager->stfd);
|
||||||
|
sqlite3BitvecDestroy(pPager->pInStmt);
|
||||||
|
pPager->pInStmt = 0;
|
||||||
|
}
|
||||||
|
pPager->stmtOpen = 0;
|
||||||
|
pPager->stmtInUse = 0;
|
||||||
|
pPager->journalOff = 0;
|
||||||
|
pPager->journalStarted = 0;
|
||||||
|
pPager->stmtAutoopen = 0;
|
||||||
|
pPager->origDbSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pPager->state = PAGER_UNLOCK;
|
||||||
|
pPager->changeCountDone = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -961,7 +954,6 @@ static void pagerUnlockAndRollback(Pager *p){
|
|||||||
static int pager_end_transaction(Pager *pPager, int hasMaster){
|
static int pager_end_transaction(Pager *pPager, int hasMaster){
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
int rc2 = SQLITE_OK;
|
int rc2 = SQLITE_OK;
|
||||||
assert( !MEMDB );
|
|
||||||
if( pPager->state<PAGER_RESERVED ){
|
if( pPager->state<PAGER_RESERVED ){
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
@ -971,7 +963,14 @@ static int pager_end_transaction(Pager *pPager, int hasMaster){
|
|||||||
pPager->stmtOpen = 0;
|
pPager->stmtOpen = 0;
|
||||||
}
|
}
|
||||||
if( pPager->journalOpen ){
|
if( pPager->journalOpen ){
|
||||||
if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE
|
if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){
|
||||||
|
int isMemoryJournal = sqlite3IsMemJournal(pPager->jfd);
|
||||||
|
sqlite3OsClose(pPager->jfd);
|
||||||
|
pPager->journalOpen = 0;
|
||||||
|
if( !isMemoryJournal ){
|
||||||
|
rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
|
||||||
|
}
|
||||||
|
}else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE
|
||||||
&& (rc = sqlite3OsTruncate(pPager->jfd, 0))==SQLITE_OK ){
|
&& (rc = sqlite3OsTruncate(pPager->jfd, 0))==SQLITE_OK ){
|
||||||
pPager->journalOff = 0;
|
pPager->journalOff = 0;
|
||||||
pPager->journalStarted = 0;
|
pPager->journalStarted = 0;
|
||||||
@ -1017,7 +1016,9 @@ static int pager_end_transaction(Pager *pPager, int hasMaster){
|
|||||||
pPager->setMaster = 0;
|
pPager->setMaster = 0;
|
||||||
pPager->needSync = 0;
|
pPager->needSync = 0;
|
||||||
/* lruListSetFirstSynced(pPager); */
|
/* lruListSetFirstSynced(pPager); */
|
||||||
pPager->dbSize = -1;
|
if( !MEMDB ){
|
||||||
|
pPager->dbSize = -1;
|
||||||
|
}
|
||||||
pPager->dbModified = 0;
|
pPager->dbModified = 0;
|
||||||
|
|
||||||
return (rc==SQLITE_OK?rc2:rc);
|
return (rc==SQLITE_OK?rc2:rc);
|
||||||
@ -1667,7 +1668,7 @@ void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){
|
|||||||
*/
|
*/
|
||||||
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
|
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
|
||||||
void sqlite3PagerSetSafetyLevel(Pager *pPager, int level, int bFullFsync){
|
void sqlite3PagerSetSafetyLevel(Pager *pPager, int level, int bFullFsync){
|
||||||
pPager->noSync = level==1 || pPager->tempFile || MEMDB;
|
pPager->noSync = level==1 || pPager->tempFile;
|
||||||
pPager->fullSync = level==3 && !pPager->tempFile;
|
pPager->fullSync = level==3 && !pPager->tempFile;
|
||||||
pPager->sync_flags = (bFullFsync?SQLITE_SYNC_FULL:SQLITE_SYNC_NORMAL);
|
pPager->sync_flags = (bFullFsync?SQLITE_SYNC_FULL:SQLITE_SYNC_NORMAL);
|
||||||
if( pPager->noSync ) pPager->needSync = 0;
|
if( pPager->noSync ) pPager->needSync = 0;
|
||||||
@ -1741,12 +1742,18 @@ int sqlite3PagerOpen(
|
|||||||
int readOnly = 0;
|
int readOnly = 0;
|
||||||
int useJournal = (flags & PAGER_OMIT_JOURNAL)==0;
|
int useJournal = (flags & PAGER_OMIT_JOURNAL)==0;
|
||||||
int noReadlock = (flags & PAGER_NO_READLOCK)!=0;
|
int noReadlock = (flags & PAGER_NO_READLOCK)!=0;
|
||||||
int journalFileSize = sqlite3JournalSize(pVfs);
|
int journalFileSize;
|
||||||
int pcacheSize = sqlite3PcacheSize();
|
int pcacheSize = sqlite3PcacheSize();
|
||||||
int szPageDflt = SQLITE_DEFAULT_PAGE_SIZE;
|
int szPageDflt = SQLITE_DEFAULT_PAGE_SIZE;
|
||||||
char *zPathname = 0;
|
char *zPathname = 0;
|
||||||
int nPathname = 0;
|
int nPathname = 0;
|
||||||
|
|
||||||
|
if( sqlite3JournalSize(pVfs)>sqlite3MemJournalSize() ){
|
||||||
|
journalFileSize = sqlite3JournalSize(pVfs);
|
||||||
|
}else{
|
||||||
|
journalFileSize = sqlite3MemJournalSize();
|
||||||
|
}
|
||||||
|
|
||||||
/* The default return is a NULL pointer */
|
/* The default return is a NULL pointer */
|
||||||
*ppPager = 0;
|
*ppPager = 0;
|
||||||
|
|
||||||
@ -1764,7 +1771,6 @@ int sqlite3PagerOpen(
|
|||||||
if( strcmp(zFilename,":memory:")==0 ){
|
if( strcmp(zFilename,":memory:")==0 ){
|
||||||
memDb = 1;
|
memDb = 1;
|
||||||
zPathname[0] = 0;
|
zPathname[0] = 0;
|
||||||
useJournal = 0;
|
|
||||||
}else
|
}else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
@ -1782,7 +1788,8 @@ int sqlite3PagerOpen(
|
|||||||
sizeof(*pPager) + /* Pager structure */
|
sizeof(*pPager) + /* Pager structure */
|
||||||
pcacheSize + /* PCache object */
|
pcacheSize + /* PCache object */
|
||||||
journalFileSize + /* The journal file structure */
|
journalFileSize + /* The journal file structure */
|
||||||
pVfs->szOsFile * 3 + /* The main db and two journal files */
|
pVfs->szOsFile + /* The main db file */
|
||||||
|
journalFileSize * 2 + /* The two journal files */
|
||||||
3*nPathname + 40 /* zFilename, zDirectory, zJournal */
|
3*nPathname + 40 /* zFilename, zDirectory, zJournal */
|
||||||
);
|
);
|
||||||
if( !pPager ){
|
if( !pPager ){
|
||||||
@ -1793,9 +1800,9 @@ int sqlite3PagerOpen(
|
|||||||
pPtr = ((u8 *)&pPager[1]) + pcacheSize;
|
pPtr = ((u8 *)&pPager[1]) + pcacheSize;
|
||||||
pPager->vfsFlags = vfsFlags;
|
pPager->vfsFlags = vfsFlags;
|
||||||
pPager->fd = (sqlite3_file*)&pPtr[pVfs->szOsFile*0];
|
pPager->fd = (sqlite3_file*)&pPtr[pVfs->szOsFile*0];
|
||||||
pPager->stfd = (sqlite3_file*)&pPtr[pVfs->szOsFile*1];
|
pPager->stfd = (sqlite3_file*)&pPtr[pVfs->szOsFile];
|
||||||
pPager->jfd = (sqlite3_file*)&pPtr[pVfs->szOsFile*2];
|
pPager->jfd = (sqlite3_file*)&pPtr[pVfs->szOsFile+journalFileSize];
|
||||||
pPager->zFilename = (char*)&pPtr[pVfs->szOsFile*2+journalFileSize];
|
pPager->zFilename = (char*)&pPtr[pVfs->szOsFile+2*journalFileSize];
|
||||||
pPager->zDirectory = &pPager->zFilename[nPathname+1];
|
pPager->zDirectory = &pPager->zFilename[nPathname+1];
|
||||||
pPager->zJournal = &pPager->zDirectory[nPathname+1];
|
pPager->zJournal = &pPager->zDirectory[nPathname+1];
|
||||||
pPager->pVfs = pVfs;
|
pPager->pVfs = pVfs;
|
||||||
@ -1845,10 +1852,14 @@ int sqlite3PagerOpen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else if( !memDb ){
|
}else{
|
||||||
/* If a temporary file is requested, it is not opened immediately.
|
/* If a temporary file is requested, it is not opened immediately.
|
||||||
** In this case we accept the default page size and delay actually
|
** In this case we accept the default page size and delay actually
|
||||||
** opening the file until the first call to OsWrite().
|
** opening the file until the first call to OsWrite().
|
||||||
|
**
|
||||||
|
** This branch is also run for an in-memory database. An in-memory
|
||||||
|
** database is the same as a temp-file that is never written out to
|
||||||
|
** disk and uses an in-memory rollback journal.
|
||||||
*/
|
*/
|
||||||
tempFile = 1;
|
tempFile = 1;
|
||||||
pPager->state = PAGER_EXCLUSIVE;
|
pPager->state = PAGER_EXCLUSIVE;
|
||||||
@ -1920,9 +1931,10 @@ int sqlite3PagerOpen(
|
|||||||
/* pPager->pLast = 0; */
|
/* pPager->pLast = 0; */
|
||||||
pPager->nExtra = nExtra;
|
pPager->nExtra = nExtra;
|
||||||
pPager->journalSizeLimit = SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT;
|
pPager->journalSizeLimit = SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT;
|
||||||
assert(pPager->fd->pMethods||memDb||tempFile);
|
assert(pPager->fd->pMethods||tempFile);
|
||||||
if( !memDb ){
|
setSectorSize(pPager);
|
||||||
setSectorSize(pPager);
|
if( memDb ){
|
||||||
|
pPager->journalMode = PAGER_JOURNALMODE_MEMORY;
|
||||||
}
|
}
|
||||||
/* pPager->pBusyHandler = 0; */
|
/* pPager->pBusyHandler = 0; */
|
||||||
/* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
|
/* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
|
||||||
@ -2043,7 +2055,7 @@ void enable_simulated_io_errors(void){
|
|||||||
int sqlite3PagerReadFileheader(Pager *pPager, int N, unsigned char *pDest){
|
int sqlite3PagerReadFileheader(Pager *pPager, int N, unsigned char *pDest){
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
memset(pDest, 0, N);
|
memset(pDest, 0, N);
|
||||||
assert(MEMDB||pPager->fd->pMethods||pPager->tempFile);
|
assert(pPager->fd->pMethods||pPager->tempFile);
|
||||||
if( pPager->fd->pMethods ){
|
if( pPager->fd->pMethods ){
|
||||||
IOTRACE(("DBHDR %p 0 %d\n", pPager, N))
|
IOTRACE(("DBHDR %p 0 %d\n", pPager, N))
|
||||||
rc = sqlite3OsRead(pPager->fd, pDest, N, 0);
|
rc = sqlite3OsRead(pPager->fd, pDest, N, 0);
|
||||||
@ -2139,7 +2151,7 @@ static int pager_wait_on_lock(Pager *pPager, int locktype){
|
|||||||
assert( PAGER_EXCLUSIVE==EXCLUSIVE_LOCK );
|
assert( PAGER_EXCLUSIVE==EXCLUSIVE_LOCK );
|
||||||
|
|
||||||
/* If the file is currently unlocked then the size must be unknown */
|
/* If the file is currently unlocked then the size must be unknown */
|
||||||
assert( pPager->state>=PAGER_SHARED || pPager->dbSize<0 || MEMDB );
|
assert( pPager->state>=PAGER_SHARED || pPager->dbSize<0 );
|
||||||
|
|
||||||
if( pPager->state>=locktype ){
|
if( pPager->state>=locktype ){
|
||||||
rc = SQLITE_OK;
|
rc = SQLITE_OK;
|
||||||
@ -2161,25 +2173,19 @@ static int pager_wait_on_lock(Pager *pPager, int locktype){
|
|||||||
*/
|
*/
|
||||||
int sqlite3PagerTruncate(Pager *pPager, Pgno nPage){
|
int sqlite3PagerTruncate(Pager *pPager, Pgno nPage){
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
assert( pPager->state>=PAGER_SHARED || MEMDB );
|
assert( pPager->state>=PAGER_SHARED );
|
||||||
|
|
||||||
|
|
||||||
sqlite3PagerPagecount(pPager, 0);
|
sqlite3PagerPagecount(pPager, 0);
|
||||||
if( pPager->errCode ){
|
if( pPager->errCode ){
|
||||||
rc = pPager->errCode;
|
rc = pPager->errCode;
|
||||||
}else if( nPage<(unsigned)pPager->dbSize ){
|
}else if( nPage<(unsigned)pPager->dbSize ){
|
||||||
if( MEMDB ){
|
rc = syncJournal(pPager);
|
||||||
pPager->dbSize = nPage;
|
if( rc==SQLITE_OK ){
|
||||||
pager_truncate_cache(pPager);
|
/* Get an exclusive lock on the database before truncating. */
|
||||||
}else{
|
rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
|
||||||
rc = syncJournal(pPager);
|
}
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
/* Get an exclusive lock on the database before truncating. */
|
rc = pager_truncate(pPager, nPage);
|
||||||
rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
|
|
||||||
}
|
|
||||||
if( rc==SQLITE_OK ){
|
|
||||||
rc = pager_truncate(pPager, nPage);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2207,7 +2213,9 @@ int sqlite3PagerClose(Pager *pPager){
|
|||||||
pPager->errCode = 0;
|
pPager->errCode = 0;
|
||||||
pPager->exclusiveMode = 0;
|
pPager->exclusiveMode = 0;
|
||||||
pager_reset(pPager);
|
pager_reset(pPager);
|
||||||
pagerUnlockAndRollback(pPager);
|
if( !MEMDB ){
|
||||||
|
pagerUnlockAndRollback(pPager);
|
||||||
|
}
|
||||||
enable_simulated_io_errors();
|
enable_simulated_io_errors();
|
||||||
sqlite3EndBenignMalloc();
|
sqlite3EndBenignMalloc();
|
||||||
PAGERTRACE2("CLOSE %d\n", PAGERID(pPager));
|
PAGERTRACE2("CLOSE %d\n", PAGERID(pPager));
|
||||||
@ -2283,7 +2291,8 @@ static int syncJournal(Pager *pPager){
|
|||||||
** (assuming there is a journal and it needs to be synced.)
|
** (assuming there is a journal and it needs to be synced.)
|
||||||
*/
|
*/
|
||||||
if( pPager->needSync ){
|
if( pPager->needSync ){
|
||||||
if( !pPager->tempFile ){
|
assert( !pPager->tempFile );
|
||||||
|
if( pPager->journalMode!=PAGER_JOURNALMODE_MEMORY ){
|
||||||
int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
|
int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
|
||||||
assert( pPager->journalOpen );
|
assert( pPager->journalOpen );
|
||||||
|
|
||||||
@ -2439,6 +2448,7 @@ static int pagerStress(void *p, PgHdr *pPg){
|
|||||||
if( pPg->flags&PGHDR_NEED_SYNC ){
|
if( pPg->flags&PGHDR_NEED_SYNC ){
|
||||||
rc = syncJournal(pPager);
|
rc = syncJournal(pPager);
|
||||||
if( rc==SQLITE_OK && pPager->fullSync &&
|
if( rc==SQLITE_OK && pPager->fullSync &&
|
||||||
|
!(pPager->journalMode==PAGER_JOURNALMODE_MEMORY) &&
|
||||||
!(sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND)
|
!(sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND)
|
||||||
){
|
){
|
||||||
pPager->nRec = 0;
|
pPager->nRec = 0;
|
||||||
@ -2572,140 +2582,139 @@ static int pagerSharedLock(Pager *pPager){
|
|||||||
|
|
||||||
if( pPager->state==PAGER_UNLOCK || isErrorReset ){
|
if( pPager->state==PAGER_UNLOCK || isErrorReset ){
|
||||||
sqlite3_vfs *pVfs = pPager->pVfs;
|
sqlite3_vfs *pVfs = pPager->pVfs;
|
||||||
if( !MEMDB ){
|
assert( !MEMDB );
|
||||||
int isHotJournal;
|
int isHotJournal;
|
||||||
assert( sqlite3PcacheRefCount(pPager->pPCache)==0 );
|
assert( sqlite3PcacheRefCount(pPager->pPCache)==0 );
|
||||||
if( !pPager->noReadlock ){
|
if( !pPager->noReadlock ){
|
||||||
rc = pager_wait_on_lock(pPager, SHARED_LOCK);
|
rc = pager_wait_on_lock(pPager, SHARED_LOCK);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
assert( pPager->state==PAGER_UNLOCK );
|
assert( pPager->state==PAGER_UNLOCK );
|
||||||
return pager_error(pPager, rc);
|
return pager_error(pPager, rc);
|
||||||
}
|
|
||||||
assert( pPager->state>=SHARED_LOCK );
|
|
||||||
}
|
}
|
||||||
|
assert( pPager->state>=SHARED_LOCK );
|
||||||
/* If a journal file exists, and there is no RESERVED lock on the
|
}
|
||||||
** database file, then it either needs to be played back or deleted.
|
|
||||||
|
/* If a journal file exists, and there is no RESERVED lock on the
|
||||||
|
** database file, then it either needs to be played back or deleted.
|
||||||
|
*/
|
||||||
|
if( !isErrorReset ){
|
||||||
|
rc = hasHotJournal(pPager, &isHotJournal);
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( isErrorReset || isHotJournal ){
|
||||||
|
/* Get an EXCLUSIVE lock on the database file. At this point it is
|
||||||
|
** important that a RESERVED lock is not obtained on the way to the
|
||||||
|
** EXCLUSIVE lock. If it were, another process might open the
|
||||||
|
** database file, detect the RESERVED lock, and conclude that the
|
||||||
|
** database is safe to read while this process is still rolling it
|
||||||
|
** back.
|
||||||
|
**
|
||||||
|
** Because the intermediate RESERVED lock is not requested, the
|
||||||
|
** second process will get to this point in the code and fail to
|
||||||
|
** obtain its own EXCLUSIVE lock on the database file.
|
||||||
*/
|
*/
|
||||||
if( !isErrorReset ){
|
if( pPager->state<EXCLUSIVE_LOCK ){
|
||||||
rc = hasHotJournal(pPager, &isHotJournal);
|
rc = sqlite3OsLock(pPager->fd, EXCLUSIVE_LOCK);
|
||||||
if( rc!=SQLITE_OK ){
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( isErrorReset || isHotJournal ){
|
|
||||||
/* Get an EXCLUSIVE lock on the database file. At this point it is
|
|
||||||
** important that a RESERVED lock is not obtained on the way to the
|
|
||||||
** EXCLUSIVE lock. If it were, another process might open the
|
|
||||||
** database file, detect the RESERVED lock, and conclude that the
|
|
||||||
** database is safe to read while this process is still rolling it
|
|
||||||
** back.
|
|
||||||
**
|
|
||||||
** Because the intermediate RESERVED lock is not requested, the
|
|
||||||
** second process will get to this point in the code and fail to
|
|
||||||
** obtain its own EXCLUSIVE lock on the database file.
|
|
||||||
*/
|
|
||||||
if( pPager->state<EXCLUSIVE_LOCK ){
|
|
||||||
rc = sqlite3OsLock(pPager->fd, EXCLUSIVE_LOCK);
|
|
||||||
if( rc!=SQLITE_OK ){
|
|
||||||
rc = pager_error(pPager, rc);
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
pPager->state = PAGER_EXCLUSIVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Open the journal for read/write access. This is because in
|
|
||||||
** exclusive-access mode the file descriptor will be kept open and
|
|
||||||
** possibly used for a transaction later on. On some systems, the
|
|
||||||
** OsTruncate() call used in exclusive-access mode also requires
|
|
||||||
** a read/write file handle.
|
|
||||||
*/
|
|
||||||
if( !isErrorReset && pPager->journalOpen==0 ){
|
|
||||||
int res;
|
|
||||||
rc = sqlite3OsAccess(pVfs,pPager->zJournal,SQLITE_ACCESS_EXISTS,&res);
|
|
||||||
if( rc==SQLITE_OK ){
|
|
||||||
if( res ){
|
|
||||||
int fout = 0;
|
|
||||||
int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL;
|
|
||||||
assert( !pPager->tempFile );
|
|
||||||
rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout);
|
|
||||||
assert( rc!=SQLITE_OK || pPager->jfd->pMethods );
|
|
||||||
if( fout&SQLITE_OPEN_READONLY ){
|
|
||||||
rc = SQLITE_BUSY;
|
|
||||||
sqlite3OsClose(pPager->jfd);
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
/* If the journal does not exist, that means some other process
|
|
||||||
** has already rolled it back */
|
|
||||||
rc = SQLITE_BUSY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( rc!=SQLITE_OK ){
|
|
||||||
if( rc!=SQLITE_NOMEM && rc!=SQLITE_IOERR_UNLOCK
|
|
||||||
&& rc!=SQLITE_IOERR_NOMEM
|
|
||||||
){
|
|
||||||
rc = SQLITE_BUSY;
|
|
||||||
}
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
pPager->journalOpen = 1;
|
|
||||||
pPager->journalStarted = 0;
|
|
||||||
pPager->journalOff = 0;
|
|
||||||
pPager->setMaster = 0;
|
|
||||||
pPager->journalHdr = 0;
|
|
||||||
|
|
||||||
/* Playback and delete the journal. Drop the database write
|
|
||||||
** lock and reacquire the read lock.
|
|
||||||
*/
|
|
||||||
rc = pager_playback(pPager, 1);
|
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
rc = pager_error(pPager, rc);
|
rc = pager_error(pPager, rc);
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
assert(pPager->state==PAGER_SHARED ||
|
pPager->state = PAGER_EXCLUSIVE;
|
||||||
(pPager->exclusiveMode && pPager->state>PAGER_SHARED)
|
}
|
||||||
);
|
|
||||||
|
/* Open the journal for read/write access. This is because in
|
||||||
|
** exclusive-access mode the file descriptor will be kept open and
|
||||||
|
** possibly used for a transaction later on. On some systems, the
|
||||||
|
** OsTruncate() call used in exclusive-access mode also requires
|
||||||
|
** a read/write file handle.
|
||||||
|
*/
|
||||||
|
if( !isErrorReset && pPager->journalOpen==0 ){
|
||||||
|
int res;
|
||||||
|
rc = sqlite3OsAccess(pVfs,pPager->zJournal,SQLITE_ACCESS_EXISTS,&res);
|
||||||
|
if( rc==SQLITE_OK ){
|
||||||
|
if( res ){
|
||||||
|
int fout = 0;
|
||||||
|
int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL;
|
||||||
|
assert( !pPager->tempFile );
|
||||||
|
rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout);
|
||||||
|
assert( rc!=SQLITE_OK || pPager->jfd->pMethods );
|
||||||
|
if( fout&SQLITE_OPEN_READONLY ){
|
||||||
|
rc = SQLITE_BUSY;
|
||||||
|
sqlite3OsClose(pPager->jfd);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
/* If the journal does not exist, that means some other process
|
||||||
|
** has already rolled it back */
|
||||||
|
rc = SQLITE_BUSY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
if( rc!=SQLITE_NOMEM && rc!=SQLITE_IOERR_UNLOCK
|
||||||
|
&& rc!=SQLITE_IOERR_NOMEM
|
||||||
|
){
|
||||||
|
rc = SQLITE_BUSY;
|
||||||
|
}
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
pPager->journalOpen = 1;
|
||||||
|
pPager->journalStarted = 0;
|
||||||
|
pPager->journalOff = 0;
|
||||||
|
pPager->setMaster = 0;
|
||||||
|
pPager->journalHdr = 0;
|
||||||
|
|
||||||
|
/* Playback and delete the journal. Drop the database write
|
||||||
|
** lock and reacquire the read lock.
|
||||||
|
*/
|
||||||
|
rc = pager_playback(pPager, 1);
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
rc = pager_error(pPager, rc);
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
assert(pPager->state==PAGER_SHARED ||
|
||||||
|
(pPager->exclusiveMode && pPager->state>PAGER_SHARED)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( sqlite3PcachePagecount(pPager->pPCache)>0 ){
|
||||||
|
/* The shared-lock has just been acquired on the database file
|
||||||
|
** and there are already pages in the cache (from a previous
|
||||||
|
** read or write transaction). Check to see if the database
|
||||||
|
** has been modified. If the database has changed, flush the
|
||||||
|
** cache.
|
||||||
|
**
|
||||||
|
** Database changes is detected by looking at 15 bytes beginning
|
||||||
|
** at offset 24 into the file. The first 4 of these 16 bytes are
|
||||||
|
** a 32-bit counter that is incremented with each change. The
|
||||||
|
** other bytes change randomly with each file change when
|
||||||
|
** a codec is in use.
|
||||||
|
**
|
||||||
|
** There is a vanishingly small chance that a change will not be
|
||||||
|
** detected. The chance of an undetected change is so small that
|
||||||
|
** it can be neglected.
|
||||||
|
*/
|
||||||
|
char dbFileVers[sizeof(pPager->dbFileVers)];
|
||||||
|
sqlite3PagerPagecount(pPager, 0);
|
||||||
|
|
||||||
|
if( pPager->errCode ){
|
||||||
|
rc = pPager->errCode;
|
||||||
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( sqlite3PcachePagecount(pPager->pPCache)>0 ){
|
if( pPager->dbSize>0 ){
|
||||||
/* The shared-lock has just been acquired on the database file
|
IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers)));
|
||||||
** and there are already pages in the cache (from a previous
|
rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24);
|
||||||
** read or write transaction). Check to see if the database
|
if( rc!=SQLITE_OK ){
|
||||||
** has been modified. If the database has changed, flush the
|
|
||||||
** cache.
|
|
||||||
**
|
|
||||||
** Database changes is detected by looking at 15 bytes beginning
|
|
||||||
** at offset 24 into the file. The first 4 of these 16 bytes are
|
|
||||||
** a 32-bit counter that is incremented with each change. The
|
|
||||||
** other bytes change randomly with each file change when
|
|
||||||
** a codec is in use.
|
|
||||||
**
|
|
||||||
** There is a vanishingly small chance that a change will not be
|
|
||||||
** detected. The chance of an undetected change is so small that
|
|
||||||
** it can be neglected.
|
|
||||||
*/
|
|
||||||
char dbFileVers[sizeof(pPager->dbFileVers)];
|
|
||||||
sqlite3PagerPagecount(pPager, 0);
|
|
||||||
|
|
||||||
if( pPager->errCode ){
|
|
||||||
rc = pPager->errCode;
|
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
}else{
|
||||||
|
memset(dbFileVers, 0, sizeof(dbFileVers));
|
||||||
|
}
|
||||||
|
|
||||||
if( pPager->dbSize>0 ){
|
if( memcmp(pPager->dbFileVers, dbFileVers, sizeof(dbFileVers))!=0 ){
|
||||||
IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers)));
|
pager_reset(pPager);
|
||||||
rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24);
|
|
||||||
if( rc!=SQLITE_OK ){
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
memset(dbFileVers, 0, sizeof(dbFileVers));
|
|
||||||
}
|
|
||||||
|
|
||||||
if( memcmp(pPager->dbFileVers, dbFileVers, sizeof(dbFileVers))!=0 ){
|
|
||||||
pager_reset(pPager);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert( pPager->exclusiveMode || pPager->state<=PAGER_SHARED );
|
assert( pPager->exclusiveMode || pPager->state<=PAGER_SHARED );
|
||||||
@ -2808,7 +2817,7 @@ int sqlite3PagerAcquire(
|
|||||||
|
|
||||||
assert( pPager->state==PAGER_UNLOCK
|
assert( pPager->state==PAGER_UNLOCK
|
||||||
|| sqlite3PcacheRefCount(pPager->pPCache)>0
|
|| sqlite3PcacheRefCount(pPager->pPCache)>0
|
||||||
|| pgno==1
|
|| pgno==1
|
||||||
);
|
);
|
||||||
|
|
||||||
/* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page
|
/* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page
|
||||||
@ -2845,7 +2854,6 @@ int sqlite3PagerAcquire(
|
|||||||
PAGER_INCR(pPager->nMiss);
|
PAGER_INCR(pPager->nMiss);
|
||||||
pPg->pPager = pPager;
|
pPg->pPager = pPager;
|
||||||
if( sqlite3BitvecTest(pPager->pInJournal, pgno) ){
|
if( sqlite3BitvecTest(pPager->pInJournal, pgno) ){
|
||||||
assert( !MEMDB );
|
|
||||||
pPg->flags |= PGHDR_IN_JOURNAL;
|
pPg->flags |= PGHDR_IN_JOURNAL;
|
||||||
}
|
}
|
||||||
memset(pPg->pExtra, 0, pPager->nExtra);
|
memset(pPg->pExtra, 0, pPager->nExtra);
|
||||||
@ -2948,7 +2956,6 @@ static int pager_open_journal(Pager *pPager){
|
|||||||
int flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_CREATE);
|
int flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_CREATE);
|
||||||
|
|
||||||
int rc;
|
int rc;
|
||||||
assert( !MEMDB );
|
|
||||||
assert( pPager->state>=PAGER_RESERVED );
|
assert( pPager->state>=PAGER_RESERVED );
|
||||||
assert( pPager->useJournal );
|
assert( pPager->useJournal );
|
||||||
assert( pPager->pInJournal==0 );
|
assert( pPager->pInJournal==0 );
|
||||||
@ -2965,13 +2972,18 @@ static int pager_open_journal(Pager *pPager){
|
|||||||
}else{
|
}else{
|
||||||
flags |= (SQLITE_OPEN_MAIN_JOURNAL);
|
flags |= (SQLITE_OPEN_MAIN_JOURNAL);
|
||||||
}
|
}
|
||||||
|
if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){
|
||||||
|
sqlite3MemJournalOpen(pPager->jfd);
|
||||||
|
rc = SQLITE_OK;
|
||||||
|
}else{
|
||||||
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
|
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
|
||||||
rc = sqlite3JournalOpen(
|
rc = sqlite3JournalOpen(
|
||||||
pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager)
|
pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager)
|
||||||
);
|
);
|
||||||
#else
|
#else
|
||||||
rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0);
|
rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
assert( rc!=SQLITE_OK || pPager->jfd->pMethods );
|
assert( rc!=SQLITE_OK || pPager->jfd->pMethods );
|
||||||
pPager->journalOff = 0;
|
pPager->journalOff = 0;
|
||||||
pPager->setMaster = 0;
|
pPager->setMaster = 0;
|
||||||
@ -3046,28 +3058,24 @@ int sqlite3PagerBegin(DbPage *pPg, int exFlag){
|
|||||||
assert( pPager->state!=PAGER_UNLOCK );
|
assert( pPager->state!=PAGER_UNLOCK );
|
||||||
if( pPager->state==PAGER_SHARED ){
|
if( pPager->state==PAGER_SHARED ){
|
||||||
assert( pPager->pInJournal==0 );
|
assert( pPager->pInJournal==0 );
|
||||||
|
assert( !MEMDB );
|
||||||
sqlite3PcacheAssertFlags(pPager->pPCache, 0, PGHDR_IN_JOURNAL);
|
sqlite3PcacheAssertFlags(pPager->pPCache, 0, PGHDR_IN_JOURNAL);
|
||||||
if( MEMDB ){
|
rc = sqlite3OsLock(pPager->fd, RESERVED_LOCK);
|
||||||
pPager->state = PAGER_EXCLUSIVE;
|
if( rc==SQLITE_OK ){
|
||||||
pPager->origDbSize = pPager->dbSize;
|
pPager->state = PAGER_RESERVED;
|
||||||
}else{
|
if( exFlag ){
|
||||||
rc = sqlite3OsLock(pPager->fd, RESERVED_LOCK);
|
rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
|
||||||
if( rc==SQLITE_OK ){
|
|
||||||
pPager->state = PAGER_RESERVED;
|
|
||||||
if( exFlag ){
|
|
||||||
rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( rc!=SQLITE_OK ){
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
pPager->dirtyCache = 0;
|
|
||||||
PAGERTRACE2("TRANSACTION %d\n", PAGERID(pPager));
|
|
||||||
if( pPager->useJournal && !pPager->tempFile
|
|
||||||
&& pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
|
|
||||||
rc = pager_open_journal(pPager);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
pPager->dirtyCache = 0;
|
||||||
|
PAGERTRACE2("TRANSACTION %d\n", PAGERID(pPager));
|
||||||
|
if( pPager->useJournal && !pPager->tempFile
|
||||||
|
&& pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
|
||||||
|
rc = pager_open_journal(pPager);
|
||||||
|
}
|
||||||
}else if( pPager->journalOpen && pPager->journalOff==0 ){
|
}else if( pPager->journalOpen && pPager->journalOff==0 ){
|
||||||
/* This happens when the pager was in exclusive-access mode the last
|
/* This happens when the pager was in exclusive-access mode the last
|
||||||
** time a (read or write) transaction was successfully concluded
|
** time a (read or write) transaction was successfully concluded
|
||||||
@ -3192,57 +3200,49 @@ static int pager_write(PgHdr *pPg){
|
|||||||
** EXCLUSIVE lock on the main database file. Write the current page to
|
** EXCLUSIVE lock on the main database file. Write the current page to
|
||||||
** the transaction journal if it is not there already.
|
** the transaction journal if it is not there already.
|
||||||
*/
|
*/
|
||||||
if( !(pPg->flags&PGHDR_IN_JOURNAL) && (pPager->journalOpen || MEMDB) ){
|
if( !(pPg->flags&PGHDR_IN_JOURNAL) && pPager->journalOpen ){
|
||||||
if( (int)pPg->pgno <= pPager->origDbSize ){
|
if( (int)pPg->pgno <= pPager->origDbSize ){
|
||||||
if( MEMDB ){
|
u32 cksum;
|
||||||
PAGERTRACE3("JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
|
char *pData2;
|
||||||
rc = sqlite3PcachePreserve(pPg, 0);
|
|
||||||
if( rc!=SQLITE_OK ){
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
u32 cksum;
|
|
||||||
char *pData2;
|
|
||||||
|
|
||||||
/* We should never write to the journal file the page that
|
/* We should never write to the journal file the page that
|
||||||
** contains the database locks. The following assert verifies
|
** contains the database locks. The following assert verifies
|
||||||
** that we do not. */
|
** that we do not. */
|
||||||
assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
|
assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
|
||||||
pData2 = CODEC2(pPager, pData, pPg->pgno, 7);
|
pData2 = CODEC2(pPager, pData, pPg->pgno, 7);
|
||||||
cksum = pager_cksum(pPager, (u8*)pData2);
|
cksum = pager_cksum(pPager, (u8*)pData2);
|
||||||
rc = write32bits(pPager->jfd, pPager->journalOff, pPg->pgno);
|
rc = write32bits(pPager->jfd, pPager->journalOff, pPg->pgno);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
rc = sqlite3OsWrite(pPager->jfd, pData2, pPager->pageSize,
|
rc = sqlite3OsWrite(pPager->jfd, pData2, pPager->pageSize,
|
||||||
pPager->journalOff + 4);
|
pPager->journalOff + 4);
|
||||||
pPager->journalOff += pPager->pageSize+4;
|
pPager->journalOff += pPager->pageSize+4;
|
||||||
}
|
}
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
rc = write32bits(pPager->jfd, pPager->journalOff, cksum);
|
rc = write32bits(pPager->jfd, pPager->journalOff, cksum);
|
||||||
pPager->journalOff += 4;
|
pPager->journalOff += 4;
|
||||||
}
|
}
|
||||||
IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno,
|
IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno,
|
||||||
pPager->journalOff, pPager->pageSize));
|
pPager->journalOff, pPager->pageSize));
|
||||||
PAGER_INCR(sqlite3_pager_writej_count);
|
PAGER_INCR(sqlite3_pager_writej_count);
|
||||||
PAGERTRACE5("JOURNAL %d page %d needSync=%d hash(%08x)\n",
|
PAGERTRACE5("JOURNAL %d page %d needSync=%d hash(%08x)\n",
|
||||||
PAGERID(pPager), pPg->pgno,
|
PAGERID(pPager), pPg->pgno,
|
||||||
((pPg->flags&PGHDR_NEED_SYNC)?1:0), pager_pagehash(pPg));
|
((pPg->flags&PGHDR_NEED_SYNC)?1:0), pager_pagehash(pPg));
|
||||||
|
|
||||||
/* An error has occured writing to the journal file. The
|
/* An error has occured writing to the journal file. The
|
||||||
** transaction will be rolled back by the layer above.
|
** transaction will be rolled back by the layer above.
|
||||||
*/
|
*/
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
pPager->nRec++;
|
pPager->nRec++;
|
||||||
assert( pPager->pInJournal!=0 );
|
assert( pPager->pInJournal!=0 );
|
||||||
sqlite3BitvecSet(pPager->pInJournal, pPg->pgno);
|
sqlite3BitvecSet(pPager->pInJournal, pPg->pgno);
|
||||||
if( !pPager->noSync ){
|
if( !pPager->noSync ){
|
||||||
pPg->flags |= PGHDR_NEED_SYNC;
|
pPg->flags |= PGHDR_NEED_SYNC;
|
||||||
}
|
}
|
||||||
if( pPager->stmtInUse ){
|
if( pPager->stmtInUse ){
|
||||||
sqlite3BitvecSet(pPager->pInStmt, pPg->pgno);
|
sqlite3BitvecSet(pPager->pInStmt, pPg->pgno);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
if( !pPager->journalStarted && !pPager->noSync ){
|
if( !pPager->journalStarted && !pPager->noSync ){
|
||||||
@ -3269,27 +3269,19 @@ static int pager_write(PgHdr *pPg){
|
|||||||
){
|
){
|
||||||
assert( (pPg->flags&PGHDR_IN_JOURNAL)
|
assert( (pPg->flags&PGHDR_IN_JOURNAL)
|
||||||
|| (int)pPg->pgno>pPager->origDbSize );
|
|| (int)pPg->pgno>pPager->origDbSize );
|
||||||
if( MEMDB ){
|
i64 offset = pPager->stmtNRec*(4+pPager->pageSize);
|
||||||
rc = sqlite3PcachePreserve(pPg, 1);
|
char *pData2 = CODEC2(pPager, pData, pPg->pgno, 7);
|
||||||
if( rc!=SQLITE_OK ){
|
rc = write32bits(pPager->stfd, offset, pPg->pgno);
|
||||||
return rc;
|
if( rc==SQLITE_OK ){
|
||||||
}
|
rc = sqlite3OsWrite(pPager->stfd, pData2, pPager->pageSize, offset+4);
|
||||||
PAGERTRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
|
|
||||||
}else{
|
|
||||||
i64 offset = pPager->stmtNRec*(4+pPager->pageSize);
|
|
||||||
char *pData2 = CODEC2(pPager, pData, pPg->pgno, 7);
|
|
||||||
rc = write32bits(pPager->stfd, offset, pPg->pgno);
|
|
||||||
if( rc==SQLITE_OK ){
|
|
||||||
rc = sqlite3OsWrite(pPager->stfd, pData2, pPager->pageSize, offset+4);
|
|
||||||
}
|
|
||||||
PAGERTRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
|
|
||||||
if( rc!=SQLITE_OK ){
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
pPager->stmtNRec++;
|
|
||||||
assert( pPager->pInStmt!=0 );
|
|
||||||
sqlite3BitvecSet(pPager->pInStmt, pPg->pgno);
|
|
||||||
}
|
}
|
||||||
|
PAGERTRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
pPager->stmtNRec++;
|
||||||
|
assert( pPager->pInStmt!=0 );
|
||||||
|
sqlite3BitvecSet(pPager->pInStmt, pPg->pgno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3298,7 +3290,7 @@ static int pager_write(PgHdr *pPg){
|
|||||||
assert( pPager->state>=PAGER_SHARED );
|
assert( pPager->state>=PAGER_SHARED );
|
||||||
if( pPager->dbSize<(int)pPg->pgno ){
|
if( pPager->dbSize<(int)pPg->pgno ){
|
||||||
pPager->dbSize = pPg->pgno;
|
pPager->dbSize = pPg->pgno;
|
||||||
if( !MEMDB && pPager->dbSize==PENDING_BYTE/pPager->pageSize ){
|
if( pPager->dbSize==PENDING_BYTE/pPager->pageSize ){
|
||||||
pPager->dbSize++;
|
pPager->dbSize++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3322,7 +3314,7 @@ int sqlite3PagerWrite(DbPage *pDbPage){
|
|||||||
Pager *pPager = pPg->pPager;
|
Pager *pPager = pPg->pPager;
|
||||||
Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize);
|
Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize);
|
||||||
|
|
||||||
if( !MEMDB && nPagePerSector>1 ){
|
if( nPagePerSector>1 ){
|
||||||
Pgno nPageCount; /* Total number of pages in database file */
|
Pgno nPageCount; /* Total number of pages in database file */
|
||||||
Pgno pg1; /* First page of the sector pPg is located on. */
|
Pgno pg1; /* First page of the sector pPg is located on. */
|
||||||
int nPage; /* Number of pages starting at pg1 to journal */
|
int nPage; /* Number of pages starting at pg1 to journal */
|
||||||
@ -3332,6 +3324,7 @@ int sqlite3PagerWrite(DbPage *pDbPage){
|
|||||||
/* Set the doNotSync flag to 1. This is because we cannot allow a journal
|
/* Set the doNotSync flag to 1. This is because we cannot allow a journal
|
||||||
** header to be written between the pages journaled by this function.
|
** header to be written between the pages journaled by this function.
|
||||||
*/
|
*/
|
||||||
|
assert( !MEMDB );
|
||||||
assert( pPager->doNotSync==0 );
|
assert( pPager->doNotSync==0 );
|
||||||
pPager->doNotSync = 1;
|
pPager->doNotSync = 1;
|
||||||
|
|
||||||
@ -3439,7 +3432,7 @@ int sqlite3PagerDontWrite(DbPage *pDbPage){
|
|||||||
Pager *pPager = pPg->pPager;
|
Pager *pPager = pPg->pPager;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if( MEMDB || pPg->pgno>pPager->origDbSize ){
|
if( pPg->pgno>pPager->origDbSize ){
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
if( pPager->pAlwaysRollback==0 ){
|
if( pPager->pAlwaysRollback==0 ){
|
||||||
@ -3500,7 +3493,6 @@ void sqlite3PagerDontRollback(DbPage *pPg){
|
|||||||
){
|
){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
assert( !MEMDB ); /* For a memdb, pPager->journalOpen is always 0 */
|
|
||||||
|
|
||||||
#ifdef SQLITE_SECURE_DELETE
|
#ifdef SQLITE_SECURE_DELETE
|
||||||
if( (pPg->flags & PGHDR_IN_JOURNAL)!=0 || (int)pPg->pgno>pPager->origDbSize ){
|
if( (pPg->flags & PGHDR_IN_JOURNAL)!=0 || (int)pPg->pgno>pPager->origDbSize ){
|
||||||
@ -3792,16 +3784,9 @@ int sqlite3PagerCommitPhaseTwo(Pager *pPager){
|
|||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
PAGERTRACE2("COMMIT %d\n", PAGERID(pPager));
|
PAGERTRACE2("COMMIT %d\n", PAGERID(pPager));
|
||||||
if( MEMDB ){
|
assert( pPager->state==PAGER_SYNCED || MEMDB || !pPager->dirtyCache );
|
||||||
sqlite3PcacheCommit(pPager->pPCache, 0);
|
rc = pager_end_transaction(pPager, pPager->setMaster);
|
||||||
sqlite3PcacheCleanAll(pPager->pPCache);
|
rc = pager_error(pPager, rc);
|
||||||
sqlite3PcacheAssertFlags(pPager->pPCache, 0, PGHDR_IN_JOURNAL);
|
|
||||||
pPager->state = PAGER_SHARED;
|
|
||||||
}else{
|
|
||||||
assert( pPager->state==PAGER_SYNCED || !pPager->dirtyCache );
|
|
||||||
rc = pager_end_transaction(pPager, pPager->setMaster);
|
|
||||||
rc = pager_error(pPager, rc);
|
|
||||||
}
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3820,16 +3805,7 @@ int sqlite3PagerCommitPhaseTwo(Pager *pPager){
|
|||||||
int sqlite3PagerRollback(Pager *pPager){
|
int sqlite3PagerRollback(Pager *pPager){
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
PAGERTRACE2("ROLLBACK %d\n", PAGERID(pPager));
|
PAGERTRACE2("ROLLBACK %d\n", PAGERID(pPager));
|
||||||
if( MEMDB ){
|
if( !pPager->dirtyCache || !pPager->journalOpen ){
|
||||||
sqlite3PcacheRollback(pPager->pPCache, 1, pPager->xReiniter);
|
|
||||||
sqlite3PcacheRollback(pPager->pPCache, 0, pPager->xReiniter);
|
|
||||||
sqlite3PcacheCleanAll(pPager->pPCache);
|
|
||||||
sqlite3PcacheAssertFlags(pPager->pPCache, 0, PGHDR_IN_JOURNAL);
|
|
||||||
pPager->dbSize = pPager->origDbSize;
|
|
||||||
pager_truncate_cache(pPager);
|
|
||||||
pPager->stmtInUse = 0;
|
|
||||||
pPager->state = PAGER_SHARED;
|
|
||||||
}else if( !pPager->dirtyCache || !pPager->journalOpen ){
|
|
||||||
rc = pager_end_transaction(pPager, pPager->setMaster);
|
rc = pager_end_transaction(pPager, pPager->setMaster);
|
||||||
}else if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){
|
}else if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){
|
||||||
if( pPager->state>=PAGER_EXCLUSIVE ){
|
if( pPager->state>=PAGER_EXCLUSIVE ){
|
||||||
@ -3848,7 +3824,9 @@ int sqlite3PagerRollback(Pager *pPager){
|
|||||||
rc = pager_playback(pPager, 0);
|
rc = pager_playback(pPager, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pPager->dbSize = -1;
|
if( !MEMDB ){
|
||||||
|
pPager->dbSize = -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* If an error occurs during a ROLLBACK, we can no longer trust the pager
|
/* If an error occurs during a ROLLBACK, we can no longer trust the pager
|
||||||
** cache. So call pager_error() on the way out to make any error
|
** cache. So call pager_error() on the way out to make any error
|
||||||
@ -3918,11 +3896,6 @@ static int pagerStmtBegin(Pager *pPager){
|
|||||||
assert( pPager->state>=PAGER_SHARED );
|
assert( pPager->state>=PAGER_SHARED );
|
||||||
assert( pPager->dbSize>=0 );
|
assert( pPager->dbSize>=0 );
|
||||||
PAGERTRACE2("STMT-BEGIN %d\n", PAGERID(pPager));
|
PAGERTRACE2("STMT-BEGIN %d\n", PAGERID(pPager));
|
||||||
if( MEMDB ){
|
|
||||||
pPager->stmtInUse = 1;
|
|
||||||
pPager->stmtSize = pPager->dbSize;
|
|
||||||
return SQLITE_OK;
|
|
||||||
}
|
|
||||||
if( !pPager->journalOpen ){
|
if( !pPager->journalOpen ){
|
||||||
pPager->stmtAutoopen = 1;
|
pPager->stmtAutoopen = 1;
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
@ -3939,9 +3912,13 @@ static int pagerStmtBegin(Pager *pPager){
|
|||||||
pPager->stmtHdrOff = 0;
|
pPager->stmtHdrOff = 0;
|
||||||
pPager->stmtCksum = pPager->cksumInit;
|
pPager->stmtCksum = pPager->cksumInit;
|
||||||
if( !pPager->stmtOpen ){
|
if( !pPager->stmtOpen ){
|
||||||
rc = sqlite3PagerOpentemp(pPager, pPager->stfd, SQLITE_OPEN_SUBJOURNAL);
|
if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){
|
||||||
if( rc ){
|
sqlite3MemJournalOpen(pPager->stfd);
|
||||||
goto stmt_begin_failed;
|
}else{
|
||||||
|
rc = sqlite3PagerOpentemp(pPager, pPager->stfd, SQLITE_OPEN_SUBJOURNAL);
|
||||||
|
if( rc ){
|
||||||
|
goto stmt_begin_failed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pPager->stmtOpen = 1;
|
pPager->stmtOpen = 1;
|
||||||
pPager->stmtNRec = 0;
|
pPager->stmtNRec = 0;
|
||||||
@ -3968,14 +3945,13 @@ int sqlite3PagerStmtBegin(Pager *pPager){
|
|||||||
int sqlite3PagerStmtCommit(Pager *pPager){
|
int sqlite3PagerStmtCommit(Pager *pPager){
|
||||||
if( pPager->stmtInUse ){
|
if( pPager->stmtInUse ){
|
||||||
PAGERTRACE2("STMT-COMMIT %d\n", PAGERID(pPager));
|
PAGERTRACE2("STMT-COMMIT %d\n", PAGERID(pPager));
|
||||||
if( !MEMDB ){
|
sqlite3BitvecDestroy(pPager->pInStmt);
|
||||||
sqlite3BitvecDestroy(pPager->pInStmt);
|
pPager->pInStmt = 0;
|
||||||
pPager->pInStmt = 0;
|
|
||||||
}else{
|
|
||||||
sqlite3PcacheCommit(pPager->pPCache, 1);
|
|
||||||
}
|
|
||||||
pPager->stmtNRec = 0;
|
pPager->stmtNRec = 0;
|
||||||
pPager->stmtInUse = 0;
|
pPager->stmtInUse = 0;
|
||||||
|
if( sqlite3IsMemJournal(pPager->stfd) ){
|
||||||
|
sqlite3OsTruncate(pPager->stfd, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pPager->stmtAutoopen = 0;
|
pPager->stmtAutoopen = 0;
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
@ -3988,14 +3964,7 @@ int sqlite3PagerStmtRollback(Pager *pPager){
|
|||||||
int rc;
|
int rc;
|
||||||
if( pPager->stmtInUse ){
|
if( pPager->stmtInUse ){
|
||||||
PAGERTRACE2("STMT-ROLLBACK %d\n", PAGERID(pPager));
|
PAGERTRACE2("STMT-ROLLBACK %d\n", PAGERID(pPager));
|
||||||
if( MEMDB ){
|
rc = pager_stmt_playback(pPager);
|
||||||
sqlite3PcacheRollback(pPager->pPCache, 1, pPager->xReiniter);
|
|
||||||
pPager->dbSize = pPager->stmtSize;
|
|
||||||
pager_truncate_cache(pPager);
|
|
||||||
rc = SQLITE_OK;
|
|
||||||
}else{
|
|
||||||
rc = pager_stmt_playback(pPager);
|
|
||||||
}
|
|
||||||
sqlite3PagerStmtCommit(pPager);
|
sqlite3PagerStmtCommit(pPager);
|
||||||
}else{
|
}else{
|
||||||
rc = SQLITE_OK;
|
rc = SQLITE_OK;
|
||||||
@ -4124,7 +4093,6 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){
|
|||||||
pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC);
|
pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC);
|
||||||
}
|
}
|
||||||
if( sqlite3BitvecTest(pPager->pInJournal, pgno) ){
|
if( sqlite3BitvecTest(pPager->pInJournal, pgno) ){
|
||||||
assert( !MEMDB );
|
|
||||||
pPg->flags |= PGHDR_IN_JOURNAL;
|
pPg->flags |= PGHDR_IN_JOURNAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4233,16 +4201,19 @@ int sqlite3PagerLockingMode(Pager *pPager, int eMode){
|
|||||||
** journal-mode.
|
** journal-mode.
|
||||||
*/
|
*/
|
||||||
int sqlite3PagerJournalMode(Pager *pPager, int eMode){
|
int sqlite3PagerJournalMode(Pager *pPager, int eMode){
|
||||||
assert( eMode==PAGER_JOURNALMODE_QUERY
|
if( !MEMDB ){
|
||||||
|| eMode==PAGER_JOURNALMODE_DELETE
|
assert( eMode==PAGER_JOURNALMODE_QUERY
|
||||||
|| eMode==PAGER_JOURNALMODE_TRUNCATE
|
|| eMode==PAGER_JOURNALMODE_DELETE
|
||||||
|| eMode==PAGER_JOURNALMODE_PERSIST
|
|| eMode==PAGER_JOURNALMODE_TRUNCATE
|
||||||
|| eMode==PAGER_JOURNALMODE_OFF );
|
|| eMode==PAGER_JOURNALMODE_PERSIST
|
||||||
assert( PAGER_JOURNALMODE_QUERY<0 );
|
|| eMode==PAGER_JOURNALMODE_OFF
|
||||||
if( eMode>=0 ){
|
|| eMode==PAGER_JOURNALMODE_MEMORY );
|
||||||
pPager->journalMode = eMode;
|
assert( PAGER_JOURNALMODE_QUERY<0 );
|
||||||
}else{
|
if( eMode>=0 ){
|
||||||
assert( eMode==PAGER_JOURNALMODE_QUERY );
|
pPager->journalMode = eMode;
|
||||||
|
}else{
|
||||||
|
assert( eMode==PAGER_JOURNALMODE_QUERY );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return (int)pPager->journalMode;
|
return (int)pPager->journalMode;
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
** subsystem. The page cache subsystem reads and writes a file a page
|
** subsystem. The page cache subsystem reads and writes a file a page
|
||||||
** at a time and provides a journal for rollback.
|
** at a time and provides a journal for rollback.
|
||||||
**
|
**
|
||||||
** @(#) $Id: pager.h,v 1.85 2008/09/29 11:49:48 danielk1977 Exp $
|
** @(#) $Id: pager.h,v 1.86 2008/10/17 18:51:53 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _PAGER_H_
|
#ifndef _PAGER_H_
|
||||||
@ -66,6 +66,7 @@ typedef struct PgHdr DbPage;
|
|||||||
#define PAGER_JOURNALMODE_PERSIST 1 /* Commit by zeroing journal header */
|
#define PAGER_JOURNALMODE_PERSIST 1 /* Commit by zeroing journal header */
|
||||||
#define PAGER_JOURNALMODE_OFF 2 /* Journal omitted. */
|
#define PAGER_JOURNALMODE_OFF 2 /* Journal omitted. */
|
||||||
#define PAGER_JOURNALMODE_TRUNCATE 3 /* Commit by truncating journal */
|
#define PAGER_JOURNALMODE_TRUNCATE 3 /* Commit by truncating journal */
|
||||||
|
#define PAGER_JOURNALMODE_MEMORY 4 /* In-memory journal file */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** See source code comments for a detailed description of the following
|
** See source code comments for a detailed description of the following
|
||||||
|
76
src/pcache.c
76
src/pcache.c
@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** This file implements that page cache.
|
** This file implements that page cache.
|
||||||
**
|
**
|
||||||
** @(#) $Id: pcache.c,v 1.33 2008/09/29 11:49:48 danielk1977 Exp $
|
** @(#) $Id: pcache.c,v 1.34 2008/10/17 18:51:53 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@ -491,8 +491,6 @@ static void pcachePageFree(PgHdr *p){
|
|||||||
if( p->pCache->bPurgeable ){
|
if( p->pCache->bPurgeable ){
|
||||||
pcache_g.nCurrentPage--;
|
pcache_g.nCurrentPage--;
|
||||||
}
|
}
|
||||||
pcacheFree(p->apSave[0]);
|
|
||||||
pcacheFree(p->apSave[1]);
|
|
||||||
pcacheFree(p);
|
pcacheFree(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -813,7 +811,6 @@ void sqlite3PcacheMakeDirty(PgHdr *p){
|
|||||||
|
|
||||||
static void pcacheMakeClean(PgHdr *p){
|
static void pcacheMakeClean(PgHdr *p){
|
||||||
PCache *pCache = p->pCache;
|
PCache *pCache = p->pCache;
|
||||||
assert( p->apSave[0]==0 && p->apSave[1]==0 );
|
|
||||||
assert( p->flags & PGHDR_DIRTY );
|
assert( p->flags & PGHDR_DIRTY );
|
||||||
pcacheRemoveFromList(&pCache->pDirty, p);
|
pcacheRemoveFromList(&pCache->pDirty, p);
|
||||||
pcacheAddToList(&pCache->pClean, p);
|
pcacheAddToList(&pCache->pClean, p);
|
||||||
@ -844,7 +841,6 @@ void sqlite3PcacheCleanAll(PCache *pCache){
|
|||||||
PgHdr *p;
|
PgHdr *p;
|
||||||
pcacheEnterMutex();
|
pcacheEnterMutex();
|
||||||
while( (p = pCache->pDirty)!=0 ){
|
while( (p = pCache->pDirty)!=0 ){
|
||||||
assert( p->apSave[0]==0 && p->apSave[1]==0 );
|
|
||||||
pcacheRemoveFromList(&pCache->pDirty, p);
|
pcacheRemoveFromList(&pCache->pDirty, p);
|
||||||
p->flags &= ~PGHDR_DIRTY;
|
p->flags &= ~PGHDR_DIRTY;
|
||||||
pcacheAddToList(&pCache->pClean, p);
|
pcacheAddToList(&pCache->pClean, p);
|
||||||
@ -869,10 +865,6 @@ void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){
|
|||||||
pcacheRemoveFromHash(p);
|
pcacheRemoveFromHash(p);
|
||||||
p->pgno = newPgno;
|
p->pgno = newPgno;
|
||||||
if( newPgno==0 ){
|
if( newPgno==0 ){
|
||||||
pcacheFree(p->apSave[0]);
|
|
||||||
pcacheFree(p->apSave[1]);
|
|
||||||
p->apSave[0] = 0;
|
|
||||||
p->apSave[1] = 0;
|
|
||||||
if( (p->flags & PGHDR_DIRTY) ){
|
if( (p->flags & PGHDR_DIRTY) ){
|
||||||
pcacheMakeClean(p);
|
pcacheMakeClean(p);
|
||||||
}
|
}
|
||||||
@ -970,72 +962,6 @@ void sqlite3PcacheClose(PCache *pCache){
|
|||||||
pcacheExitMutex();
|
pcacheExitMutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
** Preserve the content of the page. It is assumed that the content
|
|
||||||
** has not been preserved already.
|
|
||||||
**
|
|
||||||
** If idJournal==0 then this is for the overall transaction.
|
|
||||||
** If idJournal==1 then this is for the statement journal.
|
|
||||||
**
|
|
||||||
** This routine is used for in-memory databases only.
|
|
||||||
**
|
|
||||||
** Return SQLITE_OK or SQLITE_NOMEM if a memory allocation fails.
|
|
||||||
*/
|
|
||||||
int sqlite3PcachePreserve(PgHdr *p, int idJournal){
|
|
||||||
void *x;
|
|
||||||
int sz;
|
|
||||||
assert( p->pCache->bPurgeable==0 );
|
|
||||||
assert( p->apSave[idJournal]==0 );
|
|
||||||
sz = p->pCache->szPage;
|
|
||||||
p->apSave[idJournal] = x = sqlite3PageMalloc( sz );
|
|
||||||
if( x==0 ) return SQLITE_NOMEM;
|
|
||||||
memcpy(x, p->pData, sz);
|
|
||||||
return SQLITE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Commit a change previously preserved.
|
|
||||||
*/
|
|
||||||
void sqlite3PcacheCommit(PCache *pCache, int idJournal){
|
|
||||||
PgHdr *p;
|
|
||||||
int mask = idJournal==0 ? ~PGHDR_IN_JOURNAL : 0xffffff;
|
|
||||||
pcacheEnterMutex(); /* Mutex is required to call pcacheFree() */
|
|
||||||
for(p=pCache->pDirty; p; p=p->pNext){
|
|
||||||
if( p->apSave[idJournal] ){
|
|
||||||
pcacheFree(p->apSave[idJournal]);
|
|
||||||
p->apSave[idJournal] = 0;
|
|
||||||
}
|
|
||||||
p->flags &= mask;
|
|
||||||
}
|
|
||||||
pcacheExitMutex();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Rollback a change previously preserved.
|
|
||||||
*/
|
|
||||||
void sqlite3PcacheRollback(
|
|
||||||
PCache *pCache, /* Pager cache */
|
|
||||||
int idJournal, /* Which copy to rollback to */
|
|
||||||
void (*xReiniter)(PgHdr*) /* Called on each rolled back page */
|
|
||||||
){
|
|
||||||
PgHdr *p;
|
|
||||||
int sz;
|
|
||||||
int mask = idJournal==0 ? ~PGHDR_IN_JOURNAL : 0xffffff;
|
|
||||||
pcacheEnterMutex(); /* Mutex is required to call pcacheFree() */
|
|
||||||
sz = pCache->szPage;
|
|
||||||
for(p=pCache->pDirty; p; p=p->pNext){
|
|
||||||
if( p->apSave[idJournal] ){
|
|
||||||
memcpy(p->pData, p->apSave[idJournal], sz);
|
|
||||||
pcacheFree(p->apSave[idJournal]);
|
|
||||||
p->apSave[idJournal] = 0;
|
|
||||||
if( xReiniter ){
|
|
||||||
xReiniter(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p->flags &= mask;
|
|
||||||
}
|
|
||||||
pcacheExitMutex();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
/*
|
/*
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
** This header file defines the interface that the sqlite page cache
|
** This header file defines the interface that the sqlite page cache
|
||||||
** subsystem.
|
** subsystem.
|
||||||
**
|
**
|
||||||
** @(#) $Id: pcache.h,v 1.13 2008/10/11 17:42:29 drh Exp $
|
** @(#) $Id: pcache.h,v 1.14 2008/10/17 18:51:53 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _PCACHE_H_
|
#ifndef _PCACHE_H_
|
||||||
@ -40,7 +40,7 @@ struct PgHdr {
|
|||||||
*/
|
*/
|
||||||
i16 nRef; /* Number of users of this page */
|
i16 nRef; /* Number of users of this page */
|
||||||
PCache *pCache; /* Cache that owns this page */
|
PCache *pCache; /* Cache that owns this page */
|
||||||
void *apSave[2]; /* Journal entries for in-memory databases */
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
** Elements above are accessible at any time by the owner of the cache
|
** Elements above are accessible at any time by the owner of the cache
|
||||||
** without the need for a mutex. The elements that follow can only be
|
** without the need for a mutex. The elements that follow can only be
|
||||||
@ -109,11 +109,6 @@ void sqlite3PcacheMove(PgHdr*, Pgno);
|
|||||||
/* Remove all pages with pgno>x. Reset the cache if x==0 */
|
/* Remove all pages with pgno>x. Reset the cache if x==0 */
|
||||||
void sqlite3PcacheTruncate(PCache*, Pgno x);
|
void sqlite3PcacheTruncate(PCache*, Pgno x);
|
||||||
|
|
||||||
/* Routines used to implement transactions on memory-only databases. */
|
|
||||||
int sqlite3PcachePreserve(PgHdr*, int); /* Preserve current page content */
|
|
||||||
void sqlite3PcacheCommit(PCache*, int); /* Drop preserved copy */
|
|
||||||
void sqlite3PcacheRollback(PCache*, int, void (*xReiniter)(PgHdr*));
|
|
||||||
|
|
||||||
/* Get a list of all dirty pages in the cache, sorted by page number */
|
/* Get a list of all dirty pages in the cache, sorted by page number */
|
||||||
PgHdr *sqlite3PcacheDirtyList(PCache*);
|
PgHdr *sqlite3PcacheDirtyList(PCache*);
|
||||||
|
|
||||||
|
11
src/pragma.c
11
src/pragma.c
@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** This file contains code used to implement the PRAGMA command.
|
** This file contains code used to implement the PRAGMA command.
|
||||||
**
|
**
|
||||||
** $Id: pragma.c,v 1.189 2008/10/10 17:47:21 danielk1977 Exp $
|
** $Id: pragma.c,v 1.190 2008/10/17 18:51:53 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -455,11 +455,13 @@ void sqlite3Pragma(
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** PRAGMA [database.]journal_mode
|
** PRAGMA [database.]journal_mode
|
||||||
** PRAGMA [database.]journal_mode = (delete|persist|off)
|
** PRAGMA [database.]journal_mode = (delete|persist|memory|off)
|
||||||
*/
|
*/
|
||||||
if( sqlite3StrICmp(zLeft,"journal_mode")==0 ){
|
if( sqlite3StrICmp(zLeft,"journal_mode")==0 ){
|
||||||
int eMode;
|
int eMode;
|
||||||
static char * const azModeName[] = {"delete", "persist", "off", "truncate"};
|
static char * const azModeName[] = {
|
||||||
|
"delete", "persist", "off", "truncate", "memory"
|
||||||
|
};
|
||||||
|
|
||||||
if( zRight==0 ){
|
if( zRight==0 ){
|
||||||
eMode = PAGER_JOURNALMODE_QUERY;
|
eMode = PAGER_JOURNALMODE_QUERY;
|
||||||
@ -503,7 +505,8 @@ void sqlite3Pragma(
|
|||||||
assert( eMode==PAGER_JOURNALMODE_DELETE
|
assert( eMode==PAGER_JOURNALMODE_DELETE
|
||||||
|| eMode==PAGER_JOURNALMODE_TRUNCATE
|
|| eMode==PAGER_JOURNALMODE_TRUNCATE
|
||||||
|| eMode==PAGER_JOURNALMODE_PERSIST
|
|| eMode==PAGER_JOURNALMODE_PERSIST
|
||||||
|| eMode==PAGER_JOURNALMODE_OFF );
|
|| eMode==PAGER_JOURNALMODE_OFF
|
||||||
|
|| eMode==PAGER_JOURNALMODE_MEMORY );
|
||||||
sqlite3VdbeSetNumCols(v, 1);
|
sqlite3VdbeSetNumCols(v, 1);
|
||||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "journal_mode", P4_STATIC);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "journal_mode", P4_STATIC);
|
||||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0,
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0,
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** Internal interface definitions for SQLite.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqliteInt.h,v 1.784 2008/10/13 15:35:09 drh Exp $
|
** @(#) $Id: sqliteInt.h,v 1.785 2008/10/17 18:51:53 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITEINT_H_
|
#ifndef _SQLITEINT_H_
|
||||||
#define _SQLITEINT_H_
|
#define _SQLITEINT_H_
|
||||||
@ -2505,6 +2505,10 @@ int sqlite3FindInIndex(Parse *, Expr *, int*);
|
|||||||
#define sqlite3JournalSize(pVfs) ((pVfs)->szOsFile)
|
#define sqlite3JournalSize(pVfs) ((pVfs)->szOsFile)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void sqlite3MemJournalOpen(sqlite3_file *);
|
||||||
|
int sqlite3MemJournalSize();
|
||||||
|
int sqlite3IsMemJournal(sqlite3_file *);
|
||||||
|
|
||||||
#if SQLITE_MAX_EXPR_DEPTH>0
|
#if SQLITE_MAX_EXPR_DEPTH>0
|
||||||
void sqlite3ExprSetHeight(Parse *pParse, Expr *p);
|
void sqlite3ExprSetHeight(Parse *pParse, Expr *p);
|
||||||
int sqlite3SelectExprHeight(Select *);
|
int sqlite3SelectExprHeight(Select *);
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
# This file implements regression tests for SQLite library. The focus
|
# This file implements regression tests for SQLite library. The focus
|
||||||
# of these tests is the journal mode pragma.
|
# of these tests is the journal mode pragma.
|
||||||
#
|
#
|
||||||
# $Id: jrnlmode.test,v 1.6 2008/09/26 21:08:08 drh Exp $
|
# $Id: jrnlmode.test,v 1.7 2008/10/17 18:51:53 danielk1977 Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@ -95,7 +95,7 @@ ifcapable attach {
|
|||||||
PRAGMA main.journal_mode;
|
PRAGMA main.journal_mode;
|
||||||
PRAGMA aux1.journal_mode;
|
PRAGMA aux1.journal_mode;
|
||||||
}
|
}
|
||||||
} {persist persist}
|
} {persist memory}
|
||||||
do_test jrnlmode-1.10 {
|
do_test jrnlmode-1.10 {
|
||||||
execsql {
|
execsql {
|
||||||
PRAGMA main.journal_mode = OFF;
|
PRAGMA main.journal_mode = OFF;
|
||||||
@ -105,7 +105,7 @@ ifcapable attach {
|
|||||||
PRAGMA temp.journal_mode;
|
PRAGMA temp.journal_mode;
|
||||||
PRAGMA aux1.journal_mode;
|
PRAGMA aux1.journal_mode;
|
||||||
}
|
}
|
||||||
} {off persist persist}
|
} {off persist memory}
|
||||||
do_test jrnlmode-1.11 {
|
do_test jrnlmode-1.11 {
|
||||||
execsql {
|
execsql {
|
||||||
PRAGMA journal_mode;
|
PRAGMA journal_mode;
|
||||||
@ -120,8 +120,9 @@ ifcapable attach {
|
|||||||
PRAGMA aux1.journal_mode;
|
PRAGMA aux1.journal_mode;
|
||||||
PRAGMA aux2.journal_mode;
|
PRAGMA aux2.journal_mode;
|
||||||
}
|
}
|
||||||
} {off persist persist}
|
} {off memory memory}
|
||||||
do_test jrnlmode-1.11 {
|
do_test jrnlmode-1.11 {
|
||||||
|
# The journal-mode used by in-memory databases cannot be changed.
|
||||||
execsql {
|
execsql {
|
||||||
PRAGMA aux1.journal_mode = DELETE;
|
PRAGMA aux1.journal_mode = DELETE;
|
||||||
}
|
}
|
||||||
@ -130,7 +131,7 @@ ifcapable attach {
|
|||||||
PRAGMA aux1.journal_mode;
|
PRAGMA aux1.journal_mode;
|
||||||
PRAGMA aux2.journal_mode;
|
PRAGMA aux2.journal_mode;
|
||||||
}
|
}
|
||||||
} {off delete persist}
|
} {off memory memory}
|
||||||
do_test jrnlmode-1.12 {
|
do_test jrnlmode-1.12 {
|
||||||
execsql {
|
execsql {
|
||||||
PRAGMA journal_mode = delete;
|
PRAGMA journal_mode = delete;
|
||||||
@ -141,7 +142,7 @@ ifcapable attach {
|
|||||||
PRAGMA aux1.journal_mode;
|
PRAGMA aux1.journal_mode;
|
||||||
PRAGMA aux2.journal_mode;
|
PRAGMA aux2.journal_mode;
|
||||||
}
|
}
|
||||||
} {delete delete delete delete}
|
} {delete delete memory memory}
|
||||||
do_test jrnlmode-1.13 {
|
do_test jrnlmode-1.13 {
|
||||||
execsql {
|
execsql {
|
||||||
ATTACH ':memory:' as aux3;
|
ATTACH ':memory:' as aux3;
|
||||||
@ -153,7 +154,7 @@ ifcapable attach {
|
|||||||
PRAGMA aux2.journal_mode;
|
PRAGMA aux2.journal_mode;
|
||||||
PRAGMA aux3.journal_mode;
|
PRAGMA aux3.journal_mode;
|
||||||
}
|
}
|
||||||
} {delete delete delete delete delete}
|
} {delete delete memory memory memory}
|
||||||
do_test jrnlmode-1.14 {
|
do_test jrnlmode-1.14 {
|
||||||
execsql {
|
execsql {
|
||||||
PRAGMA journal_mode = TRUNCATE;
|
PRAGMA journal_mode = TRUNCATE;
|
||||||
@ -165,7 +166,7 @@ ifcapable attach {
|
|||||||
PRAGMA aux2.journal_mode;
|
PRAGMA aux2.journal_mode;
|
||||||
PRAGMA aux3.journal_mode;
|
PRAGMA aux3.journal_mode;
|
||||||
}
|
}
|
||||||
} {truncate truncate truncate truncate truncate}
|
} {truncate truncate memory memory memory}
|
||||||
|
|
||||||
do_test jrnlmode-1.99 {
|
do_test jrnlmode-1.99 {
|
||||||
execsql {
|
execsql {
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
# This file implements regression tests for SQLite library. The
|
# This file implements regression tests for SQLite library. The
|
||||||
# focus of this script is page cache subsystem.
|
# focus of this script is page cache subsystem.
|
||||||
#
|
#
|
||||||
# $Id: pager.test,v 1.31 2008/08/20 14:49:25 danielk1977 Exp $
|
# $Id: pager.test,v 1.32 2008/10/17 18:51:53 danielk1977 Exp $
|
||||||
|
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
@ -415,12 +415,14 @@ ifcapable memorydb {
|
|||||||
pager_truncate $::p2 5
|
pager_truncate $::p2 5
|
||||||
} {}
|
} {}
|
||||||
do_test pager-4.6.3 {
|
do_test pager-4.6.3 {
|
||||||
|
set page1 [page_get $::p2 1]
|
||||||
for {set i 1} {$i<5} {incr i} {
|
for {set i 1} {$i<5} {incr i} {
|
||||||
set p [page_get $::p2 $i]
|
set p [page_get $::p2 $i]
|
||||||
page_write $p "Page $i"
|
page_write $p "Page $i"
|
||||||
pager_commit $::p2
|
pager_commit $::p2
|
||||||
page_unref $p
|
page_unref $p
|
||||||
}
|
}
|
||||||
|
page_unref $page1
|
||||||
# pager_truncate $::p2 3
|
# pager_truncate $::p2 3
|
||||||
} {}
|
} {}
|
||||||
do_test pager-4.6.4 {
|
do_test pager-4.6.4 {
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
# This file implements regression tests for SQLite library. The
|
# This file implements regression tests for SQLite library. The
|
||||||
# focus of this script is page cache subsystem.
|
# focus of this script is page cache subsystem.
|
||||||
#
|
#
|
||||||
# $Id: pager2.test,v 1.7 2008/08/20 14:49:25 danielk1977 Exp $
|
# $Id: pager2.test,v 1.8 2008/10/17 18:51:53 danielk1977 Exp $
|
||||||
|
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
@ -33,13 +33,13 @@ do_test pager2-1.0 {
|
|||||||
} {0}
|
} {0}
|
||||||
do_test pager2-1.1 {
|
do_test pager2-1.1 {
|
||||||
pager_stats $::p1
|
pager_stats $::p1
|
||||||
} {ref 0 page 0 max 10 size 0 state 0 err 0 hit 0 miss 0 ovfl 0}
|
} {ref 0 page 0 max 10 size 0 state 4 err 0 hit 0 miss 0 ovfl 0}
|
||||||
do_test pager2-1.2 {
|
do_test pager2-1.2 {
|
||||||
pager_pagecount $::p1
|
pager_pagecount $::p1
|
||||||
} {0}
|
} {0}
|
||||||
do_test pager2-1.3 {
|
do_test pager2-1.3 {
|
||||||
pager_stats $::p1
|
pager_stats $::p1
|
||||||
} {ref 0 page 0 max 10 size 0 state 0 err 0 hit 0 miss 0 ovfl 0}
|
} {ref 0 page 0 max 10 size 0 state 4 err 0 hit 0 miss 0 ovfl 0}
|
||||||
do_test pager2-1.4 {
|
do_test pager2-1.4 {
|
||||||
pager_close $::p1
|
pager_close $::p1
|
||||||
} {}
|
} {}
|
||||||
@ -62,7 +62,7 @@ do_test pager2-2.3.1 {
|
|||||||
} {}
|
} {}
|
||||||
do_test pager2-2.3.2 {
|
do_test pager2-2.3.2 {
|
||||||
pager_stats $::p1
|
pager_stats $::p1
|
||||||
} {ref 0 page 0 max 10 size 0 state 0 err 0 hit 0 miss 0 ovfl 0}
|
} {ref 0 page 0 max 10 size 0 state 4 err 0 hit 0 miss 0 ovfl 0}
|
||||||
do_test pager2-2.3.3 {
|
do_test pager2-2.3.3 {
|
||||||
set v [catch {
|
set v [catch {
|
||||||
set ::g1 [page_get $::p1 1]
|
set ::g1 [page_get $::p1 1]
|
||||||
@ -72,7 +72,7 @@ do_test pager2-2.3.3 {
|
|||||||
} {0}
|
} {0}
|
||||||
do_test pager2-2.3.3 {
|
do_test pager2-2.3.3 {
|
||||||
pager_stats $::p1
|
pager_stats $::p1
|
||||||
} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0}
|
} {ref 1 page 1 max 10 size 0 state 4 err 0 hit 0 miss 1 ovfl 0}
|
||||||
do_test pager2-2.3.4 {
|
do_test pager2-2.3.4 {
|
||||||
set ::gx [page_lookup $::p1 1]
|
set ::gx [page_lookup $::p1 1]
|
||||||
page_unref $::gx
|
page_unref $::gx
|
||||||
@ -80,22 +80,22 @@ do_test pager2-2.3.4 {
|
|||||||
} {1}
|
} {1}
|
||||||
do_test pager2-2.3.5 {
|
do_test pager2-2.3.5 {
|
||||||
pager_stats $::p1
|
pager_stats $::p1
|
||||||
} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0}
|
} {ref 1 page 1 max 10 size 0 state 4 err 0 hit 0 miss 1 ovfl 0}
|
||||||
do_test pager2-2.3.6 {
|
do_test pager2-2.3.6 {
|
||||||
expr {$::g1==$::gx}
|
expr {$::g1==$::gx}
|
||||||
} {1}
|
} {1}
|
||||||
do_test pager2-2.3.7 {
|
do_test pager2-2.3.7 {
|
||||||
pager_stats $::p1
|
pager_stats $::p1
|
||||||
} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0}
|
} {ref 1 page 1 max 10 size 0 state 4 err 0 hit 0 miss 1 ovfl 0}
|
||||||
do_test pager2-2.4 {
|
do_test pager2-2.4 {
|
||||||
pager_stats $::p1
|
pager_stats $::p1
|
||||||
} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0}
|
} {ref 1 page 1 max 10 size 0 state 4 err 0 hit 0 miss 1 ovfl 0}
|
||||||
do_test pager2-2.5 {
|
do_test pager2-2.5 {
|
||||||
pager_pagecount $::p1
|
pager_pagecount $::p1
|
||||||
} {0}
|
} {0}
|
||||||
do_test pager2-2.6 {
|
do_test pager2-2.6 {
|
||||||
pager_stats $::p1
|
pager_stats $::p1
|
||||||
} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0}
|
} {ref 1 page 1 max 10 size 0 state 4 err 0 hit 0 miss 1 ovfl 0}
|
||||||
do_test pager2-2.7 {
|
do_test pager2-2.7 {
|
||||||
page_number $::g1
|
page_number $::g1
|
||||||
} {1}
|
} {1}
|
||||||
@ -107,7 +107,7 @@ do_test pager2-2.9 {
|
|||||||
} {}
|
} {}
|
||||||
do_test pager2-2.10 {
|
do_test pager2-2.10 {
|
||||||
pager_stats $::p1
|
pager_stats $::p1
|
||||||
} {ref 0 page 1 max 10 size 0 state 0 err 0 hit 0 miss 1 ovfl 0}
|
} {ref 0 page 1 max 10 size 0 state 4 err 0 hit 0 miss 1 ovfl 0}
|
||||||
do_test pager2-2.11 {
|
do_test pager2-2.11 {
|
||||||
set ::g1 [page_get $::p1 1]
|
set ::g1 [page_get $::p1 1]
|
||||||
expr {$::g1!=0}
|
expr {$::g1!=0}
|
||||||
@ -117,7 +117,7 @@ do_test pager2-2.12 {
|
|||||||
} {1}
|
} {1}
|
||||||
do_test pager2-2.13 {
|
do_test pager2-2.13 {
|
||||||
pager_stats $::p1
|
pager_stats $::p1
|
||||||
} {ref 1 page 1 max 10 size 0 state 1 err 0 hit 1 miss 1 ovfl 0}
|
} {ref 1 page 1 max 10 size 0 state 4 err 0 hit 1 miss 1 ovfl 0}
|
||||||
do_test pager2-2.14 {
|
do_test pager2-2.14 {
|
||||||
set v [catch {
|
set v [catch {
|
||||||
page_write $::g1 "Page-One"
|
page_write $::g1 "Page-One"
|
||||||
@ -138,19 +138,19 @@ do_test pager2-2.17 {
|
|||||||
} {0 {}}
|
} {0 {}}
|
||||||
do_test pager2-2.20 {
|
do_test pager2-2.20 {
|
||||||
pager_stats $::p1
|
pager_stats $::p1
|
||||||
} {ref 1 page 1 max 10 size 1 state 1 err 0 hit 1 miss 1 ovfl 0}
|
} {ref 1 page 1 max 10 size 1 state 4 err 0 hit 1 miss 1 ovfl 0}
|
||||||
do_test pager2-2.19 {
|
do_test pager2-2.19 {
|
||||||
pager_pagecount $::p1
|
pager_pagecount $::p1
|
||||||
} {1}
|
} {1}
|
||||||
do_test pager2-2.21 {
|
do_test pager2-2.21 {
|
||||||
pager_stats $::p1
|
pager_stats $::p1
|
||||||
} {ref 1 page 1 max 10 size 1 state 1 err 0 hit 1 miss 1 ovfl 0}
|
} {ref 1 page 1 max 10 size 1 state 4 err 0 hit 1 miss 1 ovfl 0}
|
||||||
do_test pager2-2.22 {
|
do_test pager2-2.22 {
|
||||||
page_unref $::g1
|
page_unref $::g1
|
||||||
} {}
|
} {}
|
||||||
do_test pager2-2.23 {
|
do_test pager2-2.23 {
|
||||||
pager_stats $::p1
|
pager_stats $::p1
|
||||||
} {ref 0 page 1 max 10 size 1 state 0 err 0 hit 1 miss 1 ovfl 0}
|
} {ref 0 page 1 max 10 size 1 state 4 err 0 hit 1 miss 1 ovfl 0}
|
||||||
do_test pager2-2.24 {
|
do_test pager2-2.24 {
|
||||||
set v [catch {
|
set v [catch {
|
||||||
page_get $::p1 1
|
page_get $::p1 1
|
||||||
@ -215,14 +215,17 @@ do_test pager2-3.5 {
|
|||||||
page_unref $::g(1)
|
page_unref $::g(1)
|
||||||
} {}
|
} {}
|
||||||
for {set i 2} {$i<=20} {incr i} {
|
for {set i 2} {$i<=20} {incr i} {
|
||||||
|
set page1 [page_get $::p1 1]
|
||||||
do_test pager2-3.6.[expr {$i-1}] [subst {
|
do_test pager2-3.6.[expr {$i-1}] [subst {
|
||||||
set gx \[page_get $::p1 $i\]
|
set gx \[page_get $::p1 $i\]
|
||||||
set v \[page_read \$gx\]
|
set v \[page_read \$gx\]
|
||||||
page_unref \$gx
|
page_unref \$gx
|
||||||
set v
|
set v
|
||||||
}] "Page-$i"
|
}] "Page-$i"
|
||||||
|
page_unref $page1
|
||||||
}
|
}
|
||||||
for {set i 1} {$i<=20} {incr i} {
|
for {set i 1} {$i<=20} {incr i} {
|
||||||
|
set page1 [page_get $::p1 1]
|
||||||
regsub -all CNT {
|
regsub -all CNT {
|
||||||
set ::g1 [page_get $::p1 CNT]
|
set ::g1 [page_get $::p1 CNT]
|
||||||
set ::g2 [page_get $::p1 CNT]
|
set ::g2 [page_get $::p1 CNT]
|
||||||
@ -244,6 +247,7 @@ for {set i 1} {$i<=20} {incr i} {
|
|||||||
expr {$vy==$::vx}
|
expr {$vy==$::vx}
|
||||||
} $i body;
|
} $i body;
|
||||||
do_test pager2-3.7.$i.3 $body {1}
|
do_test pager2-3.7.$i.3 $body {1}
|
||||||
|
page_unref $page1
|
||||||
}
|
}
|
||||||
do_test pager2-3.99 {
|
do_test pager2-3.99 {
|
||||||
pager_close $::p1
|
pager_close $::p1
|
||||||
@ -281,7 +285,7 @@ do_test pager2-4.3 {
|
|||||||
} {ref 1}
|
} {ref 1}
|
||||||
do_test pager2-4.4 {
|
do_test pager2-4.4 {
|
||||||
lrange [pager_stats $::p1] 8 9
|
lrange [pager_stats $::p1] 8 9
|
||||||
} {state 1}
|
} {state 4}
|
||||||
|
|
||||||
for {set i 1} {$i<20} {incr i} {
|
for {set i 1} {$i<20} {incr i} {
|
||||||
do_test pager2-4.5.$i.0 {
|
do_test pager2-4.5.$i.0 {
|
||||||
@ -396,7 +400,7 @@ breakpoint
|
|||||||
do_test pager2-4.5.$i.10 {
|
do_test pager2-4.5.$i.10 {
|
||||||
pager_commit $p1
|
pager_commit $p1
|
||||||
lrange [pager_stats $p1] 8 9
|
lrange [pager_stats $p1] 8 9
|
||||||
} {state 1}
|
} {state 4}
|
||||||
}
|
}
|
||||||
|
|
||||||
do_test pager2-4.99 {
|
do_test pager2-4.99 {
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#
|
#
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
#
|
#
|
||||||
# $Id: permutations.test,v 1.35 2008/10/11 17:04:04 danielk1977 Exp $
|
# $Id: permutations.test,v 1.36 2008/10/17 18:51:53 danielk1977 Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@ -448,6 +448,24 @@ run_tests "autovacuum_ioerr" -description {
|
|||||||
pragma auto_vacuum = 1
|
pragma auto_vacuum = 1
|
||||||
} -include ioerr.test
|
} -include ioerr.test
|
||||||
|
|
||||||
|
# Run tests with an in-memory journal.
|
||||||
|
#
|
||||||
|
run_tests "inmemory_journal" -description {
|
||||||
|
Run tests with an in-memory journal file.
|
||||||
|
} -presql {
|
||||||
|
pragma journal_mode = 'memory'
|
||||||
|
} -exclude {
|
||||||
|
# Exclude all tests that simulate IO errors.
|
||||||
|
autovacuum_ioerr2.test incrvacuum_ioerr.test ioerr.test
|
||||||
|
ioerr.test ioerr2.test ioerr3.test ioerr4.test ioerr5.test
|
||||||
|
vacuum3.test incrblob_err.test diskfull.test
|
||||||
|
|
||||||
|
# Exclude test scripts that use tcl IO to access journal files or count
|
||||||
|
# the number of fsync() calls.
|
||||||
|
pager.test exclusive.test jrnlmode.test sync.test misc1.test
|
||||||
|
journal1.test conflict.test
|
||||||
|
}
|
||||||
|
|
||||||
ifcapable mem3 {
|
ifcapable mem3 {
|
||||||
run_tests "memsys3" -description {
|
run_tests "memsys3" -description {
|
||||||
Run tests using the allocator in mem3.c.
|
Run tests using the allocator in mem3.c.
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
# caused by an ON CONFLICT ROLLBACK clause aborts any other pending
|
# caused by an ON CONFLICT ROLLBACK clause aborts any other pending
|
||||||
# statements.
|
# statements.
|
||||||
#
|
#
|
||||||
# $Id: rollback.test,v 1.9 2008/10/13 14:16:11 drh Exp $
|
# $Id: rollback.test,v 1.10 2008/10/17 18:51:53 danielk1977 Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@ -81,7 +81,10 @@ do_test rollback-1.9 {
|
|||||||
|
|
||||||
set permutation ""
|
set permutation ""
|
||||||
catch {set permutation $::permutations_test_prefix}
|
catch {set permutation $::permutations_test_prefix}
|
||||||
if {$tcl_platform(platform) == "unix" && $permutation ne "onefile"} {
|
if {$tcl_platform(platform) == "unix"
|
||||||
|
&& $permutation ne "onefile"
|
||||||
|
&& $permutation ne "inmemory_journal"
|
||||||
|
} {
|
||||||
do_test rollback-2.1 {
|
do_test rollback-2.1 {
|
||||||
execsql {
|
execsql {
|
||||||
BEGIN;
|
BEGIN;
|
||||||
|
@ -247,6 +247,7 @@ foreach file {
|
|||||||
vdbe.c
|
vdbe.c
|
||||||
vdbeblob.c
|
vdbeblob.c
|
||||||
journal.c
|
journal.c
|
||||||
|
memjournal.c
|
||||||
|
|
||||||
walker.c
|
walker.c
|
||||||
resolve.c
|
resolve.c
|
||||||
|
Reference in New Issue
Block a user