blob: ced0016bb2dcb4ac65eb09fe8a807195ef5a21e1 [file] [log] [blame]
drhed7c8552001-04-11 14:29:21 +00001/*
drhb19a2bc2001-09-16 00:13:26 +00002** 2001 September 15
drhed7c8552001-04-11 14:29:21 +00003**
drhb19a2bc2001-09-16 00:13:26 +00004** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
drhed7c8552001-04-11 14:29:21 +00006**
drhb19a2bc2001-09-16 00:13:26 +00007** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
drhed7c8552001-04-11 14:29:21 +000010**
11*************************************************************************
drhb19a2bc2001-09-16 00:13:26 +000012** This is the implementation of the page cache subsystem or "pager".
drhed7c8552001-04-11 14:29:21 +000013**
drhb19a2bc2001-09-16 00:13:26 +000014** The pager is used to access a database disk file. It implements
15** atomic commit and rollback through the use of a journal file that
16** is separate from the database file. The pager also implements file
17** locking to prevent two processes from writing the same database
18** file simultaneously, or one process from reading the database while
19** another is writing.
drhed7c8552001-04-11 14:29:21 +000020**
drhcd61c282002-03-06 22:01:34 +000021** @(#) $Id: pager.c,v 1.44 2002/03/06 22:01:36 drh Exp $
drhed7c8552001-04-11 14:29:21 +000022*/
drhd9b02572001-04-15 00:37:09 +000023#include "sqliteInt.h"
drhed7c8552001-04-11 14:29:21 +000024#include "pager.h"
drh8cfbf082001-09-19 13:22:39 +000025#include "os.h"
drhed7c8552001-04-11 14:29:21 +000026#include <assert.h>
drhd9b02572001-04-15 00:37:09 +000027#include <string.h>
drhed7c8552001-04-11 14:29:21 +000028
29/*
30** The page cache as a whole is always in one of the following
31** states:
32**
33** SQLITE_UNLOCK The page cache is not currently reading or
34** writing the database file. There is no
35** data held in memory. This is the initial
36** state.
37**
38** SQLITE_READLOCK The page cache is reading the database.
39** Writing is not permitted. There can be
40** multiple readers accessing the same database
drh69688d52001-04-14 16:38:23 +000041** file at the same time.
drhed7c8552001-04-11 14:29:21 +000042**
43** SQLITE_WRITELOCK The page cache is writing the database.
44** Access is exclusive. No other processes or
45** threads can be reading or writing while one
46** process is writing.
47**
drh306dc212001-05-21 13:45:10 +000048** The page cache comes up in SQLITE_UNLOCK. The first time a
49** sqlite_page_get() occurs, the state transitions to SQLITE_READLOCK.
drhed7c8552001-04-11 14:29:21 +000050** After all pages have been released using sqlite_page_unref(),
drh306dc212001-05-21 13:45:10 +000051** the state transitions back to SQLITE_UNLOCK. The first time
drhed7c8552001-04-11 14:29:21 +000052** that sqlite_page_write() is called, the state transitions to
drh306dc212001-05-21 13:45:10 +000053** SQLITE_WRITELOCK. (Note that sqlite_page_write() can only be
54** called on an outstanding page which means that the pager must
55** be in SQLITE_READLOCK before it transitions to SQLITE_WRITELOCK.)
56** The sqlite_page_rollback() and sqlite_page_commit() functions
57** transition the state from SQLITE_WRITELOCK back to SQLITE_READLOCK.
drhed7c8552001-04-11 14:29:21 +000058*/
59#define SQLITE_UNLOCK 0
60#define SQLITE_READLOCK 1
61#define SQLITE_WRITELOCK 2
62
drhd9b02572001-04-15 00:37:09 +000063
drhed7c8552001-04-11 14:29:21 +000064/*
65** Each in-memory image of a page begins with the following header.
drhbd03cae2001-06-02 02:40:57 +000066** This header is only visible to this pager module. The client
67** code that calls pager sees only the data that follows the header.
drhed7c8552001-04-11 14:29:21 +000068*/
drhd9b02572001-04-15 00:37:09 +000069typedef struct PgHdr PgHdr;
drhed7c8552001-04-11 14:29:21 +000070struct PgHdr {
71 Pager *pPager; /* The pager to which this page belongs */
72 Pgno pgno; /* The page number for this page */
drh69688d52001-04-14 16:38:23 +000073 PgHdr *pNextHash, *pPrevHash; /* Hash collision chain for PgHdr.pgno */
drhed7c8552001-04-11 14:29:21 +000074 int nRef; /* Number of users of this page */
drhd9b02572001-04-15 00:37:09 +000075 PgHdr *pNextFree, *pPrevFree; /* Freelist of pages where nRef==0 */
76 PgHdr *pNextAll, *pPrevAll; /* A list of all pages */
drhed7c8552001-04-11 14:29:21 +000077 char inJournal; /* TRUE if has been written to journal */
drhfa86c412002-02-02 15:01:15 +000078 char inCkpt; /* TRUE if written to the checkpoint journal */
drhed7c8552001-04-11 14:29:21 +000079 char dirty; /* TRUE if we need to write back changes */
drh69688d52001-04-14 16:38:23 +000080 /* SQLITE_PAGE_SIZE bytes of page data follow this header */
drh7e3b0a02001-04-28 16:52:40 +000081 /* Pager.nExtra bytes of local data follow the page data */
drhed7c8552001-04-11 14:29:21 +000082};
83
84/*
drh69688d52001-04-14 16:38:23 +000085** Convert a pointer to a PgHdr into a pointer to its data
86** and back again.
drhed7c8552001-04-11 14:29:21 +000087*/
88#define PGHDR_TO_DATA(P) ((void*)(&(P)[1]))
89#define DATA_TO_PGHDR(D) (&((PgHdr*)(D))[-1])
drh7e3b0a02001-04-28 16:52:40 +000090#define PGHDR_TO_EXTRA(P) ((void*)&((char*)(&(P)[1]))[SQLITE_PAGE_SIZE])
drhed7c8552001-04-11 14:29:21 +000091
92/*
drhed7c8552001-04-11 14:29:21 +000093** How big to make the hash table used for locating in-memory pages
drh306dc212001-05-21 13:45:10 +000094** by page number. Knuth says this should be a prime number.
drhed7c8552001-04-11 14:29:21 +000095*/
drh603240c2002-03-05 01:11:12 +000096#define N_PG_HASH 2003
drhed7c8552001-04-11 14:29:21 +000097
98/*
99** A open page cache is an instance of the following structure.
100*/
101struct Pager {
102 char *zFilename; /* Name of the database file */
103 char *zJournal; /* Name of the journal file */
drh8cfbf082001-09-19 13:22:39 +0000104 OsFile fd, jfd; /* File descriptors for database and journal */
drhfa86c412002-02-02 15:01:15 +0000105 OsFile cpfd; /* File descriptor for the checkpoint journal */
drhed7c8552001-04-11 14:29:21 +0000106 int dbSize; /* Number of pages in the file */
drh69688d52001-04-14 16:38:23 +0000107 int origDbSize; /* dbSize before the current change */
drhfa86c412002-02-02 15:01:15 +0000108 int ckptSize, ckptJSize; /* Size of database and journal at ckpt_begin() */
drh7e3b0a02001-04-28 16:52:40 +0000109 int nExtra; /* Add this many bytes to each in-memory page */
drh72f82862001-05-24 21:06:34 +0000110 void (*xDestructor)(void*); /* Call this routine when freeing pages */
drhed7c8552001-04-11 14:29:21 +0000111 int nPage; /* Total number of in-memory pages */
drhd9b02572001-04-15 00:37:09 +0000112 int nRef; /* Number of in-memory pages with PgHdr.nRef>0 */
drhed7c8552001-04-11 14:29:21 +0000113 int mxPage; /* Maximum number of pages to hold in cache */
drhd9b02572001-04-15 00:37:09 +0000114 int nHit, nMiss, nOvfl; /* Cache hits, missing, and LRU overflows */
drh603240c2002-03-05 01:11:12 +0000115 u8 journalOpen; /* True if journal file descriptors is valid */
116 u8 ckptOpen; /* True if the checkpoint journal is open */
117 u8 noSync; /* Do not sync the journal if true */
118 u8 state; /* SQLITE_UNLOCK, _READLOCK or _WRITELOCK */
119 u8 errMask; /* One of several kinds of errors */
120 u8 tempFile; /* zFilename is a temporary file */
121 u8 readOnly; /* True for a read-only database */
122 u8 needSync; /* True if an fsync() is needed on the journal */
123 u8 *aInJournal; /* One bit for each page in the database file */
124 u8 *aInCkpt; /* One bit for each page in the database */
drhed7c8552001-04-11 14:29:21 +0000125 PgHdr *pFirst, *pLast; /* List of free pages */
drhd9b02572001-04-15 00:37:09 +0000126 PgHdr *pAll; /* List of all pages */
drhed7c8552001-04-11 14:29:21 +0000127 PgHdr *aHash[N_PG_HASH]; /* Hash table to map page number of PgHdr */
drhd9b02572001-04-15 00:37:09 +0000128};
129
130/*
131** These are bits that can be set in Pager.errMask.
132*/
133#define PAGER_ERR_FULL 0x01 /* a write() failed */
134#define PAGER_ERR_MEM 0x02 /* malloc() failed */
135#define PAGER_ERR_LOCK 0x04 /* error in the locking protocol */
136#define PAGER_ERR_CORRUPT 0x08 /* database or journal corruption */
drh81a20f22001-10-12 17:30:04 +0000137#define PAGER_ERR_DISK 0x10 /* general disk I/O error - bad hard drive? */
drhd9b02572001-04-15 00:37:09 +0000138
139/*
140** The journal file contains page records in the following
141** format.
142*/
143typedef struct PageRecord PageRecord;
144struct PageRecord {
145 Pgno pgno; /* The page number */
146 char aData[SQLITE_PAGE_SIZE]; /* Original data for page pgno */
147};
148
149/*
drh5e00f6c2001-09-13 13:46:56 +0000150** Journal files begin with the following magic string. The data
151** was obtained from /dev/random. It is used only as a sanity check.
drhd9b02572001-04-15 00:37:09 +0000152*/
153static const unsigned char aJournalMagic[] = {
154 0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, 0xd4,
drhed7c8552001-04-11 14:29:21 +0000155};
156
157/*
158** Hash a page number
159*/
drhd9b02572001-04-15 00:37:09 +0000160#define pager_hash(PN) ((PN)%N_PG_HASH)
drhed7c8552001-04-11 14:29:21 +0000161
162/*
drhdd793422001-06-28 01:54:48 +0000163** Enable reference count tracking here:
164*/
165#if SQLITE_TEST
drh5e00f6c2001-09-13 13:46:56 +0000166 int pager_refinfo_enable = 0;
drhdd793422001-06-28 01:54:48 +0000167 static void pager_refinfo(PgHdr *p){
168 static int cnt = 0;
169 if( !pager_refinfo_enable ) return;
170 printf(
171 "REFCNT: %4d addr=0x%08x nRef=%d\n",
172 p->pgno, (int)PGHDR_TO_DATA(p), p->nRef
173 );
174 cnt++; /* Something to set a breakpoint on */
175 }
176# define REFINFO(X) pager_refinfo(X)
177#else
178# define REFINFO(X)
179#endif
180
181/*
drhd9b02572001-04-15 00:37:09 +0000182** Convert the bits in the pPager->errMask into an approprate
183** return code.
184*/
185static int pager_errcode(Pager *pPager){
186 int rc = SQLITE_OK;
187 if( pPager->errMask & PAGER_ERR_LOCK ) rc = SQLITE_PROTOCOL;
drh81a20f22001-10-12 17:30:04 +0000188 if( pPager->errMask & PAGER_ERR_DISK ) rc = SQLITE_IOERR;
drhd9b02572001-04-15 00:37:09 +0000189 if( pPager->errMask & PAGER_ERR_FULL ) rc = SQLITE_FULL;
190 if( pPager->errMask & PAGER_ERR_MEM ) rc = SQLITE_NOMEM;
191 if( pPager->errMask & PAGER_ERR_CORRUPT ) rc = SQLITE_CORRUPT;
192 return rc;
drhed7c8552001-04-11 14:29:21 +0000193}
194
195/*
196** Find a page in the hash table given its page number. Return
197** a pointer to the page or NULL if not found.
198*/
drhd9b02572001-04-15 00:37:09 +0000199static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){
drhed7c8552001-04-11 14:29:21 +0000200 PgHdr *p = pPager->aHash[pgno % N_PG_HASH];
201 while( p && p->pgno!=pgno ){
202 p = p->pNextHash;
203 }
204 return p;
205}
206
207/*
208** Unlock the database and clear the in-memory cache. This routine
209** sets the state of the pager back to what it was when it was first
210** opened. Any outstanding pages are invalidated and subsequent attempts
211** to access those pages will likely result in a coredump.
212*/
drhd9b02572001-04-15 00:37:09 +0000213static void pager_reset(Pager *pPager){
drhed7c8552001-04-11 14:29:21 +0000214 PgHdr *pPg, *pNext;
drhd9b02572001-04-15 00:37:09 +0000215 for(pPg=pPager->pAll; pPg; pPg=pNext){
216 pNext = pPg->pNextAll;
217 sqliteFree(pPg);
drhed7c8552001-04-11 14:29:21 +0000218 }
219 pPager->pFirst = 0;
drhd9b02572001-04-15 00:37:09 +0000220 pPager->pLast = 0;
221 pPager->pAll = 0;
drhed7c8552001-04-11 14:29:21 +0000222 memset(pPager->aHash, 0, sizeof(pPager->aHash));
223 pPager->nPage = 0;
drhfa86c412002-02-02 15:01:15 +0000224 if( pPager->state>=SQLITE_WRITELOCK ){
drhd9b02572001-04-15 00:37:09 +0000225 sqlitepager_rollback(pPager);
drhed7c8552001-04-11 14:29:21 +0000226 }
drha7fcb052001-12-14 15:09:55 +0000227 sqliteOsUnlock(&pPager->fd);
drhed7c8552001-04-11 14:29:21 +0000228 pPager->state = SQLITE_UNLOCK;
drhd9b02572001-04-15 00:37:09 +0000229 pPager->dbSize = -1;
drhed7c8552001-04-11 14:29:21 +0000230 pPager->nRef = 0;
drh8cfbf082001-09-19 13:22:39 +0000231 assert( pPager->journalOpen==0 );
drhed7c8552001-04-11 14:29:21 +0000232}
233
234/*
235** When this routine is called, the pager has the journal file open and
236** a write lock on the database. This routine releases the database
237** write lock and acquires a read lock in its place. The journal file
238** is deleted and closed.
drhed7c8552001-04-11 14:29:21 +0000239*/
drhd9b02572001-04-15 00:37:09 +0000240static int pager_unwritelock(Pager *pPager){
drhed7c8552001-04-11 14:29:21 +0000241 int rc;
drhd9b02572001-04-15 00:37:09 +0000242 PgHdr *pPg;
drhfa86c412002-02-02 15:01:15 +0000243 if( pPager->state<SQLITE_WRITELOCK ) return SQLITE_OK;
drh663fc632002-02-02 18:49:19 +0000244 sqlitepager_ckpt_commit(pPager);
drha7fcb052001-12-14 15:09:55 +0000245 sqliteOsClose(&pPager->jfd);
drh8cfbf082001-09-19 13:22:39 +0000246 pPager->journalOpen = 0;
247 sqliteOsDelete(pPager->zJournal);
drha7fcb052001-12-14 15:09:55 +0000248 rc = sqliteOsReadLock(&pPager->fd);
249 assert( rc==SQLITE_OK );
drh6019e162001-07-02 17:51:45 +0000250 sqliteFree( pPager->aInJournal );
251 pPager->aInJournal = 0;
drhd9b02572001-04-15 00:37:09 +0000252 for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
253 pPg->inJournal = 0;
254 pPg->dirty = 0;
255 }
drha7fcb052001-12-14 15:09:55 +0000256 pPager->state = SQLITE_READLOCK;
drhed7c8552001-04-11 14:29:21 +0000257 return rc;
258}
259
drhed7c8552001-04-11 14:29:21 +0000260/*
drhfa86c412002-02-02 15:01:15 +0000261** Read a single page from the journal file opened on file descriptor
262** jfd. Playback this one page.
263*/
264static int pager_playback_one_page(Pager *pPager, OsFile *jfd){
265 int rc;
266 PgHdr *pPg; /* An existing page in the cache */
267 PageRecord pgRec;
268
drh663fc632002-02-02 18:49:19 +0000269 rc = sqliteOsRead(jfd, &pgRec, sizeof(pgRec));
drhfa86c412002-02-02 15:01:15 +0000270 if( rc!=SQLITE_OK ) return rc;
271
272 /* Sanity checking on the page */
273 if( pgRec.pgno>pPager->dbSize || pgRec.pgno==0 ) return SQLITE_CORRUPT;
274
275 /* Playback the page. Update the in-memory copy of the page
276 ** at the same time, if there is one.
277 */
278 pPg = pager_lookup(pPager, pgRec.pgno);
279 if( pPg ){
280 memcpy(PGHDR_TO_DATA(pPg), pgRec.aData, SQLITE_PAGE_SIZE);
281 memset(PGHDR_TO_EXTRA(pPg), 0, pPager->nExtra);
282 }
283 rc = sqliteOsSeek(&pPager->fd, (pgRec.pgno-1)*SQLITE_PAGE_SIZE);
284 if( rc==SQLITE_OK ){
285 rc = sqliteOsWrite(&pPager->fd, pgRec.aData, SQLITE_PAGE_SIZE);
286 }
287 return rc;
288}
289
290/*
drhed7c8552001-04-11 14:29:21 +0000291** Playback the journal and thus restore the database file to
292** the state it was in before we started making changes.
293**
drhd9b02572001-04-15 00:37:09 +0000294** The journal file format is as follows: There is an initial
295** file-type string for sanity checking. Then there is a single
296** Pgno number which is the number of pages in the database before
297** changes were made. The database is truncated to this size.
drh306dc212001-05-21 13:45:10 +0000298** Next come zero or more page records where each page record
299** consists of a Pgno and SQLITE_PAGE_SIZE bytes of data. See
300** the PageRecord structure for details.
drhed7c8552001-04-11 14:29:21 +0000301**
drhd9b02572001-04-15 00:37:09 +0000302** If the file opened as the journal file is not a well-formed
303** journal file (as determined by looking at the magic number
304** at the beginning) then this routine returns SQLITE_PROTOCOL.
305** If any other errors occur during playback, the database will
306** likely be corrupted, so the PAGER_ERR_CORRUPT bit is set in
307** pPager->errMask and SQLITE_CORRUPT is returned. If it all
308** works, then this routine returns SQLITE_OK.
drhed7c8552001-04-11 14:29:21 +0000309*/
drhd9b02572001-04-15 00:37:09 +0000310static int pager_playback(Pager *pPager){
311 int nRec; /* Number of Records */
312 int i; /* Loop counter */
313 Pgno mxPg = 0; /* Size of the original file in pages */
drhd9b02572001-04-15 00:37:09 +0000314 unsigned char aMagic[sizeof(aJournalMagic)];
drhed7c8552001-04-11 14:29:21 +0000315 int rc;
316
drhc3a64ba2001-11-22 00:01:27 +0000317 /* Figure out how many records are in the journal. Abort early if
318 ** the journal is empty.
drhed7c8552001-04-11 14:29:21 +0000319 */
drh8cfbf082001-09-19 13:22:39 +0000320 assert( pPager->journalOpen );
drha7fcb052001-12-14 15:09:55 +0000321 sqliteOsSeek(&pPager->jfd, 0);
322 rc = sqliteOsFileSize(&pPager->jfd, &nRec);
drhc3a64ba2001-11-22 00:01:27 +0000323 if( rc!=SQLITE_OK ){
324 goto end_playback;
325 }
326 nRec = (nRec - (sizeof(aMagic)+sizeof(Pgno))) / sizeof(PageRecord);
327 if( nRec<=0 ){
328 goto end_playback;
329 }
330
331 /* Read the beginning of the journal and truncate the
332 ** database file back to its original size.
333 */
drha7fcb052001-12-14 15:09:55 +0000334 rc = sqliteOsRead(&pPager->jfd, aMagic, sizeof(aMagic));
drhd9b02572001-04-15 00:37:09 +0000335 if( rc!=SQLITE_OK || memcmp(aMagic,aJournalMagic,sizeof(aMagic))!=0 ){
drh81a20f22001-10-12 17:30:04 +0000336 rc = SQLITE_PROTOCOL;
337 goto end_playback;
drhd9b02572001-04-15 00:37:09 +0000338 }
drha7fcb052001-12-14 15:09:55 +0000339 rc = sqliteOsRead(&pPager->jfd, &mxPg, sizeof(mxPg));
drhd9b02572001-04-15 00:37:09 +0000340 if( rc!=SQLITE_OK ){
drh81a20f22001-10-12 17:30:04 +0000341 goto end_playback;
drhd9b02572001-04-15 00:37:09 +0000342 }
drha7fcb052001-12-14 15:09:55 +0000343 rc = sqliteOsTruncate(&pPager->fd, mxPg*SQLITE_PAGE_SIZE);
drh81a20f22001-10-12 17:30:04 +0000344 if( rc!=SQLITE_OK ){
345 goto end_playback;
346 }
drhd9b02572001-04-15 00:37:09 +0000347 pPager->dbSize = mxPg;
348
drhfa86c412002-02-02 15:01:15 +0000349 /* Copy original pages out of the journal and back into the database file.
drhed7c8552001-04-11 14:29:21 +0000350 */
drhd9b02572001-04-15 00:37:09 +0000351 for(i=nRec-1; i>=0; i--){
drhfa86c412002-02-02 15:01:15 +0000352 rc = pager_playback_one_page(pPager, &pPager->jfd);
drhd9b02572001-04-15 00:37:09 +0000353 if( rc!=SQLITE_OK ) break;
drhed7c8552001-04-11 14:29:21 +0000354 }
drh81a20f22001-10-12 17:30:04 +0000355
356end_playback:
drhd9b02572001-04-15 00:37:09 +0000357 if( rc!=SQLITE_OK ){
358 pager_unwritelock(pPager);
359 pPager->errMask |= PAGER_ERR_CORRUPT;
360 rc = SQLITE_CORRUPT;
361 }else{
362 rc = pager_unwritelock(pPager);
drhed7c8552001-04-11 14:29:21 +0000363 }
drhd9b02572001-04-15 00:37:09 +0000364 return rc;
drhed7c8552001-04-11 14:29:21 +0000365}
366
367/*
drhfa86c412002-02-02 15:01:15 +0000368** Playback the checkpoint journal.
369**
370** This is similar to playing back the transaction journal but with
371** a few extra twists.
372**
drh663fc632002-02-02 18:49:19 +0000373** (1) The number of pages in the database file at the start of
374** the checkpoint is stored in pPager->ckptSize, not in the
375** journal file itself.
drhfa86c412002-02-02 15:01:15 +0000376**
377** (2) In addition to playing back the checkpoint journal, also
378** playback all pages of the transaction journal beginning
379** at offset pPager->ckptJSize.
380*/
381static int pager_ckpt_playback(Pager *pPager){
382 int nRec; /* Number of Records */
383 int i; /* Loop counter */
384 int rc;
385
386 /* Truncate the database back to its original size.
387 */
drh663fc632002-02-02 18:49:19 +0000388 rc = sqliteOsTruncate(&pPager->fd, pPager->ckptSize*SQLITE_PAGE_SIZE);
drhfa86c412002-02-02 15:01:15 +0000389 pPager->dbSize = pPager->ckptSize;
390
391 /* Figure out how many records are in the checkpoint journal.
392 */
393 assert( pPager->ckptOpen && pPager->journalOpen );
394 sqliteOsSeek(&pPager->cpfd, 0);
395 rc = sqliteOsFileSize(&pPager->cpfd, &nRec);
396 if( rc!=SQLITE_OK ){
397 goto end_ckpt_playback;
398 }
399 nRec /= sizeof(PageRecord);
400
401 /* Copy original pages out of the checkpoint journal and back into the
402 ** database file.
403 */
404 for(i=nRec-1; i>=0; i--){
405 rc = pager_playback_one_page(pPager, &pPager->cpfd);
406 if( rc!=SQLITE_OK ) goto end_ckpt_playback;
407 }
408
409 /* Figure out how many pages need to be copied out of the transaction
410 ** journal.
411 */
412 rc = sqliteOsSeek(&pPager->jfd, pPager->ckptJSize);
413 if( rc!=SQLITE_OK ){
414 goto end_ckpt_playback;
415 }
416 rc = sqliteOsFileSize(&pPager->jfd, &nRec);
417 if( rc!=SQLITE_OK ){
418 goto end_ckpt_playback;
419 }
420 nRec = (nRec - pPager->ckptJSize)/sizeof(PageRecord);
421 for(i=nRec-1; i>=0; i--){
422 rc = pager_playback_one_page(pPager, &pPager->jfd);
423 if( rc!=SQLITE_OK ) goto end_ckpt_playback;
424 }
425
426
427end_ckpt_playback:
drhfa86c412002-02-02 15:01:15 +0000428 if( rc!=SQLITE_OK ){
drhfa86c412002-02-02 15:01:15 +0000429 pPager->errMask |= PAGER_ERR_CORRUPT;
430 rc = SQLITE_CORRUPT;
drhfa86c412002-02-02 15:01:15 +0000431 }
432 return rc;
433}
434
435/*
drhf57b14a2001-09-14 18:54:08 +0000436** Change the maximum number of in-memory pages that are allowed.
drhcd61c282002-03-06 22:01:34 +0000437**
438** The maximum number is the absolute value of the mxPage parameter.
439** If mxPage is negative, the noSync flag is also set. noSync bypasses
440** calls to sqliteOsSync(). The pager runs much faster with noSync on,
441** but if the operating system crashes or there is an abrupt power
442** failure, the database file might be left in an inconsistent and
443** unrepairable state.
drhf57b14a2001-09-14 18:54:08 +0000444*/
445void sqlitepager_set_cachesize(Pager *pPager, int mxPage){
drh603240c2002-03-05 01:11:12 +0000446 if( mxPage>=0 ){
447 pPager->noSync = 0;
448 }else{
449 pPager->noSync = 1;
450 mxPage = -mxPage;
451 }
drhf57b14a2001-09-14 18:54:08 +0000452 if( mxPage>10 ){
453 pPager->mxPage = mxPage;
454 }
455}
456
457/*
drhfa86c412002-02-02 15:01:15 +0000458** Open a temporary file. Write the name of the file into zName
459** (zName must be at least SQLITE_TEMPNAME_SIZE bytes long.) Write
460** the file descriptor into *fd. Return SQLITE_OK on success or some
461** other error code if we fail.
462**
463** The OS will automatically delete the temporary file when it is
464** closed.
465*/
466static int sqlitepager_opentemp(char *zFile, OsFile *fd){
467 int cnt = 8;
468 int rc;
469 do{
470 cnt--;
471 sqliteOsTempFileName(zFile);
472 rc = sqliteOsOpenExclusive(zFile, fd, 1);
473 }while( cnt>0 && rc!=SQLITE_OK );
474 return rc;
475}
476
477/*
drhed7c8552001-04-11 14:29:21 +0000478** Create a new page cache and put a pointer to the page cache in *ppPager.
drh5e00f6c2001-09-13 13:46:56 +0000479** The file to be cached need not exist. The file is not locked until
drhd9b02572001-04-15 00:37:09 +0000480** the first call to sqlitepager_get() and is only held open until the
481** last page is released using sqlitepager_unref().
drh382c0242001-10-06 16:33:02 +0000482**
drh6446c4d2001-12-15 14:22:18 +0000483** If zFilename is NULL then a randomly-named temporary file is created
484** and used as the file to be cached. The file will be deleted
485** automatically when it is closed.
drhed7c8552001-04-11 14:29:21 +0000486*/
drh7e3b0a02001-04-28 16:52:40 +0000487int sqlitepager_open(
488 Pager **ppPager, /* Return the Pager structure here */
489 const char *zFilename, /* Name of the database file to open */
490 int mxPage, /* Max number of in-memory cache pages */
491 int nExtra /* Extra bytes append to each in-memory page */
492){
drhed7c8552001-04-11 14:29:21 +0000493 Pager *pPager;
494 int nameLen;
drh8cfbf082001-09-19 13:22:39 +0000495 OsFile fd;
496 int rc;
drh5e00f6c2001-09-13 13:46:56 +0000497 int tempFile;
498 int readOnly = 0;
drh8cfbf082001-09-19 13:22:39 +0000499 char zTemp[SQLITE_TEMPNAME_SIZE];
drhed7c8552001-04-11 14:29:21 +0000500
drhd9b02572001-04-15 00:37:09 +0000501 *ppPager = 0;
502 if( sqlite_malloc_failed ){
503 return SQLITE_NOMEM;
504 }
drh5e00f6c2001-09-13 13:46:56 +0000505 if( zFilename ){
drh8cfbf082001-09-19 13:22:39 +0000506 rc = sqliteOsOpenReadWrite(zFilename, &fd, &readOnly);
drh5e00f6c2001-09-13 13:46:56 +0000507 tempFile = 0;
508 }else{
drhfa86c412002-02-02 15:01:15 +0000509 rc = sqlitepager_opentemp(zTemp, &fd);
drh5e00f6c2001-09-13 13:46:56 +0000510 zFilename = zTemp;
511 tempFile = 1;
512 }
drh8cfbf082001-09-19 13:22:39 +0000513 if( rc!=SQLITE_OK ){
drhed7c8552001-04-11 14:29:21 +0000514 return SQLITE_CANTOPEN;
515 }
516 nameLen = strlen(zFilename);
517 pPager = sqliteMalloc( sizeof(*pPager) + nameLen*2 + 30 );
drhd9b02572001-04-15 00:37:09 +0000518 if( pPager==0 ){
drha7fcb052001-12-14 15:09:55 +0000519 sqliteOsClose(&fd);
drhd9b02572001-04-15 00:37:09 +0000520 return SQLITE_NOMEM;
521 }
drhed7c8552001-04-11 14:29:21 +0000522 pPager->zFilename = (char*)&pPager[1];
523 pPager->zJournal = &pPager->zFilename[nameLen+1];
524 strcpy(pPager->zFilename, zFilename);
525 strcpy(pPager->zJournal, zFilename);
526 strcpy(&pPager->zJournal[nameLen], "-journal");
527 pPager->fd = fd;
drh8cfbf082001-09-19 13:22:39 +0000528 pPager->journalOpen = 0;
drhfa86c412002-02-02 15:01:15 +0000529 pPager->ckptOpen = 0;
drhed7c8552001-04-11 14:29:21 +0000530 pPager->nRef = 0;
531 pPager->dbSize = -1;
drhfa86c412002-02-02 15:01:15 +0000532 pPager->ckptSize = 0;
533 pPager->ckptJSize = 0;
drhed7c8552001-04-11 14:29:21 +0000534 pPager->nPage = 0;
drhd79caeb2001-04-15 02:27:24 +0000535 pPager->mxPage = mxPage>5 ? mxPage : 10;
drhed7c8552001-04-11 14:29:21 +0000536 pPager->state = SQLITE_UNLOCK;
drhd9b02572001-04-15 00:37:09 +0000537 pPager->errMask = 0;
drh5e00f6c2001-09-13 13:46:56 +0000538 pPager->tempFile = tempFile;
539 pPager->readOnly = readOnly;
drhf57b14a2001-09-14 18:54:08 +0000540 pPager->needSync = 0;
drhed7c8552001-04-11 14:29:21 +0000541 pPager->pFirst = 0;
542 pPager->pLast = 0;
drh7c717f72001-06-24 20:39:41 +0000543 pPager->nExtra = nExtra;
drhed7c8552001-04-11 14:29:21 +0000544 memset(pPager->aHash, 0, sizeof(pPager->aHash));
545 *ppPager = pPager;
546 return SQLITE_OK;
547}
548
549/*
drh72f82862001-05-24 21:06:34 +0000550** Set the destructor for this pager. If not NULL, the destructor is called
drh5e00f6c2001-09-13 13:46:56 +0000551** when the reference count on each page reaches zero. The destructor can
552** be used to clean up information in the extra segment appended to each page.
drh72f82862001-05-24 21:06:34 +0000553**
554** The destructor is not called as a result sqlitepager_close().
555** Destructors are only called by sqlitepager_unref().
556*/
557void sqlitepager_set_destructor(Pager *pPager, void (*xDesc)(void*)){
558 pPager->xDestructor = xDesc;
559}
560
561/*
drh5e00f6c2001-09-13 13:46:56 +0000562** Return the total number of pages in the disk file associated with
563** pPager.
drhed7c8552001-04-11 14:29:21 +0000564*/
drhd9b02572001-04-15 00:37:09 +0000565int sqlitepager_pagecount(Pager *pPager){
drhed7c8552001-04-11 14:29:21 +0000566 int n;
drhd9b02572001-04-15 00:37:09 +0000567 assert( pPager!=0 );
drhed7c8552001-04-11 14:29:21 +0000568 if( pPager->dbSize>=0 ){
569 return pPager->dbSize;
570 }
drha7fcb052001-12-14 15:09:55 +0000571 if( sqliteOsFileSize(&pPager->fd, &n)!=SQLITE_OK ){
drh81a20f22001-10-12 17:30:04 +0000572 pPager->errMask |= PAGER_ERR_DISK;
drh8cfbf082001-09-19 13:22:39 +0000573 return 0;
drhed7c8552001-04-11 14:29:21 +0000574 }
drh8cfbf082001-09-19 13:22:39 +0000575 n /= SQLITE_PAGE_SIZE;
drhd9b02572001-04-15 00:37:09 +0000576 if( pPager->state!=SQLITE_UNLOCK ){
drhed7c8552001-04-11 14:29:21 +0000577 pPager->dbSize = n;
578 }
579 return n;
580}
581
582/*
583** Shutdown the page cache. Free all memory and close all files.
584**
585** If a transaction was in progress when this routine is called, that
586** transaction is rolled back. All outstanding pages are invalidated
587** and their memory is freed. Any attempt to use a page associated
588** with this page cache after this function returns will likely
589** result in a coredump.
590*/
drhd9b02572001-04-15 00:37:09 +0000591int sqlitepager_close(Pager *pPager){
592 PgHdr *pPg, *pNext;
drhed7c8552001-04-11 14:29:21 +0000593 switch( pPager->state ){
594 case SQLITE_WRITELOCK: {
drhd9b02572001-04-15 00:37:09 +0000595 sqlitepager_rollback(pPager);
drha7fcb052001-12-14 15:09:55 +0000596 sqliteOsUnlock(&pPager->fd);
drh8cfbf082001-09-19 13:22:39 +0000597 assert( pPager->journalOpen==0 );
drhed7c8552001-04-11 14:29:21 +0000598 break;
599 }
600 case SQLITE_READLOCK: {
drha7fcb052001-12-14 15:09:55 +0000601 sqliteOsUnlock(&pPager->fd);
drhed7c8552001-04-11 14:29:21 +0000602 break;
603 }
604 default: {
605 /* Do nothing */
606 break;
607 }
608 }
drhd9b02572001-04-15 00:37:09 +0000609 for(pPg=pPager->pAll; pPg; pPg=pNext){
610 pNext = pPg->pNextAll;
611 sqliteFree(pPg);
drhed7c8552001-04-11 14:29:21 +0000612 }
drha7fcb052001-12-14 15:09:55 +0000613 sqliteOsClose(&pPager->fd);
drh8cfbf082001-09-19 13:22:39 +0000614 assert( pPager->journalOpen==0 );
drh5e00f6c2001-09-13 13:46:56 +0000615 if( pPager->tempFile ){
drhfa86c412002-02-02 15:01:15 +0000616 /* sqliteOsDelete(pPager->zFilename); */
drh5e00f6c2001-09-13 13:46:56 +0000617 }
drhed7c8552001-04-11 14:29:21 +0000618 sqliteFree(pPager);
619 return SQLITE_OK;
620}
621
622/*
drh5e00f6c2001-09-13 13:46:56 +0000623** Return the page number for the given page data.
drhed7c8552001-04-11 14:29:21 +0000624*/
drhd9b02572001-04-15 00:37:09 +0000625Pgno sqlitepager_pagenumber(void *pData){
drhed7c8552001-04-11 14:29:21 +0000626 PgHdr *p = DATA_TO_PGHDR(pData);
627 return p->pgno;
628}
629
630/*
drh7e3b0a02001-04-28 16:52:40 +0000631** Increment the reference count for a page. If the page is
632** currently on the freelist (the reference count is zero) then
633** remove it from the freelist.
634*/
drhdf0b3b02001-06-23 11:36:20 +0000635static void page_ref(PgHdr *pPg){
drh7e3b0a02001-04-28 16:52:40 +0000636 if( pPg->nRef==0 ){
637 /* The page is currently on the freelist. Remove it. */
638 if( pPg->pPrevFree ){
639 pPg->pPrevFree->pNextFree = pPg->pNextFree;
640 }else{
641 pPg->pPager->pFirst = pPg->pNextFree;
642 }
643 if( pPg->pNextFree ){
644 pPg->pNextFree->pPrevFree = pPg->pPrevFree;
645 }else{
646 pPg->pPager->pLast = pPg->pPrevFree;
647 }
648 pPg->pPager->nRef++;
649 }
650 pPg->nRef++;
drhdd793422001-06-28 01:54:48 +0000651 REFINFO(pPg);
drhdf0b3b02001-06-23 11:36:20 +0000652}
653
654/*
655** Increment the reference count for a page. The input pointer is
656** a reference to the page data.
657*/
658int sqlitepager_ref(void *pData){
659 PgHdr *pPg = DATA_TO_PGHDR(pData);
660 page_ref(pPg);
drh8c42ca92001-06-22 19:15:00 +0000661 return SQLITE_OK;
drh7e3b0a02001-04-28 16:52:40 +0000662}
663
664/*
drhb19a2bc2001-09-16 00:13:26 +0000665** Sync the journal and then write all free dirty pages to the database
666** file.
667**
668** Writing all free dirty pages to the database after the sync is a
669** non-obvious optimization. fsync() is an expensive operation so we
drhaaab5722002-02-19 13:39:21 +0000670** want to minimize the number ot times it is called. After an fsync() call,
drh6446c4d2001-12-15 14:22:18 +0000671** we are free to write dirty pages back to the database. It is best
672** to go ahead and write as many dirty pages as possible to minimize
673** the risk of having to do another fsync() later on. Writing dirty
674** free pages in this way was observed to make database operations go
675** up to 10 times faster.
drhfa86c412002-02-02 15:01:15 +0000676**
677** If we are writing to temporary database, there is no need to preserve
678** the integrity of the journal file, so we can save time and skip the
679** fsync().
drh50e5dad2001-09-15 00:57:28 +0000680*/
681static int syncAllPages(Pager *pPager){
682 PgHdr *pPg;
683 int rc = SQLITE_OK;
684 if( pPager->needSync ){
drhfa86c412002-02-02 15:01:15 +0000685 if( !pPager->tempFile ){
686 rc = sqliteOsSync(&pPager->jfd);
687 if( rc!=0 ) return rc;
688 }
drh50e5dad2001-09-15 00:57:28 +0000689 pPager->needSync = 0;
690 }
691 for(pPg=pPager->pFirst; pPg; pPg=pPg->pNextFree){
692 if( pPg->dirty ){
drha7fcb052001-12-14 15:09:55 +0000693 sqliteOsSeek(&pPager->fd, (pPg->pgno-1)*SQLITE_PAGE_SIZE);
694 rc = sqliteOsWrite(&pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);
drh50e5dad2001-09-15 00:57:28 +0000695 if( rc!=SQLITE_OK ) break;
696 pPg->dirty = 0;
697 }
698 }
drh81a20f22001-10-12 17:30:04 +0000699 return rc;
drh50e5dad2001-09-15 00:57:28 +0000700}
701
702/*
drhd9b02572001-04-15 00:37:09 +0000703** Acquire a page.
704**
drh58a11682001-11-10 13:51:08 +0000705** A read lock on the disk file is obtained when the first page is acquired.
drh5e00f6c2001-09-13 13:46:56 +0000706** This read lock is dropped when the last page is released.
drhd9b02572001-04-15 00:37:09 +0000707**
drh306dc212001-05-21 13:45:10 +0000708** A _get works for any page number greater than 0. If the database
709** file is smaller than the requested page, then no actual disk
710** read occurs and the memory image of the page is initialized to
711** all zeros. The extra data appended to a page is always initialized
712** to zeros the first time a page is loaded into memory.
713**
drhd9b02572001-04-15 00:37:09 +0000714** The acquisition might fail for several reasons. In all cases,
715** an appropriate error code is returned and *ppPage is set to NULL.
drh7e3b0a02001-04-28 16:52:40 +0000716**
717** See also sqlitepager_lookup(). Both this routine and _lookup() attempt
718** to find a page in the in-memory cache first. If the page is not already
drh5e00f6c2001-09-13 13:46:56 +0000719** in memory, this routine goes to disk to read it in whereas _lookup()
drh7e3b0a02001-04-28 16:52:40 +0000720** just returns 0. This routine acquires a read-lock the first time it
721** has to go to disk, and could also playback an old journal if necessary.
722** Since _lookup() never goes to disk, it never has to deal with locks
723** or journal files.
drhed7c8552001-04-11 14:29:21 +0000724*/
drhd9b02572001-04-15 00:37:09 +0000725int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage){
drhed7c8552001-04-11 14:29:21 +0000726 PgHdr *pPg;
727
drhd9b02572001-04-15 00:37:09 +0000728 /* Make sure we have not hit any critical errors.
729 */
730 if( pPager==0 || pgno==0 ){
731 return SQLITE_ERROR;
732 }
733 if( pPager->errMask & ~(PAGER_ERR_FULL) ){
734 return pager_errcode(pPager);
735 }
736
drhed7c8552001-04-11 14:29:21 +0000737 /* If this is the first page accessed, then get a read lock
738 ** on the database file.
739 */
740 if( pPager->nRef==0 ){
drha7fcb052001-12-14 15:09:55 +0000741 if( sqliteOsReadLock(&pPager->fd)!=SQLITE_OK ){
drhed7c8552001-04-11 14:29:21 +0000742 *ppPage = 0;
743 return SQLITE_BUSY;
744 }
drhd9b02572001-04-15 00:37:09 +0000745 pPager->state = SQLITE_READLOCK;
drhed7c8552001-04-11 14:29:21 +0000746
747 /* If a journal file exists, try to play it back.
748 */
drh8cfbf082001-09-19 13:22:39 +0000749 if( sqliteOsFileExists(pPager->zJournal) ){
drhf57b3392001-10-08 13:22:32 +0000750 int rc, dummy;
drhed7c8552001-04-11 14:29:21 +0000751
drha7fcb052001-12-14 15:09:55 +0000752 /* Get a write lock on the database
753 */
754 rc = sqliteOsWriteLock(&pPager->fd);
755 if( rc!=SQLITE_OK ){
drh6446c4d2001-12-15 14:22:18 +0000756 rc = sqliteOsUnlock(&pPager->fd);
drha7fcb052001-12-14 15:09:55 +0000757 assert( rc==SQLITE_OK );
758 *ppPage = 0;
759 return SQLITE_BUSY;
760 }
761 pPager->state = SQLITE_WRITELOCK;
762
drhed7c8552001-04-11 14:29:21 +0000763 /* Open the journal for exclusive access. Return SQLITE_BUSY if
drhf57b3392001-10-08 13:22:32 +0000764 ** we cannot get exclusive access to the journal file.
765 **
766 ** Even though we will only be reading from the journal, not writing,
767 ** we have to open the journal for writing in order to obtain an
768 ** exclusive access lock.
drhed7c8552001-04-11 14:29:21 +0000769 */
drhf57b3392001-10-08 13:22:32 +0000770 rc = sqliteOsOpenReadWrite(pPager->zJournal, &pPager->jfd, &dummy);
drha7fcb052001-12-14 15:09:55 +0000771 if( rc!=SQLITE_OK ){
772 rc = sqliteOsUnlock(&pPager->fd);
773 assert( rc==SQLITE_OK );
drhed7c8552001-04-11 14:29:21 +0000774 *ppPage = 0;
775 return SQLITE_BUSY;
776 }
drha7fcb052001-12-14 15:09:55 +0000777 pPager->journalOpen = 1;
drhed7c8552001-04-11 14:29:21 +0000778
779 /* Playback and delete the journal. Drop the database write
780 ** lock and reacquire the read lock.
781 */
drhd9b02572001-04-15 00:37:09 +0000782 rc = pager_playback(pPager);
783 if( rc!=SQLITE_OK ){
784 return rc;
785 }
drhed7c8552001-04-11 14:29:21 +0000786 }
787 pPg = 0;
788 }else{
789 /* Search for page in cache */
drhd9b02572001-04-15 00:37:09 +0000790 pPg = pager_lookup(pPager, pgno);
drhed7c8552001-04-11 14:29:21 +0000791 }
792 if( pPg==0 ){
drhd9b02572001-04-15 00:37:09 +0000793 /* The requested page is not in the page cache. */
drhed7c8552001-04-11 14:29:21 +0000794 int h;
drh7e3b0a02001-04-28 16:52:40 +0000795 pPager->nMiss++;
drhed7c8552001-04-11 14:29:21 +0000796 if( pPager->nPage<pPager->mxPage || pPager->pFirst==0 ){
797 /* Create a new page */
drh7e3b0a02001-04-28 16:52:40 +0000798 pPg = sqliteMalloc( sizeof(*pPg) + SQLITE_PAGE_SIZE + pPager->nExtra );
drhd9b02572001-04-15 00:37:09 +0000799 if( pPg==0 ){
800 *ppPage = 0;
801 pager_unwritelock(pPager);
802 pPager->errMask |= PAGER_ERR_MEM;
803 return SQLITE_NOMEM;
804 }
drhed7c8552001-04-11 14:29:21 +0000805 pPg->pPager = pPager;
drhd9b02572001-04-15 00:37:09 +0000806 pPg->pNextAll = pPager->pAll;
807 if( pPager->pAll ){
808 pPager->pAll->pPrevAll = pPg;
809 }
810 pPg->pPrevAll = 0;
drhd79caeb2001-04-15 02:27:24 +0000811 pPager->pAll = pPg;
drhd9b02572001-04-15 00:37:09 +0000812 pPager->nPage++;
drhed7c8552001-04-11 14:29:21 +0000813 }else{
drhd9b02572001-04-15 00:37:09 +0000814 /* Recycle an older page. First locate the page to be recycled.
815 ** Try to find one that is not dirty and is near the head of
816 ** of the free list */
drhed7c8552001-04-11 14:29:21 +0000817 pPg = pPager->pFirst;
drh603240c2002-03-05 01:11:12 +0000818 while( pPg && pPg->dirty ){
drhd9b02572001-04-15 00:37:09 +0000819 pPg = pPg->pNextFree;
820 }
drhb19a2bc2001-09-16 00:13:26 +0000821
822 /* If we could not find a page that has not been used recently
823 ** and which is not dirty, then sync the journal and write all
824 ** dirty free pages into the database file, thus making them
825 ** clean pages and available for recycling.
826 **
827 ** We have to sync the journal before writing a page to the main
828 ** database. But syncing is a very slow operation. So after a
829 ** sync, it is best to write everything we can back to the main
830 ** database to minimize the risk of having to sync again in the
831 ** near future. That is way we write all dirty pages after a
832 ** sync.
833 */
drh603240c2002-03-05 01:11:12 +0000834 if( pPg==0 ){
drh50e5dad2001-09-15 00:57:28 +0000835 int rc = syncAllPages(pPager);
836 if( rc!=0 ){
837 sqlitepager_rollback(pPager);
838 *ppPage = 0;
839 return SQLITE_IOERR;
840 }
841 pPg = pPager->pFirst;
842 }
drhd9b02572001-04-15 00:37:09 +0000843 assert( pPg->nRef==0 );
drh50e5dad2001-09-15 00:57:28 +0000844 assert( pPg->dirty==0 );
drhd9b02572001-04-15 00:37:09 +0000845
846 /* Unlink the old page from the free list and the hash table
847 */
drh6019e162001-07-02 17:51:45 +0000848 if( pPg->pPrevFree ){
849 pPg->pPrevFree->pNextFree = pPg->pNextFree;
drhed7c8552001-04-11 14:29:21 +0000850 }else{
drh6019e162001-07-02 17:51:45 +0000851 assert( pPager->pFirst==pPg );
852 pPager->pFirst = pPg->pNextFree;
drhed7c8552001-04-11 14:29:21 +0000853 }
drh6019e162001-07-02 17:51:45 +0000854 if( pPg->pNextFree ){
855 pPg->pNextFree->pPrevFree = pPg->pPrevFree;
856 }else{
857 assert( pPager->pLast==pPg );
858 pPager->pLast = pPg->pPrevFree;
859 }
860 pPg->pNextFree = pPg->pPrevFree = 0;
drhed7c8552001-04-11 14:29:21 +0000861 if( pPg->pNextHash ){
862 pPg->pNextHash->pPrevHash = pPg->pPrevHash;
863 }
864 if( pPg->pPrevHash ){
865 pPg->pPrevHash->pNextHash = pPg->pNextHash;
866 }else{
drhd9b02572001-04-15 00:37:09 +0000867 h = pager_hash(pPg->pgno);
drhed7c8552001-04-11 14:29:21 +0000868 assert( pPager->aHash[h]==pPg );
869 pPager->aHash[h] = pPg->pNextHash;
870 }
drh6019e162001-07-02 17:51:45 +0000871 pPg->pNextHash = pPg->pPrevHash = 0;
drhd9b02572001-04-15 00:37:09 +0000872 pPager->nOvfl++;
drhed7c8552001-04-11 14:29:21 +0000873 }
874 pPg->pgno = pgno;
drh1ab43002002-01-14 09:28:19 +0000875 if( pPager->aInJournal && (int)pgno<=pPager->origDbSize ){
drh6019e162001-07-02 17:51:45 +0000876 pPg->inJournal = (pPager->aInJournal[pgno/8] & (1<<(pgno&7)))!=0;
877 }else{
878 pPg->inJournal = 0;
879 }
drh663fc632002-02-02 18:49:19 +0000880 if( pPager->aInCkpt && (int)pgno<=pPager->ckptSize ){
drhfa86c412002-02-02 15:01:15 +0000881 pPg->inCkpt = (pPager->aInCkpt[pgno/8] & (1<<(pgno&7)))!=0;
882 }else{
883 pPg->inCkpt = 0;
884 }
drhed7c8552001-04-11 14:29:21 +0000885 pPg->dirty = 0;
886 pPg->nRef = 1;
drhdd793422001-06-28 01:54:48 +0000887 REFINFO(pPg);
drhd9b02572001-04-15 00:37:09 +0000888 pPager->nRef++;
889 h = pager_hash(pgno);
drhed7c8552001-04-11 14:29:21 +0000890 pPg->pNextHash = pPager->aHash[h];
891 pPager->aHash[h] = pPg;
892 if( pPg->pNextHash ){
893 assert( pPg->pNextHash->pPrevHash==0 );
894 pPg->pNextHash->pPrevHash = pPg;
895 }
drh306dc212001-05-21 13:45:10 +0000896 if( pPager->dbSize<0 ) sqlitepager_pagecount(pPager);
drh1ab43002002-01-14 09:28:19 +0000897 if( pPager->dbSize<(int)pgno ){
drh306dc212001-05-21 13:45:10 +0000898 memset(PGHDR_TO_DATA(pPg), 0, SQLITE_PAGE_SIZE);
899 }else{
drh81a20f22001-10-12 17:30:04 +0000900 int rc;
drha7fcb052001-12-14 15:09:55 +0000901 sqliteOsSeek(&pPager->fd, (pgno-1)*SQLITE_PAGE_SIZE);
902 rc = sqliteOsRead(&pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);
drh81a20f22001-10-12 17:30:04 +0000903 if( rc!=SQLITE_OK ){
904 return rc;
905 }
drh306dc212001-05-21 13:45:10 +0000906 }
drh7e3b0a02001-04-28 16:52:40 +0000907 if( pPager->nExtra>0 ){
908 memset(PGHDR_TO_EXTRA(pPg), 0, pPager->nExtra);
909 }
drhed7c8552001-04-11 14:29:21 +0000910 }else{
drhd9b02572001-04-15 00:37:09 +0000911 /* The requested page is in the page cache. */
drh7e3b0a02001-04-28 16:52:40 +0000912 pPager->nHit++;
drhdf0b3b02001-06-23 11:36:20 +0000913 page_ref(pPg);
drhed7c8552001-04-11 14:29:21 +0000914 }
915 *ppPage = PGHDR_TO_DATA(pPg);
916 return SQLITE_OK;
917}
918
919/*
drh7e3b0a02001-04-28 16:52:40 +0000920** Acquire a page if it is already in the in-memory cache. Do
921** not read the page from disk. Return a pointer to the page,
922** or 0 if the page is not in cache.
923**
924** See also sqlitepager_get(). The difference between this routine
925** and sqlitepager_get() is that _get() will go to the disk and read
926** in the page if the page is not already in cache. This routine
drh5e00f6c2001-09-13 13:46:56 +0000927** returns NULL if the page is not in cache or if a disk I/O error
928** has ever happened.
drh7e3b0a02001-04-28 16:52:40 +0000929*/
930void *sqlitepager_lookup(Pager *pPager, Pgno pgno){
931 PgHdr *pPg;
932
933 /* Make sure we have not hit any critical errors.
934 */
935 if( pPager==0 || pgno==0 ){
936 return 0;
937 }
938 if( pPager->errMask & ~(PAGER_ERR_FULL) ){
939 return 0;
940 }
941 if( pPager->nRef==0 ){
942 return 0;
943 }
944 pPg = pager_lookup(pPager, pgno);
945 if( pPg==0 ) return 0;
drhdf0b3b02001-06-23 11:36:20 +0000946 page_ref(pPg);
drh7e3b0a02001-04-28 16:52:40 +0000947 return PGHDR_TO_DATA(pPg);
948}
949
950/*
drhed7c8552001-04-11 14:29:21 +0000951** Release a page.
952**
953** If the number of references to the page drop to zero, then the
954** page is added to the LRU list. When all references to all pages
drhd9b02572001-04-15 00:37:09 +0000955** are released, a rollback occurs and the lock on the database is
drhed7c8552001-04-11 14:29:21 +0000956** removed.
957*/
drhd9b02572001-04-15 00:37:09 +0000958int sqlitepager_unref(void *pData){
drhed7c8552001-04-11 14:29:21 +0000959 PgHdr *pPg;
drhd9b02572001-04-15 00:37:09 +0000960
961 /* Decrement the reference count for this page
962 */
drhed7c8552001-04-11 14:29:21 +0000963 pPg = DATA_TO_PGHDR(pData);
964 assert( pPg->nRef>0 );
drhed7c8552001-04-11 14:29:21 +0000965 pPg->nRef--;
drhdd793422001-06-28 01:54:48 +0000966 REFINFO(pPg);
drhd9b02572001-04-15 00:37:09 +0000967
drh72f82862001-05-24 21:06:34 +0000968 /* When the number of references to a page reach 0, call the
969 ** destructor and add the page to the freelist.
drhd9b02572001-04-15 00:37:09 +0000970 */
drhed7c8552001-04-11 14:29:21 +0000971 if( pPg->nRef==0 ){
drh1eaa2692001-09-18 02:02:23 +0000972 Pager *pPager;
973 pPager = pPg->pPager;
drhd9b02572001-04-15 00:37:09 +0000974 pPg->pNextFree = 0;
975 pPg->pPrevFree = pPager->pLast;
drhed7c8552001-04-11 14:29:21 +0000976 pPager->pLast = pPg;
drhd9b02572001-04-15 00:37:09 +0000977 if( pPg->pPrevFree ){
978 pPg->pPrevFree->pNextFree = pPg;
drhed7c8552001-04-11 14:29:21 +0000979 }else{
980 pPager->pFirst = pPg;
981 }
drh72f82862001-05-24 21:06:34 +0000982 if( pPager->xDestructor ){
983 pPager->xDestructor(pData);
984 }
drhd9b02572001-04-15 00:37:09 +0000985
986 /* When all pages reach the freelist, drop the read lock from
987 ** the database file.
988 */
989 pPager->nRef--;
990 assert( pPager->nRef>=0 );
991 if( pPager->nRef==0 ){
992 pager_reset(pPager);
993 }
drhed7c8552001-04-11 14:29:21 +0000994 }
drhd9b02572001-04-15 00:37:09 +0000995 return SQLITE_OK;
drhed7c8552001-04-11 14:29:21 +0000996}
997
998/*
drh4b845d72002-03-05 12:41:19 +0000999** Acquire a write-lock on the database. The lock is removed when
1000** the any of the following happen:
1001**
1002** * sqlitepager_commit() is called.
1003** * sqlitepager_rollback() is called.
1004** * sqlitepager_close() is called.
1005** * sqlitepager_unref() is called to on every outstanding page.
1006**
1007** The parameter to this routine is a pointer to any open page of the
1008** database file. Nothing changes about the page - it is used merely
1009** to acquire a pointer to the Pager structure and as proof that there
1010** is already a read-lock on the database.
1011**
1012** If the database is already write-locked, this routine is a no-op.
1013*/
1014int sqlitepager_begin(void *pData){
1015 PgHdr *pPg = DATA_TO_PGHDR(pData);
1016 Pager *pPager = pPg->pPager;
1017 int rc = SQLITE_OK;
1018 assert( pPg->nRef>0 );
1019 assert( pPager->state!=SQLITE_UNLOCK );
1020 if( pPager->state==SQLITE_READLOCK ){
1021 assert( pPager->aInJournal==0 );
1022 rc = sqliteOsWriteLock(&pPager->fd);
1023 if( rc!=SQLITE_OK ){
1024 return rc;
1025 }
1026 pPager->aInJournal = sqliteMalloc( pPager->dbSize/8 + 1 );
1027 if( pPager->aInJournal==0 ){
1028 sqliteOsReadLock(&pPager->fd);
1029 return SQLITE_NOMEM;
1030 }
1031 rc = sqliteOsOpenExclusive(pPager->zJournal, &pPager->jfd, 0);
1032 if( rc!=SQLITE_OK ){
1033 sqliteFree(pPager->aInJournal);
1034 pPager->aInJournal = 0;
1035 sqliteOsReadLock(&pPager->fd);
1036 return SQLITE_CANTOPEN;
1037 }
1038 pPager->journalOpen = 1;
1039 pPager->needSync = !pPager->noSync;
1040 pPager->state = SQLITE_WRITELOCK;
1041 sqlitepager_pagecount(pPager);
1042 pPager->origDbSize = pPager->dbSize;
1043 rc = sqliteOsWrite(&pPager->jfd, aJournalMagic, sizeof(aJournalMagic));
1044 if( rc==SQLITE_OK ){
1045 rc = sqliteOsWrite(&pPager->jfd, &pPager->dbSize, sizeof(Pgno));
1046 }
1047 if( rc!=SQLITE_OK ){
1048 rc = pager_unwritelock(pPager);
1049 if( rc==SQLITE_OK ) rc = SQLITE_FULL;
1050 }
1051 }
1052 return rc;
1053}
1054
1055/*
drhed7c8552001-04-11 14:29:21 +00001056** Mark a data page as writeable. The page is written into the journal
1057** if it is not there already. This routine must be called before making
1058** changes to a page.
1059**
1060** The first time this routine is called, the pager creates a new
1061** journal and acquires a write lock on the database. If the write
1062** lock could not be acquired, this routine returns SQLITE_BUSY. The
drh306dc212001-05-21 13:45:10 +00001063** calling routine must check for that return value and be careful not to
drhed7c8552001-04-11 14:29:21 +00001064** change any page data until this routine returns SQLITE_OK.
drhd9b02572001-04-15 00:37:09 +00001065**
1066** If the journal file could not be written because the disk is full,
1067** then this routine returns SQLITE_FULL and does an immediate rollback.
1068** All subsequent write attempts also return SQLITE_FULL until there
1069** is a call to sqlitepager_commit() or sqlitepager_rollback() to
1070** reset.
drhed7c8552001-04-11 14:29:21 +00001071*/
drhd9b02572001-04-15 00:37:09 +00001072int sqlitepager_write(void *pData){
drh69688d52001-04-14 16:38:23 +00001073 PgHdr *pPg = DATA_TO_PGHDR(pData);
1074 Pager *pPager = pPg->pPager;
drhd79caeb2001-04-15 02:27:24 +00001075 int rc = SQLITE_OK;
drh69688d52001-04-14 16:38:23 +00001076
drh6446c4d2001-12-15 14:22:18 +00001077 /* Check for errors
1078 */
drhd9b02572001-04-15 00:37:09 +00001079 if( pPager->errMask ){
1080 return pager_errcode(pPager);
1081 }
drh5e00f6c2001-09-13 13:46:56 +00001082 if( pPager->readOnly ){
1083 return SQLITE_PERM;
1084 }
drh6446c4d2001-12-15 14:22:18 +00001085
1086 /* Mark the page as dirty. If the page has already been written
1087 ** to the journal then we can return right away.
1088 */
drhd9b02572001-04-15 00:37:09 +00001089 pPg->dirty = 1;
drhfa86c412002-02-02 15:01:15 +00001090 if( pPg->inJournal && (pPg->inCkpt || pPager->ckptOpen==0) ){
1091 return SQLITE_OK;
1092 }
drh6446c4d2001-12-15 14:22:18 +00001093
1094 /* If we get this far, it means that the page needs to be
drhfa86c412002-02-02 15:01:15 +00001095 ** written to the transaction journal or the ckeckpoint journal
1096 ** or both.
1097 **
1098 ** First check to see that the transaction journal exists and
1099 ** create it if it does not.
drh6446c4d2001-12-15 14:22:18 +00001100 */
drhd9b02572001-04-15 00:37:09 +00001101 assert( pPager->state!=SQLITE_UNLOCK );
drh4b845d72002-03-05 12:41:19 +00001102 rc = sqlitepager_begin(pData);
1103 if( rc!=SQLITE_OK ) return rc;
drhd9b02572001-04-15 00:37:09 +00001104 assert( pPager->state==SQLITE_WRITELOCK );
drh8cfbf082001-09-19 13:22:39 +00001105 assert( pPager->journalOpen );
drh6446c4d2001-12-15 14:22:18 +00001106
drhfa86c412002-02-02 15:01:15 +00001107 /* The transaction journal now exists and we have a write lock on the
1108 ** main database file. Write the current page to the transaction
1109 ** journal if it is not there already.
drh6446c4d2001-12-15 14:22:18 +00001110 */
drhfa86c412002-02-02 15:01:15 +00001111 if( !pPg->inJournal && (int)pPg->pgno <= pPager->origDbSize ){
drha7fcb052001-12-14 15:09:55 +00001112 rc = sqliteOsWrite(&pPager->jfd, &pPg->pgno, sizeof(Pgno));
drhd9b02572001-04-15 00:37:09 +00001113 if( rc==SQLITE_OK ){
drha7fcb052001-12-14 15:09:55 +00001114 rc = sqliteOsWrite(&pPager->jfd, pData, SQLITE_PAGE_SIZE);
drhd9b02572001-04-15 00:37:09 +00001115 }
1116 if( rc!=SQLITE_OK ){
1117 sqlitepager_rollback(pPager);
1118 pPager->errMask |= PAGER_ERR_FULL;
1119 return rc;
1120 }
drh6019e162001-07-02 17:51:45 +00001121 assert( pPager->aInJournal!=0 );
1122 pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7);
drh603240c2002-03-05 01:11:12 +00001123 pPager->needSync = !pPager->noSync;
drhfa86c412002-02-02 15:01:15 +00001124 pPg->inJournal = 1;
1125 if( pPager->ckptOpen ){
1126 pPager->aInCkpt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
1127 pPg->inCkpt = 1;
1128 }
drh69688d52001-04-14 16:38:23 +00001129 }
drh6446c4d2001-12-15 14:22:18 +00001130
drhfa86c412002-02-02 15:01:15 +00001131 /* If the checkpoint journal is open and the page is not in it,
1132 ** then write the current page to the checkpoint journal.
drh6446c4d2001-12-15 14:22:18 +00001133 */
drh663fc632002-02-02 18:49:19 +00001134 if( pPager->ckptOpen && !pPg->inCkpt && (int)pPg->pgno<=pPager->ckptSize ){
drh1e336b42002-02-14 12:50:33 +00001135 assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize );
drhfa86c412002-02-02 15:01:15 +00001136 rc = sqliteOsWrite(&pPager->cpfd, &pPg->pgno, sizeof(Pgno));
1137 if( rc==SQLITE_OK ){
1138 rc = sqliteOsWrite(&pPager->cpfd, pData, SQLITE_PAGE_SIZE);
1139 }
1140 if( rc!=SQLITE_OK ){
1141 sqlitepager_rollback(pPager);
1142 pPager->errMask |= PAGER_ERR_FULL;
1143 return rc;
1144 }
1145 assert( pPager->aInCkpt!=0 );
1146 pPager->aInCkpt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
1147 pPg->inCkpt = 1;
1148 }
1149
1150 /* Update the database size and return.
1151 */
drh1ab43002002-01-14 09:28:19 +00001152 if( pPager->dbSize<(int)pPg->pgno ){
drh306dc212001-05-21 13:45:10 +00001153 pPager->dbSize = pPg->pgno;
1154 }
drh69688d52001-04-14 16:38:23 +00001155 return rc;
drhed7c8552001-04-11 14:29:21 +00001156}
1157
1158/*
drhaacc5432002-01-06 17:07:40 +00001159** Return TRUE if the page given in the argument was previously passed
drh6019e162001-07-02 17:51:45 +00001160** to sqlitepager_write(). In other words, return TRUE if it is ok
1161** to change the content of the page.
1162*/
1163int sqlitepager_iswriteable(void *pData){
1164 PgHdr *pPg = DATA_TO_PGHDR(pData);
1165 return pPg->dirty;
1166}
1167
1168/*
drh30e58752002-03-02 20:41:57 +00001169** A call to this routine tells the pager that it is not necessary to
1170** write the information on page "pgno" back to the disk, even though
1171** that page might be marked as dirty.
1172**
1173** The overlying software layer calls this routine when all of the data
1174** on the given page is unused. The pager marks the page as clean so
1175** that it does not get written to disk.
1176**
1177** Tests show that this optimization, together with the
1178** sqlitepager_dont_rollback() below, more than double the speed
1179** of large INSERT operations and quadruple the speed of large DELETEs.
1180*/
1181void sqlitepager_dont_write(Pager *pPager, Pgno pgno){
1182 PgHdr *pPg;
1183 pPg = pager_lookup(pPager, pgno);
1184 if( pPg && pPg->dirty ){
1185 pPg->dirty = 0;
1186 }
1187}
1188
1189/*
1190** A call to this routine tells the pager that if a rollback occurs,
1191** it is not necessary to restore the data on the given page. This
1192** means that the pager does not have to record the given page in the
1193** rollback journal.
1194*/
1195void sqlitepager_dont_rollback(void *pData){
1196 PgHdr *pPg = DATA_TO_PGHDR(pData);
1197 Pager *pPager = pPg->pPager;
1198
1199 if( pPager->state!=SQLITE_WRITELOCK || pPager->journalOpen==0 ) return;
1200 if( !pPg->inJournal && (int)pPg->pgno <= pPager->origDbSize ){
1201 assert( pPager->aInJournal!=0 );
1202 pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7);
1203 pPg->inJournal = 1;
1204 if( pPager->ckptOpen ){
1205 pPager->aInCkpt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
1206 pPg->inCkpt = 1;
1207 }
1208 }
1209 if( pPager->ckptOpen && !pPg->inCkpt && (int)pPg->pgno<=pPager->ckptSize ){
1210 assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize );
1211 assert( pPager->aInCkpt!=0 );
1212 pPager->aInCkpt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
1213 pPg->inCkpt = 1;
1214 }
1215}
1216
1217/*
drhed7c8552001-04-11 14:29:21 +00001218** Commit all changes to the database and release the write lock.
drhd9b02572001-04-15 00:37:09 +00001219**
1220** If the commit fails for any reason, a rollback attempt is made
1221** and an error code is returned. If the commit worked, SQLITE_OK
1222** is returned.
drhed7c8552001-04-11 14:29:21 +00001223*/
drhd9b02572001-04-15 00:37:09 +00001224int sqlitepager_commit(Pager *pPager){
drha1b351a2001-09-14 16:42:12 +00001225 int rc;
drhed7c8552001-04-11 14:29:21 +00001226 PgHdr *pPg;
drhd9b02572001-04-15 00:37:09 +00001227
1228 if( pPager->errMask==PAGER_ERR_FULL ){
1229 rc = sqlitepager_rollback(pPager);
1230 if( rc==SQLITE_OK ) rc = SQLITE_FULL;
1231 return rc;
1232 }
1233 if( pPager->errMask!=0 ){
1234 rc = pager_errcode(pPager);
1235 return rc;
1236 }
1237 if( pPager->state!=SQLITE_WRITELOCK ){
1238 return SQLITE_ERROR;
1239 }
drh8cfbf082001-09-19 13:22:39 +00001240 assert( pPager->journalOpen );
drha7fcb052001-12-14 15:09:55 +00001241 if( pPager->needSync && sqliteOsSync(&pPager->jfd)!=SQLITE_OK ){
drhd9b02572001-04-15 00:37:09 +00001242 goto commit_abort;
drhed7c8552001-04-11 14:29:21 +00001243 }
drha1b351a2001-09-14 16:42:12 +00001244 for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
1245 if( pPg->dirty==0 ) continue;
drha7fcb052001-12-14 15:09:55 +00001246 rc = sqliteOsSeek(&pPager->fd, (pPg->pgno-1)*SQLITE_PAGE_SIZE);
drha1b351a2001-09-14 16:42:12 +00001247 if( rc!=SQLITE_OK ) goto commit_abort;
drha7fcb052001-12-14 15:09:55 +00001248 rc = sqliteOsWrite(&pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);
drha1b351a2001-09-14 16:42:12 +00001249 if( rc!=SQLITE_OK ) goto commit_abort;
drhed7c8552001-04-11 14:29:21 +00001250 }
drh603240c2002-03-05 01:11:12 +00001251 if( !pPager->noSync && sqliteOsSync(&pPager->fd)!=SQLITE_OK ){
1252 goto commit_abort;
1253 }
drhd9b02572001-04-15 00:37:09 +00001254 rc = pager_unwritelock(pPager);
1255 pPager->dbSize = -1;
1256 return rc;
1257
1258 /* Jump here if anything goes wrong during the commit process.
1259 */
1260commit_abort:
1261 rc = sqlitepager_rollback(pPager);
1262 if( rc==SQLITE_OK ){
1263 rc = SQLITE_FULL;
drhed7c8552001-04-11 14:29:21 +00001264 }
drhed7c8552001-04-11 14:29:21 +00001265 return rc;
1266}
1267
1268/*
1269** Rollback all changes. The database falls back to read-only mode.
1270** All in-memory cache pages revert to their original data contents.
1271** The journal is deleted.
drhd9b02572001-04-15 00:37:09 +00001272**
1273** This routine cannot fail unless some other process is not following
1274** the correct locking protocol (SQLITE_PROTOCOL) or unless some other
1275** process is writing trash into the journal file (SQLITE_CORRUPT) or
1276** unless a prior malloc() failed (SQLITE_NOMEM). Appropriate error
1277** codes are returned for all these occasions. Otherwise,
1278** SQLITE_OK is returned.
drhed7c8552001-04-11 14:29:21 +00001279*/
drhd9b02572001-04-15 00:37:09 +00001280int sqlitepager_rollback(Pager *pPager){
drhed7c8552001-04-11 14:29:21 +00001281 int rc;
drhd9b02572001-04-15 00:37:09 +00001282 if( pPager->errMask!=0 && pPager->errMask!=PAGER_ERR_FULL ){
drh4b845d72002-03-05 12:41:19 +00001283 if( pPager->state>=SQLITE_WRITELOCK ){
1284 pager_playback(pPager);
1285 }
drhd9b02572001-04-15 00:37:09 +00001286 return pager_errcode(pPager);
drhed7c8552001-04-11 14:29:21 +00001287 }
drhd9b02572001-04-15 00:37:09 +00001288 if( pPager->state!=SQLITE_WRITELOCK ){
1289 return SQLITE_OK;
1290 }
1291 rc = pager_playback(pPager);
1292 if( rc!=SQLITE_OK ){
1293 rc = SQLITE_CORRUPT;
1294 pPager->errMask |= PAGER_ERR_CORRUPT;
1295 }
1296 pPager->dbSize = -1;
drhed7c8552001-04-11 14:29:21 +00001297 return rc;
drh98808ba2001-10-18 12:34:46 +00001298}
drhd9b02572001-04-15 00:37:09 +00001299
1300/*
drh5e00f6c2001-09-13 13:46:56 +00001301** Return TRUE if the database file is opened read-only. Return FALSE
1302** if the database is (in theory) writable.
1303*/
1304int sqlitepager_isreadonly(Pager *pPager){
drhbe0072d2001-09-13 14:46:09 +00001305 return pPager->readOnly;
drh5e00f6c2001-09-13 13:46:56 +00001306}
1307
1308/*
drhd9b02572001-04-15 00:37:09 +00001309** This routine is used for testing and analysis only.
1310*/
1311int *sqlitepager_stats(Pager *pPager){
1312 static int a[9];
1313 a[0] = pPager->nRef;
1314 a[1] = pPager->nPage;
1315 a[2] = pPager->mxPage;
1316 a[3] = pPager->dbSize;
1317 a[4] = pPager->state;
1318 a[5] = pPager->errMask;
1319 a[6] = pPager->nHit;
1320 a[7] = pPager->nMiss;
1321 a[8] = pPager->nOvfl;
1322 return a;
1323}
drhdd793422001-06-28 01:54:48 +00001324
drhfa86c412002-02-02 15:01:15 +00001325/*
1326** Set the checkpoint.
1327**
1328** This routine should be called with the transaction journal already
1329** open. A new checkpoint journal is created that can be used to rollback
drhaaab5722002-02-19 13:39:21 +00001330** changes of a single SQL command within a larger transaction.
drhfa86c412002-02-02 15:01:15 +00001331*/
1332int sqlitepager_ckpt_begin(Pager *pPager){
1333 int rc;
1334 char zTemp[SQLITE_TEMPNAME_SIZE];
1335 assert( pPager->journalOpen );
1336 assert( !pPager->ckptOpen );
1337 pPager->aInCkpt = sqliteMalloc( pPager->dbSize/8 + 1 );
1338 if( pPager->aInCkpt==0 ){
1339 sqliteOsReadLock(&pPager->fd);
1340 return SQLITE_NOMEM;
1341 }
1342 rc = sqliteOsFileSize(&pPager->jfd, &pPager->ckptJSize);
1343 if( rc ) goto ckpt_begin_failed;
drh663fc632002-02-02 18:49:19 +00001344 pPager->ckptSize = pPager->dbSize;
drhfa86c412002-02-02 15:01:15 +00001345 rc = sqlitepager_opentemp(zTemp, &pPager->cpfd);
1346 if( rc ) goto ckpt_begin_failed;
1347 pPager->ckptOpen = 1;
1348 return SQLITE_OK;
1349
1350ckpt_begin_failed:
1351 if( pPager->aInCkpt ){
1352 sqliteFree(pPager->aInCkpt);
1353 pPager->aInCkpt = 0;
1354 }
1355 return rc;
1356}
1357
1358/*
1359** Commit a checkpoint.
1360*/
1361int sqlitepager_ckpt_commit(Pager *pPager){
drh663fc632002-02-02 18:49:19 +00001362 if( pPager->ckptOpen ){
1363 PgHdr *pPg;
1364 sqliteOsClose(&pPager->cpfd);
1365 pPager->ckptOpen = 0;
1366 sqliteFree( pPager->aInCkpt );
1367 pPager->aInCkpt = 0;
1368 for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
1369 pPg->inCkpt = 0;
1370 }
1371 }
drhfa86c412002-02-02 15:01:15 +00001372 return SQLITE_OK;
1373}
1374
1375/*
1376** Rollback a checkpoint.
1377*/
1378int sqlitepager_ckpt_rollback(Pager *pPager){
1379 int rc;
drh663fc632002-02-02 18:49:19 +00001380 if( pPager->ckptOpen ){
1381 rc = pager_ckpt_playback(pPager);
1382 sqlitepager_ckpt_commit(pPager);
1383 }else{
1384 rc = SQLITE_OK;
1385 }
drhfa86c412002-02-02 15:01:15 +00001386 return rc;
1387}
1388
drhdd793422001-06-28 01:54:48 +00001389#if SQLITE_TEST
1390/*
1391** Print a listing of all referenced pages and their ref count.
1392*/
1393void sqlitepager_refdump(Pager *pPager){
1394 PgHdr *pPg;
1395 for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
1396 if( pPg->nRef<=0 ) continue;
1397 printf("PAGE %3d addr=0x%08x nRef=%d\n",
1398 pPg->pgno, (int)PGHDR_TO_DATA(pPg), pPg->nRef);
1399 }
1400}
1401#endif