diff --git a/source/libs/tdb/src/sqlite/pager.c b/source/libs/tdb/src/sqlite/pager.c index 514b8cbc30..9acbabfabe 100644 --- a/source/libs/tdb/src/sqlite/pager.c +++ b/source/libs/tdb/src/sqlite/pager.c @@ -10,7 +10,7 @@ ** ************************************************************************* ** This is the implementation of the page cache subsystem or "pager". -** +** ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file @@ -21,7 +21,6 @@ #include "sqliteInt.h" // #include "wal.h" - // /******************* NOTES ON THE DESIGN OF THE PAGER ************************ // ** // ** This comment block describes invariants that hold when using a rollback @@ -35,60 +34,60 @@ // ** // ** Definition: A page of the database file is said to be "overwriteable" if // ** one or more of the following are true about the page: -// ** +// ** // ** (a) The original content of the page as it was at the beginning of // ** the transaction has been written into the rollback journal and // ** synced. -// ** +// ** // ** (b) The page was a freelist leaf page at the start of the transaction. -// ** +// ** // ** (c) The page number is greater than the largest page that existed in // ** the database file at the start of the transaction. -// ** +// ** // ** (1) A page of the database file is never overwritten unless one of the // ** following are true: -// ** +// ** // ** (a) The page and all other pages on the same sector are overwriteable. -// ** +// ** // ** (b) The atomic page write optimization is enabled, and the entire // ** transaction other than the update of the transaction sequence // ** number consists of a single page change. -// ** +// ** // ** (2) The content of a page written into the rollback journal exactly matches // ** both the content in the database when the rollback journal was written // ** and the content in the database at the beginning of the current // ** transaction. -// ** +// ** // ** (3) Writes to the database file are an integer multiple of the page size // ** in length and are aligned on a page boundary. -// ** +// ** // ** (4) Reads from the database file are either aligned on a page boundary and // ** an integer multiple of the page size in length or are taken from the // ** first 100 bytes of the database file. -// ** +// ** // ** (5) All writes to the database file are synced prior to the rollback journal // ** being deleted, truncated, or zeroed. -// ** +// ** // ** (6) If a super-journal file is used, then all writes to the database file // ** are synced prior to the super-journal being deleted. -// ** +// ** // ** Definition: Two databases (or the same database at two points it time) // ** are said to be "logically equivalent" if they give the same answer to // ** all queries. Note in particular the content of freelist leaf // ** pages can be changed arbitrarily without affecting the logical equivalence // ** of the database. -// ** +// ** // ** (7) At any time, if any subset, including the empty set and the total set, -// ** of the unsynced changes to a rollback journal are removed and the +// ** of the unsynced changes to a rollback journal are removed and the // ** journal is rolled back, the resulting database file will be logically // ** equivalent to the database file at the beginning of the transaction. -// ** +// ** // ** (8) When a transaction is rolled back, the xTruncate method of the VFS // ** is called to restore the database file to the same size it was at // ** the beginning of the transaction. (In some VFSes, the xTruncate // ** method is a no-op, but that does not change the fact the SQLite will // ** invoke it.) -// ** +// ** // ** (9) Whenever the database file is modified, at least one bit in the range // ** of bytes from 24 through 39 inclusive will be changed prior to releasing // ** the EXCLUSIVE lock, thus signaling other connections on the same @@ -121,7 +120,7 @@ // /* // ** The following two macros are used within the PAGERTRACE() macros above -// ** to print out file-descriptors. +// ** to print out file-descriptors. // ** // ** PAGERID() takes a pointer to a Pager struct as its argument. The // ** associated file-descriptor is returned. FILEHANDLEID() takes an sqlite3_file @@ -142,7 +141,7 @@ // ** | | | // ** | V | // ** |<-------WRITER_LOCKED------> ERROR -// ** | | ^ +// ** | | ^ // ** | V | // ** |<------WRITER_CACHEMOD-------->| // ** | | | @@ -154,7 +153,7 @@ // ** // ** // ** List of state transitions and the C [function] that performs each: -// ** +// ** // ** OPEN -> READER [sqlite3PagerSharedLock] // ** READER -> OPEN [pager_unlock] // ** @@ -166,7 +165,7 @@ // ** // ** WRITER_*** -> ERROR [pager_error] // ** ERROR -> OPEN [pager_unlock] -// ** +// ** // ** // ** OPEN: // ** @@ -180,9 +179,9 @@ // ** // ** READER: // ** -// ** In this state all the requirements for reading the database in +// ** In this state all the requirements for reading the database in // ** rollback (non-WAL) mode are met. Unless the pager is (or recently -// ** was) in exclusive-locking mode, a user-level read transaction is +// ** was) in exclusive-locking mode, a user-level read transaction is // ** open. The database size is known in this state. // ** // ** A connection running with locking_mode=normal enters this state when @@ -192,28 +191,28 @@ // ** this state even after the read-transaction is closed. The only way // ** a locking_mode=exclusive connection can transition from READER to OPEN // ** is via the ERROR state (see below). -// ** +// ** // ** * A read transaction may be active (but a write-transaction cannot). // ** * A SHARED or greater lock is held on the database file. -// ** * The dbSize variable may be trusted (even if a user-level read +// ** * The dbSize variable may be trusted (even if a user-level read // ** transaction is not active). The dbOrigSize and dbFileSize variables // ** may not be trusted at this point. // ** * If the database is a WAL database, then the WAL connection is open. -// ** * Even if a read-transaction is not open, it is guaranteed that +// ** * Even if a read-transaction is not open, it is guaranteed that // ** there is no hot-journal in the file-system. // ** // ** WRITER_LOCKED: // ** // ** The pager moves to this state from READER when a write-transaction -// ** is first opened on the database. In WRITER_LOCKED state, all locks -// ** required to start a write-transaction are held, but no actual +// ** is first opened on the database. In WRITER_LOCKED state, all locks +// ** required to start a write-transaction are held, but no actual // ** modifications to the cache or database have taken place. // ** -// ** In rollback mode, a RESERVED or (if the transaction was opened with +// ** In rollback mode, a RESERVED or (if the transaction was opened with // ** BEGIN EXCLUSIVE) EXCLUSIVE lock is obtained on the database file when -// ** moving to this state, but the journal file is not written to or opened -// ** to in this state. If the transaction is committed or rolled back while -// ** in WRITER_LOCKED state, all that is required is to unlock the database +// ** moving to this state, but the journal file is not written to or opened +// ** to in this state. If the transaction is committed or rolled back while +// ** in WRITER_LOCKED state, all that is required is to unlock the database // ** file. // ** // ** IN WAL mode, WalBeginWriteTransaction() is called to lock the log file. @@ -221,7 +220,7 @@ // ** is made to obtain an EXCLUSIVE lock on the database file. // ** // ** * A write transaction is active. -// ** * If the connection is open in rollback-mode, a RESERVED or greater +// ** * If the connection is open in rollback-mode, a RESERVED or greater // ** lock is held on the database file. // ** * If the connection is open in WAL-mode, a WAL write transaction // ** is open (i.e. sqlite3WalBeginWriteTransaction() has been successfully @@ -240,7 +239,7 @@ // ** // ** * A write transaction is active. // ** * A RESERVED or greater lock is held on the database file. -// ** * The journal file is open and the first header has been written +// ** * The journal file is open and the first header has been written // ** to it, but the header has not been synced to disk. // ** * The contents of the page cache have been modified. // ** @@ -253,7 +252,7 @@ // ** // ** * A write transaction is active. // ** * An EXCLUSIVE or greater lock is held on the database file. -// ** * The journal file is open and the first header has been written +// ** * The journal file is open and the first header has been written // ** and synced to disk. // ** * The contents of the page cache have been modified (and possibly // ** written to disk). @@ -265,8 +264,8 @@ // ** A rollback-mode pager changes to WRITER_FINISHED state from WRITER_DBMOD // ** state after the entire transaction has been successfully written into the // ** database file. In this state the transaction may be committed simply -// ** by finalizing the journal file. Once in WRITER_FINISHED state, it is -// ** not possible to modify the database further. At this point, the upper +// ** by finalizing the journal file. Once in WRITER_FINISHED state, it is +// ** not possible to modify the database further. At this point, the upper // ** layer must either commit or rollback the transaction. // ** // ** * A write transaction is active. @@ -274,19 +273,19 @@ // ** * All writing and syncing of journal and database data has finished. // ** If no error occurred, all that remains is to finalize the journal to // ** commit the transaction. If an error did occur, the caller will need -// ** to rollback the transaction. +// ** to rollback the transaction. // ** // ** ERROR: // ** // ** The ERROR state is entered when an IO or disk-full error (including -// ** SQLITE_IOERR_NOMEM) occurs at a point in the code that makes it -// ** difficult to be sure that the in-memory pager state (cache contents, +// ** SQLITE_IOERR_NOMEM) occurs at a point in the code that makes it +// ** difficult to be sure that the in-memory pager state (cache contents, // ** db size etc.) are consistent with the contents of the file-system. // ** // ** Temporary pager files may enter the ERROR state, but in-memory pagers // ** cannot. // ** -// ** For example, if an IO error occurs while performing a rollback, +// ** For example, if an IO error occurs while performing a rollback, // ** the contents of the page-cache may be left in an inconsistent state. // ** At this point it would be dangerous to change back to READER state // ** (as usually happens after a rollback). Any subsequent readers might @@ -296,13 +295,13 @@ // ** instead of READER following such an error. // ** // ** Once it has entered the ERROR state, any attempt to use the pager -// ** to read or write data returns an error. Eventually, once all +// ** to read or write data returns an error. Eventually, once all // ** outstanding transactions have been abandoned, the pager is able to -// ** transition back to OPEN state, discarding the contents of the +// ** transition back to OPEN state, discarding the contents of the // ** page-cache and any other in-memory state at the same time. Everything // ** is reloaded from disk (and, if necessary, hot-journal rollback peformed) // ** when a read-transaction is next opened on the pager (transitioning -// ** the pager into READER state). At that point the system has recovered +// ** the pager into READER state). At that point the system has recovered // ** from the error. // ** // ** Specifically, the pager jumps into the ERROR state if: @@ -318,21 +317,21 @@ // ** memory. // ** // ** In other cases, the error is returned to the b-tree layer. The b-tree -// ** layer then attempts a rollback operation. If the error condition +// ** layer then attempts a rollback operation. If the error condition // ** persists, the pager enters the ERROR state via condition (1) above. // ** // ** Condition (3) is necessary because it can be triggered by a read-only // ** statement executed within a transaction. In this case, if the error // ** code were simply returned to the user, the b-tree layer would not // ** automatically attempt a rollback, as it assumes that an error in a -// ** read-only statement cannot leave the pager in an internally inconsistent +// ** read-only statement cannot leave the pager in an internally inconsistent // ** state. // ** // ** * The Pager.errCode variable is set to something other than SQLITE_OK. // ** * There are one or more outstanding references to pages (after the // ** last reference is dropped the pager should move back to OPEN state). // ** * The pager is not an in-memory pager. -// ** +// ** // ** // ** Notes: // ** @@ -342,7 +341,7 @@ // ** // ** * Normally, a connection open in exclusive mode is never in PAGER_OPEN // ** state. There are two exceptions: immediately after exclusive-mode has -// ** been turned on (and before any read or write transactions are +// ** been turned on (and before any read or write transactions are // ** executed), and when the pager is leaving the "error state". // ** // ** * See also: assert_pager_state(). @@ -356,7 +355,7 @@ // #define PAGER_ERROR 6 // /* -// ** The Pager.eLock variable is almost always set to one of the +// ** The Pager.eLock variable is almost always set to one of the // ** following locking-states, according to the lock currently held on // ** the database file: NO_LOCK, SHARED_LOCK, RESERVED_LOCK or EXCLUSIVE_LOCK. // ** This variable is kept up to date as locks are taken and released by @@ -371,20 +370,20 @@ // ** to a less exclusive (lower) value than the lock that is actually held // ** at the system level, but it is never set to a more exclusive value. // ** -// ** This is usually safe. If an xUnlock fails or appears to fail, there may +// ** This is usually safe. If an xUnlock fails or appears to fail, there may // ** be a few redundant xLock() calls or a lock may be held for longer than // ** required, but nothing really goes wrong. // ** // ** The exception is when the database file is unlocked as the pager moves -// ** from ERROR to OPEN state. At this point there may be a hot-journal file +// ** from ERROR to OPEN state. At this point there may be a hot-journal file // ** in the file-system that needs to be rolled back (as part of an OPEN->SHARED // ** transition, by the same pager or any other). If the call to xUnlock() // ** fails at this point and the pager is left holding an EXCLUSIVE lock, this // ** can confuse the call to xCheckReservedLock() call made later as part // ** of hot-journal detection. // ** -// ** xCheckReservedLock() is defined as returning true "if there is a RESERVED -// ** lock held by this process or any others". So xCheckReservedLock may +// ** xCheckReservedLock() is defined as returning true "if there is a RESERVED +// ** lock held by this process or any others". So xCheckReservedLock may // ** return true because the caller itself is holding an EXCLUSIVE lock (but // ** doesn't know it because of a previous error in xUnlock). If this happens // ** a hot-journal may be mistaken for a journal being created by an active @@ -395,25 +394,24 @@ // ** database in the ERROR state, Pager.eLock is set to UNKNOWN_LOCK. It // ** is only changed back to a real locking state after a successful call // ** to xLock(EXCLUSIVE). Also, the code to do the OPEN->SHARED state transition -// ** omits the check for a hot-journal if Pager.eLock is set to UNKNOWN_LOCK +// ** omits the check for a hot-journal if Pager.eLock is set to UNKNOWN_LOCK // ** lock. Instead, it assumes a hot-journal exists and obtains an EXCLUSIVE // ** lock on the database file before attempting to roll it back. See function // ** PagerSharedLock() for more detail. // ** -// ** Pager.eLock may only be set to UNKNOWN_LOCK when the pager is in +// ** Pager.eLock may only be set to UNKNOWN_LOCK when the pager is in // ** PAGER_OPEN state. // */ // #define UNKNOWN_LOCK (EXCLUSIVE_LOCK+1) // /* -// ** The maximum allowed sector size. 64KiB. If the xSectorsize() method +// ** The maximum allowed sector size. 64KiB. If the xSectorsize() method // ** returns a value larger than this, then MAX_SECTOR_SIZE is used instead. // ** This could conceivably cause corruption following a power failure on // ** such a system. This is currently an undocumented limit. // */ // #define MAX_SECTOR_SIZE 0x10000 - // /* // ** An instance of the following structure is allocated for each active // ** savepoint and statement transaction in the system. All such structures @@ -422,7 +420,7 @@ // ** // ** When a savepoint is created, the PagerSavepoint.iHdrOffset field is // ** set to 0. If a journal-header is written into the main journal while -// ** the savepoint is active, then iHdrOffset is set to the byte offset +// ** the savepoint is active, then iHdrOffset is set to the byte offset // ** immediately following the last journal record written into the main // ** journal before the journal-header. This is required during savepoint // ** rollback (see pagerPlaybackSavepoint()). @@ -447,262 +445,262 @@ // #define SPILLFLAG_ROLLBACK 0x02 /* Current rolling back, so do not spill */ // #define SPILLFLAG_NOSYNC 0x04 /* Spill is ok, but do not sync */ -// /* -// ** An open page cache is an instance of struct Pager. A description of -// ** some of the more important member variables follows: -// ** -// ** eState -// ** -// ** The current 'state' of the pager object. See the comment and state -// ** diagram above for a description of the pager state. -// ** -// ** eLock -// ** -// ** For a real on-disk database, the current lock held on the database file - -// ** NO_LOCK, SHARED_LOCK, RESERVED_LOCK or EXCLUSIVE_LOCK. -// ** -// ** For a temporary or in-memory database (neither of which require any -// ** locks), this variable is always set to EXCLUSIVE_LOCK. Since such -// ** databases always have Pager.exclusiveMode==1, this tricks the pager -// ** logic into thinking that it already has all the locks it will ever -// ** need (and no reason to release them). -// ** -// ** In some (obscure) circumstances, this variable may also be set to -// ** UNKNOWN_LOCK. See the comment above the #define of UNKNOWN_LOCK for -// ** details. -// ** -// ** changeCountDone -// ** -// ** This boolean variable is used to make sure that the change-counter -// ** (the 4-byte header field at byte offset 24 of the database file) is -// ** not updated more often than necessary. -// ** -// ** It is set to true when the change-counter field is updated, which -// ** can only happen if an exclusive lock is held on the database file. -// ** It is cleared (set to false) whenever an exclusive lock is -// ** relinquished on the database file. Each time a transaction is committed, -// ** The changeCountDone flag is inspected. If it is true, the work of -// ** updating the change-counter is omitted for the current transaction. -// ** -// ** This mechanism means that when running in exclusive mode, a connection -// ** need only update the change-counter once, for the first transaction -// ** committed. -// ** -// ** setSuper -// ** -// ** When PagerCommitPhaseOne() is called to commit a transaction, it may -// ** (or may not) specify a super-journal name to be written into the -// ** journal file before it is synced to disk. -// ** -// ** Whether or not a journal file contains a super-journal pointer affects -// ** the way in which the journal file is finalized after the transaction is -// ** committed or rolled back when running in "journal_mode=PERSIST" mode. -// ** If a journal file does not contain a super-journal pointer, it is -// ** finalized by overwriting the first journal header with zeroes. If -// ** it does contain a super-journal pointer the journal file is finalized -// ** by truncating it to zero bytes, just as if the connection were -// ** running in "journal_mode=truncate" mode. -// ** -// ** Journal files that contain super-journal pointers cannot be finalized -// ** simply by overwriting the first journal-header with zeroes, as the -// ** super-journal pointer could interfere with hot-journal rollback of any -// ** subsequently interrupted transaction that reuses the journal file. -// ** -// ** The flag is cleared as soon as the journal file is finalized (either -// ** by PagerCommitPhaseTwo or PagerRollback). If an IO error prevents the -// ** journal file from being successfully finalized, the setSuper flag -// ** is cleared anyway (and the pager will move to ERROR state). -// ** -// ** doNotSpill -// ** -// ** This variables control the behavior of cache-spills (calls made by -// ** the pcache module to the pagerStress() routine to write cached data -// ** to the file-system in order to free up memory). -// ** -// ** When bits SPILLFLAG_OFF or SPILLFLAG_ROLLBACK of doNotSpill are set, -// ** writing to the database from pagerStress() is disabled altogether. -// ** The SPILLFLAG_ROLLBACK case is done in a very obscure case that -// ** comes up during savepoint rollback that requires the pcache module -// ** to allocate a new page to prevent the journal file from being written -// ** while it is being traversed by code in pager_playback(). The SPILLFLAG_OFF -// ** case is a user preference. -// ** -// ** If the SPILLFLAG_NOSYNC bit is set, writing to the database from -// ** pagerStress() is permitted, but syncing the journal file is not. -// ** This flag is set by sqlite3PagerWrite() when the file-system sector-size -// ** is larger than the database page-size in order to prevent a journal sync -// ** from happening in between the journalling of two pages on the same sector. -// ** -// ** subjInMemory -// ** -// ** This is a boolean variable. If true, then any required sub-journal -// ** is opened as an in-memory journal file. If false, then in-memory -// ** sub-journals are only used for in-memory pager files. -// ** -// ** This variable is updated by the upper layer each time a new -// ** write-transaction is opened. -// ** -// ** dbSize, dbOrigSize, dbFileSize -// ** -// ** Variable dbSize is set to the number of pages in the database file. -// ** It is valid in PAGER_READER and higher states (all states except for -// ** OPEN and ERROR). -// ** -// ** dbSize is set based on the size of the database file, which may be -// ** larger than the size of the database (the value stored at offset -// ** 28 of the database header by the btree). If the size of the file -// ** is not an integer multiple of the page-size, the value stored in -// ** dbSize is rounded down (i.e. a 5KB file with 2K page-size has dbSize==2). -// ** Except, any file that is greater than 0 bytes in size is considered -// ** to have at least one page. (i.e. a 1KB file with 2K page-size leads -// ** to dbSize==1). -// ** -// ** During a write-transaction, if pages with page-numbers greater than -// ** dbSize are modified in the cache, dbSize is updated accordingly. -// ** Similarly, if the database is truncated using PagerTruncateImage(), -// ** dbSize is updated. -// ** -// ** Variables dbOrigSize and dbFileSize are valid in states -// ** PAGER_WRITER_LOCKED and higher. dbOrigSize is a copy of the dbSize -// ** variable at the start of the transaction. It is used during rollback, -// ** and to determine whether or not pages need to be journalled before -// ** being modified. -// ** -// ** Throughout a write-transaction, dbFileSize contains the size of -// ** the file on disk in pages. It is set to a copy of dbSize when the -// ** write-transaction is first opened, and updated when VFS calls are made -// ** to write or truncate the database file on disk. -// ** -// ** The only reason the dbFileSize variable is required is to suppress -// ** unnecessary calls to xTruncate() after committing a transaction. If, -// ** when a transaction is committed, the dbFileSize variable indicates -// ** that the database file is larger than the database image (Pager.dbSize), -// ** pager_truncate() is called. The pager_truncate() call uses xFilesize() -// ** to measure the database file on disk, and then truncates it if required. -// ** dbFileSize is not used when rolling back a transaction. In this case -// ** pager_truncate() is called unconditionally (which means there may be -// ** a call to xFilesize() that is not strictly required). In either case, -// ** pager_truncate() may cause the file to become smaller or larger. -// ** -// ** dbHintSize -// ** -// ** The dbHintSize variable is used to limit the number of calls made to -// ** the VFS xFileControl(FCNTL_SIZE_HINT) method. -// ** -// ** dbHintSize is set to a copy of the dbSize variable when a -// ** write-transaction is opened (at the same time as dbFileSize and -// ** dbOrigSize). If the xFileControl(FCNTL_SIZE_HINT) method is called, -// ** dbHintSize is increased to the number of pages that correspond to the -// ** size-hint passed to the method call. See pager_write_pagelist() for -// ** details. -// ** -// ** errCode -// ** -// ** The Pager.errCode variable is only ever used in PAGER_ERROR state. It -// ** is set to zero in all other states. In PAGER_ERROR state, Pager.errCode -// ** is always set to SQLITE_FULL, SQLITE_IOERR or one of the SQLITE_IOERR_XXX -// ** sub-codes. -// ** -// ** syncFlags, walSyncFlags -// ** -// ** syncFlags is either SQLITE_SYNC_NORMAL (0x02) or SQLITE_SYNC_FULL (0x03). -// ** syncFlags is used for rollback mode. walSyncFlags is used for WAL mode -// ** and contains the flags used to sync the checkpoint operations in the -// ** lower two bits, and sync flags used for transaction commits in the WAL -// ** file in bits 0x04 and 0x08. In other words, to get the correct sync flags -// ** for checkpoint operations, use (walSyncFlags&0x03) and to get the correct -// ** sync flags for transaction commit, use ((walSyncFlags>>2)&0x03). Note -// ** that with synchronous=NORMAL in WAL mode, transaction commit is not synced -// ** meaning that the 0x04 and 0x08 bits are both zero. -// */ -// struct Pager { -// sqlite3_vfs *pVfs; /* OS functions to use for IO */ -// u8 exclusiveMode; /* Boolean. True if locking_mode==EXCLUSIVE */ -// u8 journalMode; /* One of the PAGER_JOURNALMODE_* values */ -// u8 useJournal; /* Use a rollback journal on this file */ -// u8 noSync; /* Do not sync the journal if true */ -// u8 fullSync; /* Do extra syncs of the journal for robustness */ -// u8 extraSync; /* sync directory after journal delete */ -// u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */ -// u8 walSyncFlags; /* See description above */ -// u8 tempFile; /* zFilename is a temporary or immutable file */ -// u8 noLock; /* Do not lock (except in WAL mode) */ -// u8 readOnly; /* True for a read-only database */ -// u8 memDb; /* True to inhibit all file I/O */ -// u8 memVfs; /* VFS-implemented memory database */ +/* +** An open page cache is an instance of struct Pager. A description of +** some of the more important member variables follows: +** +** eState +** +** The current 'state' of the pager object. See the comment and state +** diagram above for a description of the pager state. +** +** eLock +** +** For a real on-disk database, the current lock held on the database file - +** NO_LOCK, SHARED_LOCK, RESERVED_LOCK or EXCLUSIVE_LOCK. +** +** For a temporary or in-memory database (neither of which require any +** locks), this variable is always set to EXCLUSIVE_LOCK. Since such +** databases always have Pager.exclusiveMode==1, this tricks the pager +** logic into thinking that it already has all the locks it will ever +** need (and no reason to release them). +** +** In some (obscure) circumstances, this variable may also be set to +** UNKNOWN_LOCK. See the comment above the #define of UNKNOWN_LOCK for +** details. +** +** changeCountDone +** +** This boolean variable is used to make sure that the change-counter +** (the 4-byte header field at byte offset 24 of the database file) is +** not updated more often than necessary. +** +** It is set to true when the change-counter field is updated, which +** can only happen if an exclusive lock is held on the database file. +** It is cleared (set to false) whenever an exclusive lock is +** relinquished on the database file. Each time a transaction is committed, +** The changeCountDone flag is inspected. If it is true, the work of +** updating the change-counter is omitted for the current transaction. +** +** This mechanism means that when running in exclusive mode, a connection +** need only update the change-counter once, for the first transaction +** committed. +** +** setSuper +** +** When PagerCommitPhaseOne() is called to commit a transaction, it may +** (or may not) specify a super-journal name to be written into the +** journal file before it is synced to disk. +** +** Whether or not a journal file contains a super-journal pointer affects +** the way in which the journal file is finalized after the transaction is +** committed or rolled back when running in "journal_mode=PERSIST" mode. +** If a journal file does not contain a super-journal pointer, it is +** finalized by overwriting the first journal header with zeroes. If +** it does contain a super-journal pointer the journal file is finalized +** by truncating it to zero bytes, just as if the connection were +** running in "journal_mode=truncate" mode. +** +** Journal files that contain super-journal pointers cannot be finalized +** simply by overwriting the first journal-header with zeroes, as the +** super-journal pointer could interfere with hot-journal rollback of any +** subsequently interrupted transaction that reuses the journal file. +** +** The flag is cleared as soon as the journal file is finalized (either +** by PagerCommitPhaseTwo or PagerRollback). If an IO error prevents the +** journal file from being successfully finalized, the setSuper flag +** is cleared anyway (and the pager will move to ERROR state). +** +** doNotSpill +** +** This variables control the behavior of cache-spills (calls made by +** the pcache module to the pagerStress() routine to write cached data +** to the file-system in order to free up memory). +** +** When bits SPILLFLAG_OFF or SPILLFLAG_ROLLBACK of doNotSpill are set, +** writing to the database from pagerStress() is disabled altogether. +** The SPILLFLAG_ROLLBACK case is done in a very obscure case that +** comes up during savepoint rollback that requires the pcache module +** to allocate a new page to prevent the journal file from being written +** while it is being traversed by code in pager_playback(). The SPILLFLAG_OFF +** case is a user preference. +** +** If the SPILLFLAG_NOSYNC bit is set, writing to the database from +** pagerStress() is permitted, but syncing the journal file is not. +** This flag is set by sqlite3PagerWrite() when the file-system sector-size +** is larger than the database page-size in order to prevent a journal sync +** from happening in between the journalling of two pages on the same sector. +** +** subjInMemory +** +** This is a boolean variable. If true, then any required sub-journal +** is opened as an in-memory journal file. If false, then in-memory +** sub-journals are only used for in-memory pager files. +** +** This variable is updated by the upper layer each time a new +** write-transaction is opened. +** +** dbSize, dbOrigSize, dbFileSize +** +** Variable dbSize is set to the number of pages in the database file. +** It is valid in PAGER_READER and higher states (all states except for +** OPEN and ERROR). +** +** dbSize is set based on the size of the database file, which may be +** larger than the size of the database (the value stored at offset +** 28 of the database header by the btree). If the size of the file +** is not an integer multiple of the page-size, the value stored in +** dbSize is rounded down (i.e. a 5KB file with 2K page-size has dbSize==2). +** Except, any file that is greater than 0 bytes in size is considered +** to have at least one page. (i.e. a 1KB file with 2K page-size leads +** to dbSize==1). +** +** During a write-transaction, if pages with page-numbers greater than +** dbSize are modified in the cache, dbSize is updated accordingly. +** Similarly, if the database is truncated using PagerTruncateImage(), +** dbSize is updated. +** +** Variables dbOrigSize and dbFileSize are valid in states +** PAGER_WRITER_LOCKED and higher. dbOrigSize is a copy of the dbSize +** variable at the start of the transaction. It is used during rollback, +** and to determine whether or not pages need to be journalled before +** being modified. +** +** Throughout a write-transaction, dbFileSize contains the size of +** the file on disk in pages. It is set to a copy of dbSize when the +** write-transaction is first opened, and updated when VFS calls are made +** to write or truncate the database file on disk. +** +** The only reason the dbFileSize variable is required is to suppress +** unnecessary calls to xTruncate() after committing a transaction. If, +** when a transaction is committed, the dbFileSize variable indicates +** that the database file is larger than the database image (Pager.dbSize), +** pager_truncate() is called. The pager_truncate() call uses xFilesize() +** to measure the database file on disk, and then truncates it if required. +** dbFileSize is not used when rolling back a transaction. In this case +** pager_truncate() is called unconditionally (which means there may be +** a call to xFilesize() that is not strictly required). In either case, +** pager_truncate() may cause the file to become smaller or larger. +** +** dbHintSize +** +** The dbHintSize variable is used to limit the number of calls made to +** the VFS xFileControl(FCNTL_SIZE_HINT) method. +** +** dbHintSize is set to a copy of the dbSize variable when a +** write-transaction is opened (at the same time as dbFileSize and +** dbOrigSize). If the xFileControl(FCNTL_SIZE_HINT) method is called, +** dbHintSize is increased to the number of pages that correspond to the +** size-hint passed to the method call. See pager_write_pagelist() for +** details. +** +** errCode +** +** The Pager.errCode variable is only ever used in PAGER_ERROR state. It +** is set to zero in all other states. In PAGER_ERROR state, Pager.errCode +** is always set to SQLITE_FULL, SQLITE_IOERR or one of the SQLITE_IOERR_XXX +** sub-codes. +** +** syncFlags, walSyncFlags +** +** syncFlags is either SQLITE_SYNC_NORMAL (0x02) or SQLITE_SYNC_FULL (0x03). +** syncFlags is used for rollback mode. walSyncFlags is used for WAL mode +** and contains the flags used to sync the checkpoint operations in the +** lower two bits, and sync flags used for transaction commits in the WAL +** file in bits 0x04 and 0x08. In other words, to get the correct sync flags +** for checkpoint operations, use (walSyncFlags&0x03) and to get the correct +** sync flags for transaction commit, use ((walSyncFlags>>2)&0x03). Note +** that with synchronous=NORMAL in WAL mode, transaction commit is not synced +** meaning that the 0x04 and 0x08 bits are both zero. +*/ +struct Pager { + // sqlite3_vfs *pVfs; /* OS functions to use for IO */ + // u8 exclusiveMode; /* Boolean. True if locking_mode==EXCLUSIVE */ + // u8 journalMode; /* One of the PAGER_JOURNALMODE_* values */ + // u8 useJournal; /* Use a rollback journal on this file */ + // u8 noSync; /* Do not sync the journal if true */ + // u8 fullSync; /* Do extra syncs of the journal for robustness */ + // u8 extraSync; /* sync directory after journal delete */ + // u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */ + // u8 walSyncFlags; /* See description above */ + // u8 tempFile; /* zFilename is a temporary or immutable file */ + // u8 noLock; /* Do not lock (except in WAL mode) */ + // u8 readOnly; /* True for a read-only database */ + // u8 memDb; /* True to inhibit all file I/O */ + // u8 memVfs; /* VFS-implemented memory database */ -// /************************************************************************** -// ** The following block contains those class members that change during -// ** routine operation. Class members not in this block are either fixed -// ** when the pager is first created or else only change when there is a -// ** significant mode change (such as changing the page_size, locking_mode, -// ** or the journal_mode). From another view, these class members describe -// ** the "state" of the pager, while other class members describe the -// ** "configuration" of the pager. -// */ -// u8 eState; /* Pager state (OPEN, READER, WRITER_LOCKED..) */ -// u8 eLock; /* Current lock held on database file */ -// u8 changeCountDone; /* Set after incrementing the change-counter */ -// u8 setSuper; /* Super-jrnl name is written into jrnl */ -// u8 doNotSpill; /* Do not spill the cache when non-zero */ -// u8 subjInMemory; /* True to use in-memory sub-journals */ -// u8 bUseFetch; /* True to use xFetch() */ -// u8 hasHeldSharedLock; /* True if a shared lock has ever been held */ -// Pgno dbSize; /* Number of pages in the database */ -// Pgno dbOrigSize; /* dbSize before the current transaction */ -// Pgno dbFileSize; /* Number of pages in the database file */ -// Pgno dbHintSize; /* Value passed to FCNTL_SIZE_HINT call */ -// int errCode; /* One of several kinds of errors */ -// int nRec; /* Pages journalled since last j-header written */ -// u32 cksumInit; /* Quasi-random value added to every checksum */ -// u32 nSubRec; /* Number of records written to sub-journal */ -// Bitvec *pInJournal; /* One bit for each page in the database file */ -// sqlite3_file *fd; /* File descriptor for database */ -// sqlite3_file *jfd; /* File descriptor for main journal */ -// sqlite3_file *sjfd; /* File descriptor for sub-journal */ -// i64 journalOff; /* Current write offset in the journal file */ -// i64 journalHdr; /* Byte offset to previous journal header */ -// sqlite3_backup *pBackup; /* Pointer to list of ongoing backup processes */ -// PagerSavepoint *aSavepoint; /* Array of active savepoints */ -// int nSavepoint; /* Number of elements in aSavepoint[] */ -// u32 iDataVersion; /* Changes whenever database content changes */ -// char dbFileVers[16]; /* Changes whenever database file changes */ + // /************************************************************************** + // ** The following block contains those class members that change during + // ** routine operation. Class members not in this block are either fixed + // ** when the pager is first created or else only change when there is a + // ** significant mode change (such as changing the page_size, locking_mode, + // ** or the journal_mode). From another view, these class members describe + // ** the "state" of the pager, while other class members describe the + // ** "configuration" of the pager. + // */ + // u8 eState; /* Pager state (OPEN, READER, WRITER_LOCKED..) */ + // u8 eLock; /* Current lock held on database file */ + // u8 changeCountDone; /* Set after incrementing the change-counter */ + // u8 setSuper; /* Super-jrnl name is written into jrnl */ + // u8 doNotSpill; /* Do not spill the cache when non-zero */ + // u8 subjInMemory; /* True to use in-memory sub-journals */ + // u8 bUseFetch; /* True to use xFetch() */ + // u8 hasHeldSharedLock; /* True if a shared lock has ever been held */ + // Pgno dbSize; /* Number of pages in the database */ + // Pgno dbOrigSize; /* dbSize before the current transaction */ + // Pgno dbFileSize; /* Number of pages in the database file */ + // Pgno dbHintSize; /* Value passed to FCNTL_SIZE_HINT call */ + // int errCode; /* One of several kinds of errors */ + // int nRec; /* Pages journalled since last j-header written */ + // u32 cksumInit; /* Quasi-random value added to every checksum */ + // u32 nSubRec; /* Number of records written to sub-journal */ + // Bitvec *pInJournal; /* One bit for each page in the database file */ + // sqlite3_file *fd; /* File descriptor for database */ + // sqlite3_file *jfd; /* File descriptor for main journal */ + // sqlite3_file *sjfd; /* File descriptor for sub-journal */ + // i64 journalOff; /* Current write offset in the journal file */ + // i64 journalHdr; /* Byte offset to previous journal header */ + // sqlite3_backup *pBackup; /* Pointer to list of ongoing backup processes */ + // PagerSavepoint *aSavepoint; /* Array of active savepoints */ + // int nSavepoint; /* Number of elements in aSavepoint[] */ + // u32 iDataVersion; /* Changes whenever database content changes */ + // char dbFileVers[16]; /* Changes whenever database file changes */ -// int nMmapOut; /* Number of mmap pages currently outstanding */ -// sqlite3_int64 szMmap; /* Desired maximum mmap size */ -// PgHdr *pMmapFreelist; /* List of free mmap page headers (pDirty) */ -// /* -// ** End of the routinely-changing class members -// ***************************************************************************/ + // int nMmapOut; /* Number of mmap pages currently outstanding */ + // sqlite3_int64 szMmap; /* Desired maximum mmap size */ + // PgHdr *pMmapFreelist; /* List of free mmap page headers (pDirty) */ + // /* + // ** End of the routinely-changing class members + // ***************************************************************************/ -// u16 nExtra; /* Add this many bytes to each in-memory page */ -// i16 nReserve; /* Number of unused bytes at end of each page */ -// u32 vfsFlags; /* Flags for sqlite3_vfs.xOpen() */ -// u32 sectorSize; /* Assumed sector size during rollback */ -// Pgno mxPgno; /* Maximum allowed size of the database */ -// i64 pageSize; /* Number of bytes in a page */ -// i64 journalSizeLimit; /* Size limit for persistent journal files */ -// char *zFilename; /* Name of the database file */ -// char *zJournal; /* Name of the journal file */ -// int (*xBusyHandler)(void*); /* Function to call when busy */ -// void *pBusyHandlerArg; /* Context argument for xBusyHandler */ -// int aStat[4]; /* Total cache hits, misses, writes, spills */ -// #ifdef SQLITE_TEST -// int nRead; /* Database pages read */ -// #endif -// void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */ -// int (*xGet)(Pager*,Pgno,DbPage**,int); /* Routine to fetch a patch */ -// char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ -// PCache *pPCache; /* Pointer to page cache object */ -// #ifndef SQLITE_OMIT_WAL -// Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */ -// char *zWal; /* File name for write-ahead log */ -// #endif -// }; + // u16 nExtra; /* Add this many bytes to each in-memory page */ + // i16 nReserve; /* Number of unused bytes at end of each page */ + // u32 vfsFlags; /* Flags for sqlite3_vfs.xOpen() */ + // u32 sectorSize; /* Assumed sector size during rollback */ + // Pgno mxPgno; /* Maximum allowed size of the database */ + // i64 pageSize; /* Number of bytes in a page */ + // i64 journalSizeLimit; /* Size limit for persistent journal files */ + // char *zFilename; /* Name of the database file */ + // char *zJournal; /* Name of the journal file */ + // int (*xBusyHandler)(void*); /* Function to call when busy */ + // void *pBusyHandlerArg; /* Context argument for xBusyHandler */ + // int aStat[4]; /* Total cache hits, misses, writes, spills */ + // #ifdef SQLITE_TEST + // int nRead; /* Database pages read */ + // #endif + // void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */ + // int (*xGet)(Pager*,Pgno,DbPage**,int); /* Routine to fetch a patch */ + // char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ + // PCache *pPCache; /* Pointer to page cache object */ + // #ifndef SQLITE_OMIT_WAL + // Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */ + // char *zWal; /* File name for write-ahead log */ + // #endif +}; // /* // ** Indexes for use with Pager.aStat[]. The Pager.aStat[] array contains -// ** the values accessed by passing SQLITE_DBSTATUS_CACHE_HIT, CACHE_MISS +// ** the values accessed by passing SQLITE_DBSTATUS_CACHE_HIT, CACHE_MISS // ** or CACHE_WRITE to sqlite3_db_status(). // */ // #define PAGER_STAT_HIT 0 @@ -724,8 +722,6 @@ // # define PAGER_INCR(v) // #endif - - // /* // ** Journal files begin with the following magic string. The data // ** was obtained from /dev/random. It is used only as a sanity check. @@ -760,7 +756,7 @@ // #define JOURNAL_PG_SZ(pPager) ((pPager->pageSize) + 8) // /* -// ** The journal header size for this pager. This is usually the same +// ** The journal header size for this pager. This is usually the same // ** size as a single disk sector. See also setSectorSize(). // */ // #define JOURNAL_HDR_SZ(pPager) (pPager->sectorSize) @@ -835,7 +831,7 @@ // # define pagerBeginReadTransaction(z) SQLITE_OK // #endif -// #ifndef NDEBUG +// #ifndef NDEBUG // /* // ** Usage: // ** @@ -864,25 +860,25 @@ // assert( p->tempFile==0 || p->eLock==EXCLUSIVE_LOCK ); // assert( p->tempFile==0 || pPager->changeCountDone ); -// /* If the useJournal flag is clear, the journal-mode must be "OFF". +// /* If the useJournal flag is clear, the journal-mode must be "OFF". // ** And if the journal-mode is "OFF", the journal file must not be open. // */ // assert( p->journalMode==PAGER_JOURNALMODE_OFF || p->useJournal ); // assert( p->journalMode!=PAGER_JOURNALMODE_OFF || !isOpen(p->jfd) ); -// /* Check that MEMDB implies noSync. And an in-memory journal. Since -// ** this means an in-memory pager performs no IO at all, it cannot encounter -// ** either SQLITE_IOERR or SQLITE_FULL during rollback or while finalizing -// ** a journal file. (although the in-memory journal implementation may -// ** return SQLITE_IOERR_NOMEM while the journal file is being written). It -// ** is therefore not possible for an in-memory pager to enter the ERROR +// /* Check that MEMDB implies noSync. And an in-memory journal. Since +// ** this means an in-memory pager performs no IO at all, it cannot encounter +// ** either SQLITE_IOERR or SQLITE_FULL during rollback or while finalizing +// ** a journal file. (although the in-memory journal implementation may +// ** return SQLITE_IOERR_NOMEM while the journal file is being written). It +// ** is therefore not possible for an in-memory pager to enter the ERROR // ** state. // */ // if( MEMDB ){ // assert( !isOpen(p->fd) ); // assert( p->noSync ); -// assert( p->journalMode==PAGER_JOURNALMODE_OFF -// || p->journalMode==PAGER_JOURNALMODE_MEMORY +// assert( p->journalMode==PAGER_JOURNALMODE_OFF +// || p->journalMode==PAGER_JOURNALMODE_MEMORY // ); // assert( p->eState!=PAGER_ERROR && p->eState!=PAGER_OPEN ); // assert( pagerUseWal(p)==0 ); @@ -929,9 +925,9 @@ // ** to journal_mode=wal. // */ // assert( p->eLock>=RESERVED_LOCK ); -// assert( isOpen(p->jfd) -// || p->journalMode==PAGER_JOURNALMODE_OFF -// || p->journalMode==PAGER_JOURNALMODE_WAL +// assert( isOpen(p->jfd) +// || p->journalMode==PAGER_JOURNALMODE_OFF +// || p->journalMode==PAGER_JOURNALMODE_WAL // ); // } // assert( pPager->dbOrigSize==pPager->dbFileSize ); @@ -943,9 +939,9 @@ // assert( pPager->errCode==SQLITE_OK ); // assert( !pagerUseWal(pPager) ); // assert( p->eLock>=EXCLUSIVE_LOCK ); -// assert( isOpen(p->jfd) -// || p->journalMode==PAGER_JOURNALMODE_OFF -// || p->journalMode==PAGER_JOURNALMODE_WAL +// assert( isOpen(p->jfd) +// || p->journalMode==PAGER_JOURNALMODE_OFF +// || p->journalMode==PAGER_JOURNALMODE_WAL // || (sqlite3OsDeviceCharacteristics(p->fd)&SQLITE_IOCAP_BATCH_ATOMIC) // ); // assert( pPager->dbOrigSize<=pPager->dbHintSize ); @@ -955,9 +951,9 @@ // assert( p->eLock==EXCLUSIVE_LOCK ); // assert( pPager->errCode==SQLITE_OK ); // assert( !pagerUseWal(pPager) ); -// assert( isOpen(p->jfd) -// || p->journalMode==PAGER_JOURNALMODE_OFF -// || p->journalMode==PAGER_JOURNALMODE_WAL +// assert( isOpen(p->jfd) +// || p->journalMode==PAGER_JOURNALMODE_OFF +// || p->journalMode==PAGER_JOURNALMODE_WAL // || (sqlite3OsDeviceCharacteristics(p->fd)&SQLITE_IOCAP_BATCH_ATOMIC) // ); // break; @@ -976,7 +972,7 @@ // } // #endif /* ifndef NDEBUG */ -// #ifdef SQLITE_DEBUG +// #ifdef SQLITE_DEBUG // /* // ** Return a pointer to a human readable string in a static buffer // ** containing the state of the Pager object passed as an argument. This @@ -1110,7 +1106,6 @@ // */ // #define put32bits(A,B) sqlite3Put4byte((u8*)A,B) - // /* // ** Write a 32-bit integer into the given file descriptor. Return SQLITE_OK // ** on success or an error code is something goes wrong. @@ -1127,7 +1122,7 @@ // ** succeeds, set the Pager.eLock variable to match the (attempted) new lock. // ** // ** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is -// ** called, do not modify it. See the comment above the #define of +// ** called, do not modify it. See the comment above the #define of // ** UNKNOWN_LOCK for an explanation of this. // */ // static int pagerUnlockDb(Pager *pPager, int eLock){ @@ -1151,11 +1146,11 @@ // /* // ** Lock the database file to level eLock, which must be either SHARED_LOCK, // ** RESERVED_LOCK or EXCLUSIVE_LOCK. If the caller is successful, set the -// ** Pager.eLock variable to the new locking state. +// ** Pager.eLock variable to the new locking state. // ** -// ** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is -// ** called, do not modify it unless the new locking state is EXCLUSIVE_LOCK. -// ** See the comment above the #define of UNKNOWN_LOCK for an explanation +// ** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is +// ** called, do not modify it unless the new locking state is EXCLUSIVE_LOCK. +// ** See the comment above the #define of UNKNOWN_LOCK for an explanation // ** of this. // */ // static int pagerLockDb(Pager *pPager, int eLock){ @@ -1182,7 +1177,7 @@ // ** (b) the value returned by OsSectorSize() is less than or equal // ** to the page size. // ** -// ** If it can be used, then the value returned is the size of the journal +// ** If it can be used, then the value returned is the size of the journal // ** file when it contains rollback data for exactly one page. // ** // ** The atomic-batch-write optimization can be used if OsDeviceCharacteristics() @@ -1273,8 +1268,8 @@ // /* // ** When this is called the journal file for pager pPager must be open. -// ** This function attempts to read a super-journal file name from the -// ** end of the file and, if successful, copies it into memory supplied +// ** This function attempts to read a super-journal file name from the +// ** end of the file and, if successful, copies it into memory supplied // ** by the caller. See comments above writeSuperJournal() for the format // ** used to store a super-journal file name at the end of a journal file. // ** @@ -1290,7 +1285,7 @@ // ** nul-terminator byte is appended to the buffer following the // ** super-journal file name. // ** -// ** If it is determined that no super-journal file name is present +// ** If it is determined that no super-journal file name is present // ** zSuper[0] is set to 0 and SQLITE_OK returned. // ** // ** If an error occurs while reading from the journal file, an SQLite @@ -1308,9 +1303,9 @@ // if( SQLITE_OK!=(rc = sqlite3OsFileSize(pJrnl, &szJ)) // || szJ<16 // || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len)) -// || len>=nSuper +// || len>=nSuper // || len>szJ-16 -// || len==0 +// || len==0 // || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum)) // || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8)) // || memcmp(aMagic, aJournalMagic, 8) @@ -1333,13 +1328,13 @@ // } // zSuper[len] = '\0'; // zSuper[len+1] = '\0'; - + // return SQLITE_OK; // } // /* -// ** Return the offset of the sector boundary at or immediately -// ** following the value in pPager->journalOff, assuming a sector +// ** Return the offset of the sector boundary at or immediately +// ** following the value in pPager->journalOff, assuming a sector // ** size of pPager->sectorSize bytes. // ** // ** i.e for a sector size of 512: @@ -1350,7 +1345,7 @@ // ** 512 512 // ** 100 512 // ** 2000 2048 -// ** +// ** // */ // static i64 journalHdrOffset(Pager *pPager){ // i64 offset = 0; @@ -1372,12 +1367,12 @@ // ** // ** If doTruncate is non-zero or the Pager.journalSizeLimit variable is // ** set to 0, then truncate the journal file to zero bytes in size. Otherwise, -// ** zero the 28-byte header at the start of the journal file. In either case, -// ** if the pager is not in no-sync mode, sync the journal file immediately +// ** zero the 28-byte header at the start of the journal file. In either case, +// ** if the pager is not in no-sync mode, sync the journal file immediately // ** after writing or truncating it. // ** // ** If Pager.journalSizeLimit is set to a positive, non-zero value, and -// ** following the truncation or zeroing described above the size of the +// ** following the truncation or zeroing described above the size of the // ** journal file in bytes is larger than this value, then truncate the // ** journal file to Pager.journalSizeLimit bytes. The journal file does // ** not need to be synced following this operation. @@ -1403,8 +1398,8 @@ // rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_DATAONLY|pPager->syncFlags); // } -// /* At this point the transaction is committed but the write lock -// ** is still held on the file. If there is a size limit configured for +// /* At this point the transaction is committed but the write lock +// ** is still held on the file. If there is a size limit configured for // ** the persistent journal and the journal file currently consumes more // ** space than that limit allows for, truncate it now. There is no need // ** to sync the file following this operation. @@ -1432,7 +1427,7 @@ // ** - 4 bytes: Initial database page count. // ** - 4 bytes: Sector size used by the process that wrote this journal. // ** - 4 bytes: Database page size. -// ** +// ** // ** Followed by (JOURNAL_HDR_SZ - 28) bytes of unused space. // */ // static int writeJournalHdr(Pager *pPager){ @@ -1448,8 +1443,8 @@ // nHeader = JOURNAL_HDR_SZ(pPager); // } -// /* If there are active savepoints and any of them were created -// ** since the most recent journal header was written, update the +// /* If there are active savepoints and any of them were created +// ** since the most recent journal header was written, update the // ** PagerSavepoint.iHdrOffset fields now. // */ // for(ii=0; iinSavepoint; ii++){ @@ -1460,10 +1455,10 @@ // pPager->journalHdr = pPager->journalOff = journalHdrOffset(pPager); -// /* +// /* // ** Write the nRec Field - the number of page records that follow this // ** journal header. Normally, zero is written to this value at this time. -// ** After the records are added to the journal (and the journal synced, +// ** After the records are added to the journal (and the journal synced, // ** if in full-sync mode), the zero is overwritten with the true number // ** of records (see syncJournal()). // ** @@ -1482,7 +1477,7 @@ // */ // assert( isOpen(pPager->fd) || pPager->noSync ); // if( pPager->noSync || (pPager->journalMode==PAGER_JOURNALMODE_MEMORY) -// || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND) +// || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND) // ){ // memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic)); // put32bits(&zHeader[sizeof(aJournalMagic)], 0xffffffff); @@ -1490,7 +1485,7 @@ // memset(zHeader, 0, sizeof(aJournalMagic)+4); // } -// /* The random check-hash initializer */ +// /* The random check-hash initializer */ // sqlite3_randomness(sizeof(pPager->cksumInit), &pPager->cksumInit); // put32bits(&zHeader[sizeof(aJournalMagic)+4], pPager->cksumInit); // /* The initial database size */ @@ -1509,23 +1504,23 @@ // memset(&zHeader[sizeof(aJournalMagic)+20], 0, // nHeader-(sizeof(aJournalMagic)+20)); -// /* In theory, it is only necessary to write the 28 bytes that the -// ** journal header consumes to the journal file here. Then increment the -// ** Pager.journalOff variable by JOURNAL_HDR_SZ so that the next +// /* In theory, it is only necessary to write the 28 bytes that the +// ** journal header consumes to the journal file here. Then increment the +// ** Pager.journalOff variable by JOURNAL_HDR_SZ so that the next // ** record is written to the following sector (leaving a gap in the file // ** that will be implicitly filled in by the OS). // ** -// ** However it has been discovered that on some systems this pattern can +// ** However it has been discovered that on some systems this pattern can // ** be significantly slower than contiguously writing data to the file, -// ** even if that means explicitly writing data to the block of +// ** even if that means explicitly writing data to the block of // ** (JOURNAL_HDR_SZ - 28) bytes that will not be used. So that is what -// ** is done. +// ** is done. // ** -// ** The loop is required here in case the sector-size is larger than the +// ** The loop is required here in case the sector-size is larger than the // ** database page size. Since the zHeader buffer is only Pager.pageSize // ** bytes in size, more than one call to sqlite3OsWrite() may be required // ** to populate the entire journal header sector. -// */ +// */ // for(nWrite=0; rc==SQLITE_OK&&nWritejournalHdr, nHeader)) // rc = sqlite3OsWrite(pPager->jfd, zHeader, nHeader, pPager->journalOff); @@ -1623,29 +1618,29 @@ // /* Check that the values read from the page-size and sector-size fields // ** are within range. To be 'in range', both values need to be a power -// ** of two greater than or equal to 512 or 32, and not greater than their +// ** of two greater than or equal to 512 or 32, and not greater than their // ** respective compile time maximum limits. // */ // if( iPageSize<512 || iSectorSize<32 // || iPageSize>SQLITE_MAX_PAGE_SIZE || iSectorSize>MAX_SECTOR_SIZE -// || ((iPageSize-1)&iPageSize)!=0 || ((iSectorSize-1)&iSectorSize)!=0 +// || ((iPageSize-1)&iPageSize)!=0 || ((iSectorSize-1)&iSectorSize)!=0 // ){ -// /* If the either the page-size or sector-size in the journal-header is -// ** invalid, then the process that wrote the journal-header must have -// ** crashed before the header was synced. In this case stop reading +// /* If the either the page-size or sector-size in the journal-header is +// ** invalid, then the process that wrote the journal-header must have +// ** crashed before the header was synced. In this case stop reading // ** the journal file here. // */ // return SQLITE_DONE; // } -// /* Update the page-size to match the value read from the journal. -// ** Use a testcase() macro to make sure that malloc failure within +// /* Update the page-size to match the value read from the journal. +// ** Use a testcase() macro to make sure that malloc failure within // ** PagerSetPagesize() is tested. // */ // rc = sqlite3PagerSetPagesize(pPager, &iPageSize, -1); // testcase( rc!=SQLITE_OK ); -// /* Update the assumed sector-size to match the value used by +// /* Update the assumed sector-size to match the value used by // ** the process that created this journal. If this journal was // ** created by a process other than this one, then this routine // ** is being called from within pager_playback(). The local value @@ -1658,7 +1653,6 @@ // return rc; // } - // /* // ** Write the supplied super-journal name into the journal file for pager // ** pPager at the current location. The super-journal name must be the last @@ -1675,7 +1669,7 @@ // ** The super-journal page checksum is the sum of the bytes in thesuper-journal // ** name, where each byte is interpreted as a signed 8-bit integer. // ** -// ** If zSuper is a NULL pointer (occurs for a single database transaction), +// ** If zSuper is a NULL pointer (occurs for a single database transaction), // ** this call is a no-op. // */ // static int writeSuperJournal(Pager *pPager, const char *zSuper){ @@ -1688,8 +1682,8 @@ // assert( pPager->setSuper==0 ); // assert( !pagerUseWal(pPager) ); -// if( !zSuper -// || pPager->journalMode==PAGER_JOURNALMODE_MEMORY +// if( !zSuper +// || pPager->journalMode==PAGER_JOURNALMODE_MEMORY // || !isOpen(pPager->jfd) // ){ // return SQLITE_OK; @@ -1725,16 +1719,16 @@ // } // pPager->journalOff += (nSuper+20); -// /* If the pager is in peristent-journal mode, then the physical +// /* If the pager is in peristent-journal mode, then the physical // ** journal-file may extend past the end of the super-journal name -// ** and 8 bytes of magic data just written to the file. This is +// ** and 8 bytes of magic data just written to the file. This is // ** dangerous because the code to rollback a hot-journal file -// ** will not be able to find the super-journal name to determine -// ** whether or not the journal is hot. +// ** will not be able to find the super-journal name to determine +// ** whether or not the journal is hot. // ** -// ** Easiest thing to do in this scenario is to truncate the journal +// ** Easiest thing to do in this scenario is to truncate the journal // ** file to the required size. -// */ +// */ // if( SQLITE_OK==(rc = sqlite3OsFileSize(pPager->jfd, &jrnlSize)) // && jrnlSize>pPager->journalOff // ){ @@ -1779,7 +1773,7 @@ // } // /* -// ** Set the bit number pgno in the PagerSavepoint.pInSavepoint +// ** Set the bit number pgno in the PagerSavepoint.pInSavepoint // ** bitvecs of all open savepoints. Return SQLITE_OK if successful // ** or SQLITE_NOMEM if a malloc failure occurs. // */ @@ -1808,8 +1802,8 @@ // ** not exhibit the UNDELETABLE_WHEN_OPEN property, the journal file is // ** closed (if it is open). // ** -// ** If the pager is in ERROR state when this function is called, the -// ** contents of the pager cache are discarded before switching back to +// ** If the pager is in ERROR state when this function is called, the +// ** contents of the pager cache are discarded before switching back to // ** the OPEN state. Regardless of whether the pager is in exclusive-mode // ** or not, any journal file left in the file-system will be treated // ** as a hot-journal and rolled back the next time a read-transaction @@ -1817,9 +1811,9 @@ // */ // static void pager_unlock(Pager *pPager){ -// assert( pPager->eState==PAGER_READER -// || pPager->eState==PAGER_OPEN -// || pPager->eState==PAGER_ERROR +// assert( pPager->eState==PAGER_READER +// || pPager->eState==PAGER_OPEN +// || pPager->eState==PAGER_ERROR // ); // sqlite3BitvecDestroy(pPager->pInJournal); @@ -1896,17 +1890,17 @@ // /* // ** This function is called whenever an IOERR or FULL error that requires // ** the pager to transition into the ERROR state may ahve occurred. -// ** The first argument is a pointer to the pager structure, the second -// ** the error-code about to be returned by a pager API function. The -// ** value returned is a copy of the second argument to this function. +// ** The first argument is a pointer to the pager structure, the second +// ** the error-code about to be returned by a pager API function. The +// ** value returned is a copy of the second argument to this function. // ** // ** If the second argument is SQLITE_FULL, SQLITE_IOERR or one of the // ** IOERR sub-codes, the pager enters the ERROR state and the error code // ** is stored in Pager.errCode. While the pager remains in the ERROR state, // ** all major API calls on the Pager will immediately return Pager.errCode. // ** -// ** The ERROR state indicates that the contents of the pager-cache -// ** cannot be trusted. This state can be cleared by completely discarding +// ** The ERROR state indicates that the contents of the pager-cache +// ** cannot be trusted. This state can be cleared by completely discarding // ** the contents of the pager-cache. If a transaction was active when // ** the persistent error occurred, then the rollback journal may need // ** to be replayed to restore the contents of the database file (as if @@ -1954,27 +1948,27 @@ // } // /* -// ** This routine ends a transaction. A transaction is usually ended by -// ** either a COMMIT or a ROLLBACK operation. This routine may be called +// ** This routine ends a transaction. A transaction is usually ended by +// ** either a COMMIT or a ROLLBACK operation. This routine may be called // ** after rollback of a hot-journal, or if an error occurs while opening // ** the journal file or writing the very first journal-header of a // ** database transaction. -// ** +// ** // ** This routine is never called in PAGER_ERROR state. If it is called // ** in PAGER_NONE or PAGER_SHARED state and the lock held is less // ** exclusive than a RESERVED lock, it is a no-op. // ** // ** Otherwise, any active savepoints are released. // ** -// ** If the journal file is open, then it is "finalized". Once a journal -// ** file has been finalized it is not possible to use it to roll back a +// ** If the journal file is open, then it is "finalized". Once a journal +// ** file has been finalized it is not possible to use it to roll back a // ** transaction. Nor will it be considered to be a hot-journal by this // ** or any other database connection. Exactly how a journal is finalized // ** depends on whether or not the pager is running in exclusive mode and // ** the current journal-mode (Pager.journalMode value), as follows: // ** // ** journalMode==MEMORY -// ** Journal file descriptor is simply closed. This destroys an +// ** Journal file descriptor is simply closed. This destroys an // ** in-memory journal. // ** // ** journalMode==TRUNCATE @@ -1994,12 +1988,12 @@ // ** journalMode==PERSIST is used instead. // ** // ** After the journal is finalized, the pager moves to PAGER_READER state. -// ** If running in non-exclusive rollback mode, the lock on the file is +// ** If running in non-exclusive rollback mode, the lock on the file is // ** downgraded to a SHARED_LOCK. // ** // ** SQLITE_OK is returned if no error occurs. If an error occurs during // ** any of the IO operations to finalize the journal file or unlock the -// ** database then the IO error code is returned to the user. If the +// ** database then the IO error code is returned to the user. If the // ** operation to finalize the journal file fails, then the code still // ** tries to unlock the database file if not in exclusive mode. If the // ** unlock operation fails as well, then the first error code related @@ -2018,9 +2012,9 @@ // ** 1. After a successful hot-journal rollback, it is called with // ** eState==PAGER_NONE and eLock==EXCLUSIVE_LOCK. // ** -// ** 2. If a connection with locking_mode=exclusive holding an EXCLUSIVE +// ** 2. If a connection with locking_mode=exclusive holding an EXCLUSIVE // ** lock switches back to locking_mode=normal and then executes a -// ** read-transaction, this function is called with eState==PAGER_READER +// ** read-transaction, this function is called with eState==PAGER_READER // ** and eLock==EXCLUSIVE_LOCK when the read-transaction is closed. // */ // assert( assert_pager_state(pPager) ); @@ -2030,7 +2024,7 @@ // } // releaseAllSavepoints(pPager); -// assert( isOpen(pPager->jfd) || pPager->pInJournal==0 +// assert( isOpen(pPager->jfd) || pPager->pInJournal==0 // || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_BATCH_ATOMIC) // ); // if( isOpen(pPager->jfd) ){ @@ -2068,9 +2062,9 @@ // */ // int bDelete = !pPager->tempFile; // assert( sqlite3JournalIsInMemory(pPager->jfd)==0 ); -// assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE -// || pPager->journalMode==PAGER_JOURNALMODE_MEMORY -// || pPager->journalMode==PAGER_JOURNALMODE_WAL +// assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE +// || pPager->journalMode==PAGER_JOURNALMODE_MEMORY +// || pPager->journalMode==PAGER_JOURNALMODE_WAL // ); // sqlite3OsClose(pPager->jfd); // if( bDelete ){ @@ -2103,8 +2097,8 @@ // } // if( pagerUseWal(pPager) ){ -// /* Drop the WAL write-lock, if any. Also, if the connection was in -// ** locking_mode=exclusive mode but is no longer, drop the EXCLUSIVE +// /* Drop the WAL write-lock, if any. Also, if the connection was in +// ** locking_mode=exclusive mode but is no longer, drop the EXCLUSIVE // ** lock held on the database file. // */ // rc2 = sqlite3WalEndWriteTransaction(pPager->pWal); @@ -2112,7 +2106,7 @@ // }else if( rc==SQLITE_OK && bCommit && pPager->dbFileSize>pPager->dbSize ){ // /* This branch is taken when committing a transaction in rollback-journal // ** mode if the database file on disk is larger than the database image. -// ** At this point the journal has been finalized and the transaction +// ** At this point the journal has been finalized and the transaction // ** successfully committed, but the EXCLUSIVE lock is still held on the // ** file. So it is safe to truncate the database file to its minimum // ** required size. */ @@ -2125,7 +2119,7 @@ // if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; // } -// if( !pPager->exclusiveMode +// if( !pPager->exclusiveMode // && (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0)) // ){ // rc2 = pagerUnlockDb(pPager, SHARED_LOCK); @@ -2137,19 +2131,19 @@ // } // /* -// ** Execute a rollback if a transaction is active and unlock the -// ** database file. +// ** Execute a rollback if a transaction is active and unlock the +// ** database file. // ** -// ** If the pager has already entered the ERROR state, do not attempt +// ** If the pager has already entered the ERROR state, do not attempt // ** the rollback at this time. Instead, pager_unlock() is called. The // ** call to pager_unlock() will discard all in-memory pages, unlock -// ** the database file and move the pager back to OPEN state. If this -// ** means that there is a hot-journal left in the file-system, the next -// ** connection to obtain a shared lock on the pager (which may be this one) +// ** the database file and move the pager back to OPEN state. If this +// ** means that there is a hot-journal left in the file-system, the next +// ** connection to obtain a shared lock on the pager (which may be this one) // ** will roll it back. // ** // ** If the pager has not already entered the ERROR state, but an IO or -// ** malloc error occurs during a rollback, then this will itself cause +// ** malloc error occurs during a rollback, then this will itself cause // ** the pager to enter the ERROR state. Which will be cleared by the // ** call to pager_unlock(), as described above. // */ @@ -2170,10 +2164,10 @@ // /* // ** Parameter aData must point to a buffer of pPager->pageSize bytes -// ** of data. Compute and return a checksum based ont the contents of the +// ** of data. Compute and return a checksum based ont the contents of the // ** page of data and the current value of pPager->cksumInit. // ** -// ** This is not a real checksum. It is really just the sum of the +// ** This is not a real checksum. It is really just the sum of the // ** random initial value (pPager->cksumInit) and every 200th byte // ** of the page data, starting with byte offset (pPager->pageSize%200). // ** Each byte is interpreted as an 8-bit unsigned integer. @@ -2181,8 +2175,8 @@ // ** Changing the formula used to compute this checksum results in an // ** incompatible journal file format. // ** -// ** If journal corruption occurs due to a power failure, the most likely -// ** scenario is that one end or the other of the record will be changed. +// ** If journal corruption occurs due to a power failure, the most likely +// ** scenario is that one end or the other of the record will be changed. // ** It is much less likely that the two ends of the journal record will be // ** correct and the middle be corrupt. Thus, this "checksum" scheme, // ** though fast and simple, catches the mostly likely kind of corruption. @@ -2203,7 +2197,7 @@ // ** The page begins at offset *pOffset into the file. The *pOffset // ** value is increased to the start of the next page in the journal. // ** -// ** The main rollback journal uses checksums - the statement journal does +// ** The main rollback journal uses checksums - the statement journal does // ** not. // ** // ** If the page number of the page record read from the (sub-)journal file @@ -2223,7 +2217,7 @@ // ** is successfully read from the (sub-)journal file but appears to be // ** corrupted, SQLITE_DONE is returned. Data is considered corrupted in // ** two circumstances: -// ** +// ** // ** * If the record page-number is illegal (0 or PAGER_MJ_PGNO), or // ** * If the record is being rolled back from the main journal file // ** and the checksum field does not match the record content. @@ -2258,7 +2252,7 @@ // assert( aData ); /* Temp storage must have already been allocated */ // assert( pagerUseWal(pPager)==0 || (!isMainJrnl && isSavepnt) ); -// /* Either the state is greater than PAGER_WRITER_CACHEMOD (a transaction +// /* Either the state is greater than PAGER_WRITER_CACHEMOD (a transaction // ** or savepoint rollback done at the request of the caller) or this is // ** a hot-journal rollback. If it is a hot-journal rollback, the pager // ** is in state OPEN and holds an EXCLUSIVE lock. Hot-journal rollback @@ -2324,7 +2318,7 @@ // ** assert()able. // ** // ** If in WRITER_DBMOD, WRITER_FINISHED or OPEN state, then we update the -// ** pager cache if it exists and the main file. The page is then marked +// ** pager cache if it exists and the main file. The page is then marked // ** not dirty. Since this code is only executed in PAGER_OPEN state for // ** a hot-journal rollback, it is guaranteed that the page-cache is empty // ** if the pager is in OPEN state. @@ -2388,18 +2382,18 @@ // }else if( !isMainJrnl && pPg==0 ){ // /* If this is a rollback of a savepoint and data was not written to // ** the database and the page is not in-memory, there is a potential -// ** problem. When the page is next fetched by the b-tree layer, it -// ** will be read from the database file, which may or may not be -// ** current. +// ** problem. When the page is next fetched by the b-tree layer, it +// ** will be read from the database file, which may or may not be +// ** current. // ** // ** There are a couple of different ways this can happen. All are quite -// ** obscure. When running in synchronous mode, this can only happen +// ** obscure. When running in synchronous mode, this can only happen // ** if the page is on the free-list at the start of the transaction, then // ** populated, then moved using sqlite3PagerMovepage(). // ** // ** The solution is to add an in-memory page to the cache containing -// ** the data just read from the sub-journal. Mark the page as dirty -// ** and if the pager requires a journal-sync, then mark the page as +// ** the data just read from the sub-journal. Mark the page as dirty +// ** and if the pager requires a journal-sync, then mark the page as // ** requiring a journal-sync before it is written. // */ // assert( isSavepnt ); @@ -2444,26 +2438,26 @@ // ** This routine checks if it is possible to delete the super-journal file, // ** and does so if it is. // ** -// ** Argument zSuper may point to Pager.pTmpSpace. So that buffer is not +// ** Argument zSuper may point to Pager.pTmpSpace. So that buffer is not // ** available for use within this function. // ** -// ** When a super-journal file is created, it is populated with the names -// ** of all of its child journals, one after another, formatted as utf-8 -// ** encoded text. The end of each child journal file is marked with a +// ** When a super-journal file is created, it is populated with the names +// ** of all of its child journals, one after another, formatted as utf-8 +// ** encoded text. The end of each child journal file is marked with a // ** nul-terminator byte (0x00). i.e. the entire contents of a super-journal // ** file for a transaction involving two databases might be: // ** // ** "/home/bill/a.db-journal\x00/home/bill/b.db-journal\x00" // ** -// ** A super-journal file may only be deleted once all of its child +// ** A super-journal file may only be deleted once all of its child // ** journals have been rolled back. // ** -// ** This function reads the contents of the super-journal file into +// ** This function reads the contents of the super-journal file into // ** memory and loops through each of the child journal names. For // ** each child journal, it checks if: // ** // ** * if the child journal exists, and if so -// ** * if the child journal contains a reference to super-journal +// ** * if the child journal contains a reference to super-journal // ** file zSuper // ** // ** If a child journal can be found that matches both of the criteria @@ -2473,12 +2467,12 @@ // ** // ** If an IO error within this function, an error code is returned. This // ** function allocates memory by calling sqlite3Malloc(). If an allocation -// ** fails, SQLITE_NOMEM is returned. Otherwise, if no IO or malloc errors +// ** fails, SQLITE_NOMEM is returned. Otherwise, if no IO or malloc errors // ** occur, SQLITE_OK is returned. // ** // ** TODO: This function allocates a single block of memory to load // ** the entire contents of the super-journal file. This could be -// ** a couple of kilobytes or so - potentially larger than the page +// ** a couple of kilobytes or so - potentially larger than the page // ** size. // */ // static int pager_delsuper(Pager *pPager, const char *zSuper){ @@ -2539,7 +2533,7 @@ // /* One of the journals pointed to by the super-journal exists. // ** Open it and check if it points at the super-journal. If // ** so, return without deleting the super-journal file. -// ** NB: zJournal is really a MAIN_JOURNAL. But call it a +// ** NB: zJournal is really a MAIN_JOURNAL. But call it a // ** SUPER_JOURNAL here so that the VFS will not send the zJournal // ** name into sqlite3_database_file_object(). // */ @@ -2564,7 +2558,7 @@ // } // zJournal += (sqlite3Strlen30(zJournal)+1); // } - + // sqlite3OsClose(pSuper); // rc = sqlite3OsDelete(pVfs, zSuper, 0); @@ -2578,22 +2572,21 @@ // return rc; // } - // /* -// ** This function is used to change the actual size of the database +// ** This function is used to change the actual size of the database // ** file in the file-system. This only happens when committing a transaction, // ** or rolling back a transaction (including rolling back a hot-journal). // ** // ** If the main database file is not open, or the pager is not in either -// ** DBMOD or OPEN state, this function is a no-op. Otherwise, the size -// ** of the file is changed to nPage pages (nPage*pPager->pageSize bytes). +// ** DBMOD or OPEN state, this function is a no-op. Otherwise, the size +// ** of the file is changed to nPage pages (nPage*pPager->pageSize bytes). // ** If the file on disk is currently larger than nPage pages, then use the VFS // ** xTruncate() method to truncate it. // ** -// ** Or, it might be the case that the file on disk is smaller than -// ** nPage pages. Some operating system implementations can get confused if -// ** you try to truncate a file to some size that is larger than it -// ** currently is, so detect this case and write a single zero byte to +// ** Or, it might be the case that the file on disk is smaller than +// ** nPage pages. Some operating system implementations can get confused if +// ** you try to truncate a file to some size that is larger than it +// ** currently is, so detect this case and write a single zero byte to // ** the end of the new file instead. // ** // ** If successful, return SQLITE_OK. If an IO error occurs while modifying @@ -2603,9 +2596,9 @@ // int rc = SQLITE_OK; // assert( pPager->eState!=PAGER_ERROR ); // assert( pPager->eState!=PAGER_READER ); - -// if( isOpen(pPager->fd) -// && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) + +// if( isOpen(pPager->fd) +// && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) // ){ // i64 currentSize, newSize; // int szPage = pPager->pageSize; @@ -2649,8 +2642,8 @@ // /* // ** Set the value of the Pager.sectorSize variable for the given // ** pager based on the value returned by the xSectorSize method -// ** of the open database file. The sector size will be used -// ** to determine the size and alignment of journal header and +// ** of the open database file. The sector size will be used +// ** to determine the size and alignment of journal header and // ** super-journal pointers within created journal files. // ** // ** For temporary files the effective sector size is always 512 bytes. @@ -2673,7 +2666,7 @@ // assert( isOpen(pPager->fd) || pPager->tempFile ); // if( pPager->tempFile -// || (sqlite3OsDeviceCharacteristics(pPager->fd) & +// || (sqlite3OsDeviceCharacteristics(pPager->fd) & // SQLITE_IOCAP_POWERSAFE_OVERWRITE)!=0 // ){ // /* Sector size doesn't matter for temporary files. Also, the file @@ -2687,15 +2680,15 @@ // /* // ** Playback the journal and thus restore the database file to -// ** the state it was in before we started making changes. +// ** the state it was in before we started making changes. // ** -// ** The journal file format is as follows: +// ** The journal file format is as follows: // ** // ** (1) 8 byte prefix. A copy of aJournalMagic[]. // ** (2) 4 byte big-endian integer which is the number of valid page records // ** in the journal. If this value is 0xffffffff, then compute the // ** number of page records from the journal size. -// ** (3) 4 byte big-endian integer which is the initial value for the +// ** (3) 4 byte big-endian integer which is the initial value for the // ** sanity checksum. // ** (4) 4 byte integer which is the number of pages to truncate the // ** database to during a rollback. @@ -2724,7 +2717,7 @@ // ** from the file size. This value is used when the user selects the // ** no-sync option for the journal. A power failure could lead to corruption // ** in this case. But for things like temporary table (which will be -// ** deleted when the power is restored) we don't care. +// ** deleted when the power is restored) we don't care. // ** // ** If the file opened as the journal file is not a well-formed // ** journal file then all pages up to the first corrupted page are rolled @@ -2736,7 +2729,7 @@ // ** and an error code is returned. // ** // ** The isHot parameter indicates that we are trying to rollback a journal -// ** that might be a hot journal. Or, it could be that the journal is +// ** that might be a hot journal. Or, it could be that the journal is // ** preserved because of JOURNALMODE_PERSIST or JOURNALMODE_TRUNCATE. // ** If the journal really is hot, reset the pager cache prior rolling // ** back any content. If the journal is merely persistent, no reset is @@ -2787,9 +2780,9 @@ // pPager->journalOff = 0; // needPagerReset = isHot; -// /* This loop terminates either when a readJournalHdr() or -// ** pager_playback_one_page() call returns SQLITE_DONE or an IO error -// ** occurs. +// /* This loop terminates either when a readJournalHdr() or +// ** pager_playback_one_page() call returns SQLITE_DONE or an IO error +// ** occurs. // */ // while( 1 ){ // /* Read the next journal header from the journal file. If there are @@ -2798,7 +2791,7 @@ // ** This indicates nothing more needs to be rolled back. // */ // rc = readJournalHdr(pPager, isHot, szJ, &nRec, &mxPg); -// if( rc!=SQLITE_OK ){ +// if( rc!=SQLITE_OK ){ // if( rc==SQLITE_DONE ){ // rc = SQLITE_OK; // } @@ -2826,7 +2819,7 @@ // ** chunk of the journal contains zero pages to be rolled back. But // ** when doing a ROLLBACK and the nRec==0 chunk is the last chunk in // ** the journal, it means that the journal might contain additional -// ** pages that need to be rolled back and that the number of pages +// ** pages that need to be rolled back and that the number of pages // ** should be computed based on the journal file size. // */ // if( nRec==0 && !isHot && @@ -2845,7 +2838,7 @@ // pPager->dbSize = mxPg; // } -// /* Copy original pages out of the journal and back into the +// /* Copy original pages out of the journal and back into the // ** database file and/or page cache. // */ // for(u=0; ufd,SQLITE_FCNTL_DB_UNCHANGED,0); // #endif -// /* If this playback is happening automatically as a result of an IO or -// ** malloc error that occurred after the change-counter was updated but -// ** before the transaction was committed, then the change-counter -// ** modification may just have been reverted. If this happens in exclusive +// /* If this playback is happening automatically as a result of an IO or +// ** malloc error that occurred after the change-counter was updated but +// ** before the transaction was committed, then the change-counter +// ** modification may just have been reverted. If this happens in exclusive // ** mode, then subsequent transactions performed by the connection will not // ** update the change-counter at all. This may lead to cache inconsistency // ** problems for other processes at some point in the future. So, just @@ -2946,10 +2939,9 @@ // return rc; // } - // /* // ** Read the content for page pPg out of the database file (or out of -// ** the WAL if that is where the most recent copy if found) into +// ** the WAL if that is where the most recent copy if found) into // ** pPg->pData. A shared lock or greater must be held on the database // ** file before this function is called. // ** @@ -3039,15 +3031,15 @@ // #ifndef SQLITE_OMIT_WAL // /* -// ** This function is invoked once for each page that has already been +// ** This function is invoked once for each page that has already been // ** written into the log file when a WAL transaction is rolled back. -// ** Parameter iPg is the page number of said page. The pCtx argument +// ** Parameter iPg is the page number of said page. The pCtx argument // ** is actually a pointer to the Pager structure. // ** // ** If page iPg is present in the cache, and has no outstanding references, // ** it is discarded. Otherwise, if there are one or more outstanding // ** references, the page content is reloaded from the database. If the -// ** attempt to reload content from the database is required and fails, +// ** attempt to reload content from the database is required and fails, // ** return an SQLite error code. Otherwise, SQLITE_OK. // */ // static int pagerUndoCallback(void *pCtx, Pgno iPg){ @@ -3073,7 +3065,7 @@ // ** updated as data is copied out of the rollback journal and into the // ** database. This is not generally possible with a WAL database, as // ** rollback involves simply truncating the log file. Therefore, if one -// ** or more frames have already been written to the log (and therefore +// ** or more frames have already been written to the log (and therefore // ** also copied into the backup databases) as part of this transaction, // ** the backups must be restarted. // */ @@ -3090,7 +3082,7 @@ // PgHdr *pList; /* List of dirty pages to revert */ // /* For all pages in the cache that are currently dirty or have already -// ** been written (but not committed) to the log file, do one of the +// ** been written (but not committed) to the log file, do one of the // ** following: // ** // ** + Discard the cached page (if refcount==0), or @@ -3112,11 +3104,11 @@ // ** This function is a wrapper around sqlite3WalFrames(). As well as logging // ** the contents of the list of pages headed by pList (connected by pDirty), // ** this function notifies any active backup processes that the pages have -// ** changed. +// ** changed. // ** // ** The list of pages passed into this routine is always sorted by page number. // ** Hence, if page 1 appears anywhere on the list, it will be the first page. -// */ +// */ // static int pagerWalFrames( // Pager *pPager, /* Pager object */ // PgHdr *pList, /* List of frames to log */ @@ -3157,7 +3149,7 @@ // pPager->aStat[PAGER_STAT_WRITE] += nList; // if( pList->pgno==1 ) pager_write_changecounter(pList); -// rc = sqlite3WalFrames(pPager->pWal, +// rc = sqlite3WalFrames(pPager->pWal, // pPager->pageSize, pList, nTruncate, isCommit, pPager->walSyncFlags // ); // if( rc==SQLITE_OK && pPager->pBackup ){ @@ -3272,9 +3264,9 @@ // ** Return SQLITE_OK or an error code. // ** // ** The caller must hold a SHARED lock on the database file to call this -// ** function. Because an EXCLUSIVE lock on the db file is required to delete -// ** a WAL on a none-empty database, this ensures there is no race condition -// ** between the xAccess() below and an xDelete() being executed by some +// ** function. Because an EXCLUSIVE lock on the db file is required to delete +// ** a WAL on a none-empty database, this ensures there is no race condition +// ** between the xAccess() below and an xDelete() being executed by some // ** other connection. // */ // static int pagerOpenWalIfPresent(Pager *pPager){ @@ -3310,21 +3302,21 @@ // /* // ** Playback savepoint pSavepoint. Or, if pSavepoint==NULL, then playback -// ** the entire super-journal file. The case pSavepoint==NULL occurs when -// ** a ROLLBACK TO command is invoked on a SAVEPOINT that is a transaction +// ** the entire super-journal file. The case pSavepoint==NULL occurs when +// ** a ROLLBACK TO command is invoked on a SAVEPOINT that is a transaction // ** savepoint. // ** -// ** When pSavepoint is not NULL (meaning a non-transaction savepoint is +// ** When pSavepoint is not NULL (meaning a non-transaction savepoint is // ** being rolled back), then the rollback consists of up to three stages, // ** performed in the order specified: // ** // ** * Pages are played back from the main journal starting at byte -// ** offset PagerSavepoint.iOffset and continuing to +// ** offset PagerSavepoint.iOffset and continuing to // ** PagerSavepoint.iHdrOffset, or to the end of the main journal // ** file if PagerSavepoint.iHdrOffset is zero. // ** // ** * If PagerSavepoint.iHdrOffset is not zero, then pages are played -// ** back starting from the journal header immediately following +// ** back starting from the journal header immediately following // ** PagerSavepoint.iHdrOffset to the end of the main journal file. // ** // ** * Pages are then played back from the sub-journal file, starting @@ -3340,7 +3332,7 @@ // ** journal file. There is no need for a bitvec in this case. // ** // ** In either case, before playback commences the Pager.dbSize variable -// ** is reset to the value that it held at the start of the savepoint +// ** is reset to the value that it held at the start of the savepoint // ** (or transaction). No page with a page-number greater than this value // ** is played back. If one is encountered it is simply skipped. // */ @@ -3361,7 +3353,7 @@ // } // } -// /* Set the database size back to the value it was before the savepoint +// /* Set the database size back to the value it was before the savepoint // ** being reverted was opened. // */ // pPager->dbSize = pSavepoint ? pSavepoint->nOrig : pPager->dbOrigSize; @@ -3414,7 +3406,7 @@ // ** test is related to ticket #2565. See the discussion in the // ** pager_playback() function for additional information. // */ -// if( nJRec==0 +// if( nJRec==0 // && pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff // ){ // nJRec = (u32)((szJ - pPager->journalOff)/JOURNAL_PG_SZ(pPager)); @@ -3590,7 +3582,7 @@ // /* // ** The following global variable is incremented whenever the library // ** attempts to open a temporary file. This information is used for -// ** testing and analysis only. +// ** testing and analysis only. // */ // #ifdef SQLITE_TEST // int sqlite3_opentemp_count = 0; @@ -3599,8 +3591,8 @@ // /* // ** Open a temporary file. // ** -// ** Write the file descriptor into *pFile. Return SQLITE_OK on success -// ** or some other error code if we fail. The OS will automatically +// ** Write the file descriptor into *pFile. Return SQLITE_OK on success +// ** or some other error code if we fail. The OS will automatically // ** delete the temporary file when it is closed. // ** // ** The flags passed to the VFS layer xOpen() call are those specified @@ -3632,9 +3624,9 @@ // /* // ** Set the busy handler function. // ** -// ** The pager invokes the busy-handler if sqlite3OsLock() returns +// ** The pager invokes the busy-handler if sqlite3OsLock() returns // ** SQLITE_BUSY when trying to upgrade from no-lock to a SHARED lock, -// ** or when trying to upgrade from a RESERVED lock to an EXCLUSIVE +// ** or when trying to upgrade from a RESERVED lock to an EXCLUSIVE // ** lock. It does *not* invoke the busy handler when upgrading from // ** SHARED to RESERVED, or when upgrading from SHARED to EXCLUSIVE // ** (which occurs during hot-journal rollback). Summary: @@ -3646,7 +3638,7 @@ // ** SHARED_LOCK -> EXCLUSIVE_LOCK | No // ** RESERVED_LOCK -> EXCLUSIVE_LOCK | Yes // ** -// ** If the busy-handler callback returns non-zero, the lock is +// ** If the busy-handler callback returns non-zero, the lock is // ** retried. If it returns zero, then the SQLITE_BUSY error is // ** returned to the caller of the pager API function. // */ @@ -3665,16 +3657,16 @@ // } // /* -// ** Change the page size used by the Pager object. The new page size +// ** Change the page size used by the Pager object. The new page size // ** is passed in *pPageSize. // ** // ** If the pager is in the error state when this function is called, it -// ** is a no-op. The value returned is the error state error code (i.e. +// ** is a no-op. The value returned is the error state error code (i.e. // ** one of SQLITE_IOERR, an SQLITE_IOERR_xxx sub-code or SQLITE_FULL). // ** // ** Otherwise, if all of the following are true: // ** -// ** * the new page size (value of *pPageSize) is valid (a power +// ** * the new page size (value of *pPageSize) is valid (a power // ** of two between 512 and SQLITE_MAX_PAGE_SIZE, inclusive), and // ** // ** * there are no outstanding page references, and @@ -3684,14 +3676,14 @@ // ** // ** then the pager object page size is set to *pPageSize. // ** -// ** If the page size is changed, then this function uses sqlite3PagerMalloc() -// ** to obtain a new Pager.pTmpSpace buffer. If this allocation attempt -// ** fails, SQLITE_NOMEM is returned and the page size remains unchanged. +// ** If the page size is changed, then this function uses sqlite3PagerMalloc() +// ** to obtain a new Pager.pTmpSpace buffer. If this allocation attempt +// ** fails, SQLITE_NOMEM is returned and the page size remains unchanged. // ** In all other cases, SQLITE_OK is returned. // ** // ** If the page size is not changed, either because one of the enumerated // ** conditions above is not true, the pager was in error state when this -// ** function was called, or because the memory allocation attempt failed, +// ** function was called, or because the memory allocation attempt failed, // ** then *pPageSize is set to the old, retained page size before returning. // */ // int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nReserve){ @@ -3701,7 +3693,7 @@ // ** function may be called from within PagerOpen(), before the state // ** of the Pager object is internally consistent. // ** -// ** At one point this function returned an error if the pager was in +// ** At one point this function returned an error if the pager was in // ** PAGER_ERROR state. But since PAGER_ERROR state guarantees that // ** there is at least one outstanding page reference, this function // ** is a no-op for that case anyhow. @@ -3710,8 +3702,8 @@ // u32 pageSize = *pPageSize; // assert( pageSize==0 || (pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE) ); // if( (pPager->memDb==0 || pPager->dbSize==0) -// && sqlite3PcacheRefCount(pPager->pPCache)==0 -// && pageSize && pageSize!=(u32)pPager->pageSize +// && sqlite3PcacheRefCount(pPager->pPCache)==0 +// && pageSize && pageSize!=(u32)pPager->pageSize // ){ // char *pNew = NULL; /* New temp space */ // i64 nByte = 0; @@ -3767,7 +3759,7 @@ // } // /* -// ** Attempt to set the maximum database page count if mxPage is positive. +// ** Attempt to set the maximum database page count if mxPage is positive. // ** Make no changes if mxPage is zero or negative. And never reduce the // ** maximum page count below the current size of the database. // ** @@ -3811,11 +3803,11 @@ // /* // ** Read the first N bytes from the beginning of the file into memory -// ** that pDest points to. +// ** that pDest points to. // ** // ** If the pager was opened on a transient file (zFilename==""), or // ** opened on a file less than N bytes in size, the output buffer is -// ** zeroed and SQLITE_OK returned. The rationale for this is that this +// ** zeroed and SQLITE_OK returned. The rationale for this is that this // ** function is used to read database headers, and a new transient or // ** zero sized database has a header than consists entirely of zeroes. // ** @@ -3848,7 +3840,7 @@ // ** This function may only be called when a read-transaction is open on // ** the pager. It returns the total number of pages in the database. // ** -// ** However, if the file is between 1 and bytes in size, then +// ** However, if the file is between 1 and bytes in size, then // ** this is considered a 1 page file. // */ // void sqlite3PagerPagecount(Pager *pPager, int *pnPage){ @@ -3857,25 +3849,24 @@ // *pnPage = (int)pPager->dbSize; // } - // /* // ** Try to obtain a lock of type locktype on the database file. If // ** a similar or greater lock is already held, this function is a no-op // ** (returning SQLITE_OK immediately). // ** -// ** Otherwise, attempt to obtain the lock using sqlite3OsLock(). Invoke -// ** the busy callback if the lock is currently not available. Repeat -// ** until the busy callback returns false or until the attempt to +// ** Otherwise, attempt to obtain the lock using sqlite3OsLock(). Invoke +// ** the busy callback if the lock is currently not available. Repeat +// ** until the busy callback returns false or until the attempt to // ** obtain the lock succeeds. // ** // ** Return SQLITE_OK on success and an error code if we cannot obtain -// ** the lock. If the lock is obtained successfully, set the Pager.state +// ** the lock. If the lock is obtained successfully, set the Pager.state // ** variable to locktype before returning. // */ // static int pager_wait_on_lock(Pager *pPager, int locktype){ // int rc; /* Return code */ -// /* Check that this is either a no-op (because the requested lock is +// /* Check that this is either a no-op (because the requested lock is // ** already held), or one of the transitions that the busy-handler // ** may be invoked during, according to the comment above // ** sqlite3PagerSetBusyhandler(). @@ -3892,10 +3883,10 @@ // } // /* -// ** Function assertTruncateConstraint(pPager) checks that one of the +// ** Function assertTruncateConstraint(pPager) checks that one of the // ** following is true for all dirty pages currently in the page-cache: // ** -// ** a) The page number is less than or equal to the size of the +// ** a) The page number is less than or equal to the size of the // ** current database image, in pages, OR // ** // ** b) if the page content were written at this time, it would not @@ -3908,9 +3899,9 @@ // ** the database file. If a savepoint transaction were rolled back after // ** this happened, the correct behavior would be to restore the current // ** content of the page. However, since this content is not present in either -// ** the database file or the portion of the rollback journal and +// ** the database file or the portion of the rollback journal and // ** sub-journal rolled back the content could not be restored and the -// ** database image would become corrupt. It is therefore fortunate that +// ** database image would become corrupt. It is therefore fortunate that // ** this circumstance cannot arise. // */ // #if defined(SQLITE_DEBUG) @@ -3926,9 +3917,9 @@ // #endif // /* -// ** Truncate the in-memory database file image to nPage pages. This -// ** function does not actually modify the database file on disk. It -// ** just sets the internal state of the pager object so that the +// ** Truncate the in-memory database file image to nPage pages. This +// ** function does not actually modify the database file on disk. It +// ** just sets the internal state of the pager object so that the // ** truncation will be done when the current transaction is committed. // ** // ** This function is only called right before committing a transaction. @@ -3944,28 +3935,27 @@ // /* At one point the code here called assertTruncateConstraint() to // ** ensure that all pages being truncated away by this operation are, -// ** if one or more savepoints are open, present in the savepoint +// ** if one or more savepoints are open, present in the savepoint // ** journal so that they can be restored if the savepoint is rolled // ** back. This is no longer necessary as this function is now only -// ** called right before committing a transaction. So although the -// ** Pager object may still have open savepoints (Pager.nSavepoint!=0), +// ** called right before committing a transaction. So although the +// ** Pager object may still have open savepoints (Pager.nSavepoint!=0), // ** they cannot be rolled back. So the assertTruncateConstraint() call // ** is no longer correct. */ // } - // /* // ** This function is called before attempting a hot-journal rollback. It // ** syncs the journal file to disk, then sets pPager->journalHdr to the // ** size of the journal file so that the pager_playback() routine knows // ** that the entire journal file has been synced. // ** -// ** Syncing a hot-journal to disk before attempting to roll it back ensures +// ** Syncing a hot-journal to disk before attempting to roll it back ensures // ** that if a power-failure occurs during the rollback, the process that // ** attempts rollback following system recovery sees the same journal // ** content as this process. // ** -// ** If everything goes as planned, SQLITE_OK is returned. Otherwise, +// ** If everything goes as planned, SQLITE_OK is returned. Otherwise, // ** an SQLite error code. // */ // static int pagerSyncHotJournal(Pager *pPager){ @@ -3981,7 +3971,7 @@ // #if SQLITE_MAX_MMAP_SIZE>0 // /* -// ** Obtain a reference to a memory mapped page object for page number pgno. +// ** Obtain a reference to a memory mapped page object for page number pgno. // ** The new object will use the pointer pData, obtained from xFetch(). // ** If successful, set *ppPage to point to the new page reference // ** and return SQLITE_OK. Otherwise, return an SQLite error code and set @@ -3997,7 +3987,7 @@ // PgHdr **ppPage /* OUT: Acquired page object */ // ){ // PgHdr *p; /* Memory mapped page to return */ - + // if( pPager->pMmapFreelist ){ // *ppPage = p = pPager->pMmapFreelist; // pPager->pMmapFreelist = p->pDirty; @@ -4031,7 +4021,7 @@ // #endif // /* -// ** Release a reference to page pPg. pPg must have been returned by an +// ** Release a reference to page pPg. pPg must have been returned by an // ** earlier call to pagerAcquireMapPage(). // */ // static void pagerReleaseMapPage(PgHdr *pPg){ @@ -4080,77 +4070,76 @@ // return rc; // } +/* +** Shutdown the page cache. Free all memory and close all files. +** +** If a transaction was in progress when this routine is called, that +** transaction is rolled back. All outstanding pages are invalidated +** and their memory is freed. Any attempt to use a page associated +** with this page cache after this function returns will likely +** result in a coredump. +** +** This function always succeeds. If a transaction is active an attempt +** is made to roll it back. If an error occurs during the rollback +** a hot journal may be left in the filesystem but no error is returned +** to the caller. +*/ +int sqlite3PagerClose(Pager *pPager, sqlite3 *db) { + // u8 *pTmp = (u8*)pPager->pTmpSpace; + // assert( db || pagerUseWal(pPager)==0 ); + // assert( assert_pager_state(pPager) ); + // disable_simulated_io_errors(); + // sqlite3BeginBenignMalloc(); + // pagerFreeMapHdrs(pPager); + // /* pPager->errCode = 0; */ + // pPager->exclusiveMode = 0; + // #ifndef SQLITE_OMIT_WAL + // { + // u8 *a = 0; + // assert( db || pPager->pWal==0 ); + // if( db && 0==(db->flags & SQLITE_NoCkptOnClose) + // && SQLITE_OK==databaseIsUnmoved(pPager) + // ){ + // a = pTmp; + // } + // sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize,a); + // pPager->pWal = 0; + // } + // #endif + // pager_reset(pPager); + // if( MEMDB ){ + // pager_unlock(pPager); + // }else{ + // /* If it is open, sync the journal file before calling UnlockAndRollback. + // ** If this is not done, then an unsynced portion of the open journal + // ** file may be played back into the database. If a power failure occurs + // ** while this is happening, the database could become corrupt. + // ** + // ** If an error occurs while trying to sync the journal, shift the pager + // ** into the ERROR state. This causes UnlockAndRollback to unlock the + // ** database and close the journal file without attempting to roll it + // ** back or finalize it. The next database user will have to do hot-journal + // ** rollback before accessing the database file. + // */ + // if( isOpen(pPager->jfd) ){ + // pager_error(pPager, pagerSyncHotJournal(pPager)); + // } + // pagerUnlockAndRollback(pPager); + // } + // sqlite3EndBenignMalloc(); + // enable_simulated_io_errors(); + // PAGERTRACE(("CLOSE %d\n", PAGERID(pPager))); + // IOTRACE(("CLOSE %p\n", pPager)) + // sqlite3OsClose(pPager->jfd); + // sqlite3OsClose(pPager->fd); + // sqlite3PageFree(pTmp); + // sqlite3PcacheClose(pPager->pPCache); + // assert( !pPager->aSavepoint && !pPager->pInJournal ); + // assert( !isOpen(pPager->jfd) && !isOpen(pPager->sjfd) ); -// /* -// ** Shutdown the page cache. Free all memory and close all files. -// ** -// ** If a transaction was in progress when this routine is called, that -// ** transaction is rolled back. All outstanding pages are invalidated -// ** and their memory is freed. Any attempt to use a page associated -// ** with this page cache after this function returns will likely -// ** result in a coredump. -// ** -// ** This function always succeeds. If a transaction is active an attempt -// ** is made to roll it back. If an error occurs during the rollback -// ** a hot journal may be left in the filesystem but no error is returned -// ** to the caller. -// */ -// int sqlite3PagerClose(Pager *pPager, sqlite3 *db){ -// u8 *pTmp = (u8*)pPager->pTmpSpace; -// assert( db || pagerUseWal(pPager)==0 ); -// assert( assert_pager_state(pPager) ); -// disable_simulated_io_errors(); -// sqlite3BeginBenignMalloc(); -// pagerFreeMapHdrs(pPager); -// /* pPager->errCode = 0; */ -// pPager->exclusiveMode = 0; -// #ifndef SQLITE_OMIT_WAL -// { -// u8 *a = 0; -// assert( db || pPager->pWal==0 ); -// if( db && 0==(db->flags & SQLITE_NoCkptOnClose) -// && SQLITE_OK==databaseIsUnmoved(pPager) -// ){ -// a = pTmp; -// } -// sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize,a); -// pPager->pWal = 0; -// } -// #endif -// pager_reset(pPager); -// if( MEMDB ){ -// pager_unlock(pPager); -// }else{ -// /* If it is open, sync the journal file before calling UnlockAndRollback. -// ** If this is not done, then an unsynced portion of the open journal -// ** file may be played back into the database. If a power failure occurs -// ** while this is happening, the database could become corrupt. -// ** -// ** If an error occurs while trying to sync the journal, shift the pager -// ** into the ERROR state. This causes UnlockAndRollback to unlock the -// ** database and close the journal file without attempting to roll it -// ** back or finalize it. The next database user will have to do hot-journal -// ** rollback before accessing the database file. -// */ -// if( isOpen(pPager->jfd) ){ -// pager_error(pPager, pagerSyncHotJournal(pPager)); -// } -// pagerUnlockAndRollback(pPager); -// } -// sqlite3EndBenignMalloc(); -// enable_simulated_io_errors(); -// PAGERTRACE(("CLOSE %d\n", PAGERID(pPager))); -// IOTRACE(("CLOSE %p\n", pPager)) -// sqlite3OsClose(pPager->jfd); -// sqlite3OsClose(pPager->fd); -// sqlite3PageFree(pTmp); -// sqlite3PcacheClose(pPager->pPCache); -// assert( !pPager->aSavepoint && !pPager->pInJournal ); -// assert( !isOpen(pPager->jfd) && !isOpen(pPager->sjfd) ); - -// sqlite3_free(pPager); -// return SQLITE_OK; -// } + // sqlite3_free(pPager); + return SQLITE_OK; +} // #if !defined(NDEBUG) || defined(SQLITE_TEST) // /* @@ -4174,7 +4163,7 @@ // ** disk and can be restored in the event of a hot-journal rollback. // ** // ** If the Pager.noSync flag is set, then this function is a no-op. -// ** Otherwise, the actions required depend on the journal-mode and the +// ** Otherwise, the actions required depend on the journal-mode and the // ** device characteristics of the file-system, as follows: // ** // ** * If the journal file is an in-memory journal file, no action need @@ -4186,7 +4175,7 @@ // ** been written following it. If the pager is operating in full-sync // ** mode, then the journal file is synced before this field is updated. // ** -// ** * If the device does not support the SEQUENTIAL property, then +// ** * If the device does not support the SEQUENTIAL property, then // ** journal file is synced. // ** // ** Or, in pseudo-code: @@ -4195,11 +4184,11 @@ // ** if( NOT SAFE_APPEND ){ // ** if( ) xSync(); // ** -// ** } +// ** } // ** if( NOT SEQUENTIAL ) xSync(); // ** } // ** -// ** If successful, this routine clears the PGHDR_NEED_SYNC flag of every +// ** If successful, this routine clears the PGHDR_NEED_SYNC flag of every // ** page currently held in memory before returning SQLITE_OK. If an IO // ** error is encountered, then the IO error code is returned to the caller. // */ @@ -4227,10 +4216,10 @@ // ** mode, then the journal file may at this point actually be larger // ** than Pager.journalOff bytes. If the next thing in the journal // ** file happens to be a journal-header (written as part of the -// ** previous connection's transaction), and a crash or power-failure -// ** occurs after nRec is updated but before this connection writes -// ** anything else to the journal file (or commits/rolls back its -// ** transaction), then SQLite may become confused when doing the +// ** previous connection's transaction), and a crash or power-failure +// ** occurs after nRec is updated but before this connection writes +// ** anything else to the journal file (or commits/rolls back its +// ** transaction), then SQLite may become confused when doing the // ** hot-journal rollback following recovery. It may roll back all // ** of this connections data, then proceed to rolling back the old, // ** out-of-date data that follows it. Database corruption. @@ -4240,7 +4229,7 @@ // ** byte to the start of it to prevent it from being recognized. // ** // ** Variable iNextHdrOffset is set to the offset at which this -// ** problematic header will occur, if it exists. aMagic is used +// ** problematic header will occur, if it exists. aMagic is used // ** as a temporary buffer to inspect the first couple of bytes of // ** the potential journal header. // */ @@ -4267,7 +4256,7 @@ // ** it as a candidate for rollback. // ** // ** This is not required if the persistent media supports the -// ** SAFE_APPEND property. Because in this case it is not possible +// ** SAFE_APPEND property. Because in this case it is not possible // ** for garbage data to be appended to the file, the nRec field // ** is populated with 0xFFFFFFFF when the journal header is written // ** and never needs to be updated. @@ -4287,7 +4276,7 @@ // if( 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){ // PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager))); // IOTRACE(("JSYNC %p\n", pPager)) -// rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags| +// rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags| // (pPager->syncFlags==SQLITE_SYNC_FULL?SQLITE_SYNC_DATAONLY:0) // ); // if( rc!=SQLITE_OK ) return rc; @@ -4304,8 +4293,8 @@ // } // } -// /* Unless the pager is in noSync mode, the journal file was just -// ** successfully synced. Either way, clear the PGHDR_NEED_SYNC flag on +// /* Unless the pager is in noSync mode, the journal file was just +// ** successfully synced. Either way, clear the PGHDR_NEED_SYNC flag on // ** all pages. // */ // sqlite3PcacheClearSyncFlags(pPager->pPCache); @@ -4325,9 +4314,9 @@ // ** is called. Before writing anything to the database file, this lock // ** is upgraded to an EXCLUSIVE lock. If the lock cannot be obtained, // ** SQLITE_BUSY is returned and no data is written to the database file. -// ** +// ** // ** If the pager is a temp-file pager and the actual file-system file -// ** is not yet open, it is created and opened before any data is +// ** is not yet open, it is created and opened before any data is // ** written out. // ** // ** Once the lock has been upgraded and, if necessary, the file opened, @@ -4342,7 +4331,7 @@ // ** in Pager.dbFileVers[] is updated to match the new value stored in // ** the database file. // ** -// ** If everything is successful, SQLITE_OK is returned. If an IO error +// ** If everything is successful, SQLITE_OK is returned. If an IO error // ** occurs, an IO error code is returned. Or, if the EXCLUSIVE lock cannot // ** be obtained, SQLITE_BUSY is returned. // */ @@ -4368,7 +4357,7 @@ // ** file size will be. // */ // assert( rc!=SQLITE_OK || isOpen(pPager->fd) ); -// if( rc==SQLITE_OK +// if( rc==SQLITE_OK // && pPager->dbHintSizedbSize // && (pList->pDirty || pList->pgno>pPager->dbHintSize) // ){ @@ -4390,7 +4379,7 @@ // */ // if( pgno<=pPager->dbSize && 0==(pList->flags&PGHDR_DONT_WRITE) ){ // i64 offset = (pgno-1)*(i64)pPager->pageSize; /* Offset to write */ -// char *pData; /* Data to write */ +// char *pData; /* Data to write */ // assert( (pList->flags&PGHDR_NEED_SYNC)==0 ); // if( pList->pgno==1 ) pager_write_changecounter(pList); @@ -4401,8 +4390,8 @@ // rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset); // /* If page 1 was just written, update Pager.dbFileVers to match -// ** the value now stored in the database file. If writing this -// ** page caused the database file to grow, update dbFileSize. +// ** the value now stored in the database file. If writing this +// ** page caused the database file to grow, update dbFileSize. // */ // if( pgno==1 ){ // memcpy(&pPager->dbFileVers, &pData[24], sizeof(pPager->dbFileVers)); @@ -4430,18 +4419,18 @@ // } // /* -// ** Ensure that the sub-journal file is open. If it is already open, this +// ** Ensure that the sub-journal file is open. If it is already open, this // ** function is a no-op. // ** -// ** SQLITE_OK is returned if everything goes according to plan. An -// ** SQLITE_IOERR_XXX error code is returned if a call to sqlite3OsOpen() +// ** SQLITE_OK is returned if everything goes according to plan. An +// ** SQLITE_IOERR_XXX error code is returned if a call to sqlite3OsOpen() // ** fails. // */ // static int openSubJournal(Pager *pPager){ // int rc = SQLITE_OK; // if( !isOpen(pPager->sjfd) ){ -// const int flags = SQLITE_OPEN_SUBJOURNAL | SQLITE_OPEN_READWRITE -// | SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE +// const int flags = SQLITE_OPEN_SUBJOURNAL | SQLITE_OPEN_READWRITE +// | SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE // | SQLITE_OPEN_DELETEONCLOSE; // int nStmtSpill = sqlite3Config.nStmtSpill; // if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY || pPager->subjInMemory ){ @@ -4453,13 +4442,13 @@ // } // /* -// ** Append a record of the current state of page pPg to the sub-journal. +// ** Append a record of the current state of page pPg to the sub-journal. // ** // ** If successful, set the bit corresponding to pPg->pgno in the bitvecs // ** for all open savepoints before returning. // ** // ** This function returns SQLITE_OK if everything is successful, an IO -// ** error code if the attempt to write to the sub-journal fails, or +// ** error code if the attempt to write to the sub-journal fails, or // ** SQLITE_NOMEM if a malloc fails while setting a bit in a savepoint // ** bitvec. // */ @@ -4472,9 +4461,9 @@ // assert( pPager->useJournal ); // assert( isOpen(pPager->jfd) || pagerUseWal(pPager) ); // assert( isOpen(pPager->sjfd) || pPager->nSubRec==0 ); -// assert( pagerUseWal(pPager) -// || pageInJournal(pPager, pPg) -// || pPg->pgno>pPager->dbOrigSize +// assert( pagerUseWal(pPager) +// || pageInJournal(pPager, pPg) +// || pPg->pgno>pPager->dbOrigSize // ); // rc = openSubJournal(pPager); @@ -4511,14 +4500,14 @@ // ** This function is called by the pcache layer when it has reached some // ** soft memory limit. The first argument is a pointer to a Pager object // ** (cast as a void*). The pager is always 'purgeable' (not an in-memory -// ** database). The second argument is a reference to a page that is +// ** database). The second argument is a reference to a page that is // ** currently dirty but has no outstanding references. The page -// ** is always associated with the Pager object passed as the first +// ** is always associated with the Pager object passed as the first // ** argument. // ** // ** The job of this function is to make pPg clean by writing its contents // ** out to the database file, if possible. This may involve syncing the -// ** journal file. +// ** journal file. // ** // ** If successful, sqlite3PcacheMakeClean() is called on the page and // ** SQLITE_OK returned. If an IO error occurs while trying to make the @@ -4543,7 +4532,7 @@ // ** a rollback or by user request, respectively. // ** // ** Spilling is also prohibited when in an error state since that could -// ** lead to database corruption. In the current implementation it +// ** lead to database corruption. In the current implementation it // ** is impossible for sqlite3PcacheFetch() to be called with createFlag==3 // ** while in the error state, hence it is impossible for this routine to // ** be called in the error state. Nevertheless, we include a NEVER() @@ -4564,26 +4553,26 @@ // pPg->pDirty = 0; // if( pagerUseWal(pPager) ){ // /* Write a single frame for this page to the log. */ -// rc = subjournalPageIfRequired(pPg); +// rc = subjournalPageIfRequired(pPg); // if( rc==SQLITE_OK ){ // rc = pagerWalFrames(pPager, pPg, 0, 0); // } // }else{ - + // #ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE // if( pPager->tempFile==0 ){ // rc = sqlite3JournalCreate(pPager->jfd); // if( rc!=SQLITE_OK ) return pager_error(pPager, rc); // } // #endif - + // /* Sync the journal file if required. */ -// if( pPg->flags&PGHDR_NEED_SYNC +// if( pPg->flags&PGHDR_NEED_SYNC // || pPager->eState==PAGER_WRITER_CACHEMOD // ){ // rc = syncJournal(pPager, 1); // } - + // /* Write the contents of the page out to the database file. */ // if( rc==SQLITE_OK ){ // assert( (pPg->flags&PGHDR_NEED_SYNC)==0 ); @@ -4597,7 +4586,7 @@ // sqlite3PcacheMakeClean(pPg); // } -// return pager_error(pPager, rc); +// return pager_error(pPager, rc); // } // /* @@ -4620,404 +4609,402 @@ // return rc; // } -// /* -// ** Allocate and initialize a new Pager object and put a pointer to it -// ** in *ppPager. The pager should eventually be freed by passing it -// ** to sqlite3PagerClose(). -// ** -// ** The zFilename argument is the path to the database file to open. -// ** If zFilename is NULL then a randomly-named temporary file is created -// ** and used as the file to be cached. Temporary files are be deleted -// ** automatically when they are closed. If zFilename is ":memory:" then -// ** all information is held in cache. It is never written to disk. -// ** This can be used to implement an in-memory database. -// ** -// ** The nExtra parameter specifies the number of bytes of space allocated -// ** along with each page reference. This space is available to the user -// ** via the sqlite3PagerGetExtra() API. When a new page is allocated, the -// ** first 8 bytes of this space are zeroed but the remainder is uninitialized. -// ** (The extra space is used by btree as the MemPage object.) -// ** -// ** The flags argument is used to specify properties that affect the -// ** operation of the pager. It should be passed some bitwise combination -// ** of the PAGER_* flags. -// ** -// ** The vfsFlags parameter is a bitmask to pass to the flags parameter -// ** of the xOpen() method of the supplied VFS when opening files. -// ** -// ** If the pager object is allocated and the specified file opened -// ** successfully, SQLITE_OK is returned and *ppPager set to point to -// ** the new pager object. If an error occurs, *ppPager is set to NULL -// ** and error code returned. This function may return SQLITE_NOMEM -// ** (sqlite3Malloc() is used to allocate memory), SQLITE_CANTOPEN or -// ** various SQLITE_IO_XXX errors. -// */ -// int sqlite3PagerOpen( -// sqlite3_vfs *pVfs, /* The virtual file system to use */ -// Pager **ppPager, /* OUT: Return the Pager structure here */ -// const char *zFilename, /* Name of the database file to open */ -// int nExtra, /* Extra bytes append to each in-memory page */ -// int flags, /* flags controlling this file */ -// int vfsFlags, /* flags passed through to sqlite3_vfs.xOpen() */ -// void (*xReinit)(DbPage*) /* Function to reinitialize pages */ -// ){ -// u8 *pPtr; -// Pager *pPager = 0; /* Pager object to allocate and return */ -// int rc = SQLITE_OK; /* Return code */ -// int tempFile = 0; /* True for temp files (incl. in-memory files) */ -// int memDb = 0; /* True if this is an in-memory file */ -// #ifndef SQLITE_OMIT_DESERIALIZE -// int memJM = 0; /* Memory journal mode */ -// #else -// # define memJM 0 -// #endif -// int readOnly = 0; /* True if this is a read-only file */ -// int journalFileSize; /* Bytes to allocate for each journal fd */ -// char *zPathname = 0; /* Full path to database file */ -// int nPathname = 0; /* Number of bytes in zPathname */ -// int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */ -// int pcacheSize = sqlite3PcacheSize(); /* Bytes to allocate for PCache */ -// u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE; /* Default page size */ -// const char *zUri = 0; /* URI args to copy */ -// int nUriByte = 1; /* Number of bytes of URI args at *zUri */ -// int nUri = 0; /* Number of URI parameters */ +/* +** Allocate and initialize a new Pager object and put a pointer to it +** in *ppPager. The pager should eventually be freed by passing it +** to sqlite3PagerClose(). +** +** The zFilename argument is the path to the database file to open. +** If zFilename is NULL then a randomly-named temporary file is created +** and used as the file to be cached. Temporary files are be deleted +** automatically when they are closed. If zFilename is ":memory:" then +** all information is held in cache. It is never written to disk. +** This can be used to implement an in-memory database. +** +** The nExtra parameter specifies the number of bytes of space allocated +** along with each page reference. This space is available to the user +** via the sqlite3PagerGetExtra() API. When a new page is allocated, the +** first 8 bytes of this space are zeroed but the remainder is uninitialized. +** (The extra space is used by btree as the MemPage object.) +** +** The flags argument is used to specify properties that affect the +** operation of the pager. It should be passed some bitwise combination +** of the PAGER_* flags. +** +** The vfsFlags parameter is a bitmask to pass to the flags parameter +** of the xOpen() method of the supplied VFS when opening files. +** +** If the pager object is allocated and the specified file opened +** successfully, SQLITE_OK is returned and *ppPager set to point to +** the new pager object. If an error occurs, *ppPager is set to NULL +** and error code returned. This function may return SQLITE_NOMEM +** (sqlite3Malloc() is used to allocate memory), SQLITE_CANTOPEN or +** various SQLITE_IO_XXX errors. +*/ +int sqlite3PagerOpen(sqlite3_vfs *pVfs, /* The virtual file system to use */ + Pager ** ppPager, /* OUT: Return the Pager structure here */ + const char * zFilename, /* Name of the database file to open */ + int nExtra, /* Extra bytes append to each in-memory page */ + int flags, /* flags controlling this file */ + int vfsFlags, /* flags passed through to sqlite3_vfs.xOpen() */ + void (*xReinit)(DbPage *) /* Function to reinitialize pages */ +) { + // u8 *pPtr; + // Pager *pPager = 0; /* Pager object to allocate and return */ + // int rc = SQLITE_OK; /* Return code */ + // int tempFile = 0; /* True for temp files (incl. in-memory files) */ + // int memDb = 0; /* True if this is an in-memory file */ + // #ifndef SQLITE_OMIT_DESERIALIZE + // int memJM = 0; /* Memory journal mode */ + // #else + // # define memJM 0 + // #endif + // int readOnly = 0; /* True if this is a read-only file */ + // int journalFileSize; /* Bytes to allocate for each journal fd */ + // char *zPathname = 0; /* Full path to database file */ + // int nPathname = 0; /* Number of bytes in zPathname */ + // int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */ + // int pcacheSize = sqlite3PcacheSize(); /* Bytes to allocate for PCache */ + // u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE; /* Default page size */ + // const char *zUri = 0; /* URI args to copy */ + // int nUriByte = 1; /* Number of bytes of URI args at *zUri */ + // int nUri = 0; /* Number of URI parameters */ -// /* Figure out how much space is required for each journal file-handle -// ** (there are two of them, the main journal and the sub-journal). */ -// journalFileSize = ROUND8(sqlite3JournalSize(pVfs)); + // /* Figure out how much space is required for each journal file-handle + // ** (there are two of them, the main journal and the sub-journal). */ + // journalFileSize = ROUND8(sqlite3JournalSize(pVfs)); -// /* Set the output variable to NULL in case an error occurs. */ -// *ppPager = 0; + // /* Set the output variable to NULL in case an error occurs. */ + // *ppPager = 0; -// #ifndef SQLITE_OMIT_MEMORYDB -// if( flags & PAGER_MEMORY ){ -// memDb = 1; -// if( zFilename && zFilename[0] ){ -// zPathname = sqlite3DbStrDup(0, zFilename); -// if( zPathname==0 ) return SQLITE_NOMEM; -// nPathname = sqlite3Strlen30(zPathname); -// zFilename = 0; -// } -// } -// #endif + // #ifndef SQLITE_OMIT_MEMORYDB + // if( flags & PAGER_MEMORY ){ + // memDb = 1; + // if( zFilename && zFilename[0] ){ + // zPathname = sqlite3DbStrDup(0, zFilename); + // if( zPathname==0 ) return SQLITE_NOMEM; + // nPathname = sqlite3Strlen30(zPathname); + // zFilename = 0; + // } + // } + // #endif -// /* Compute and store the full pathname in an allocated buffer pointed -// ** to by zPathname, length nPathname. Or, if this is a temporary file, -// ** leave both nPathname and zPathname set to 0. -// */ -// if( zFilename && zFilename[0] ){ -// const char *z; -// nPathname = pVfs->mxPathname+1; -// zPathname = sqlite3DbMallocRaw(0, nPathname*2); -// if( zPathname==0 ){ -// return SQLITE_NOMEM; -// } -// zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */ -// rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname); -// if( rc!=SQLITE_OK ){ -// if( rc==SQLITE_OK_SYMLINK ){ -// if( vfsFlags & SQLITE_OPEN_NOFOLLOW ){ -// rc = SQLITE_CANTOPEN_SYMLINK; -// }else{ -// rc = SQLITE_OK; -// } -// } -// } -// nPathname = sqlite3Strlen30(zPathname); -// z = zUri = &zFilename[sqlite3Strlen30(zFilename)+1]; -// while( *z ){ -// z += strlen(z)+1; -// z += strlen(z)+1; -// nUri++; -// } -// nUriByte = (int)(&z[1] - zUri); -// assert( nUriByte>=1 ); -// if( rc==SQLITE_OK && nPathname+8>pVfs->mxPathname ){ -// /* This branch is taken when the journal path required by -// ** the database being opened will be more than pVfs->mxPathname -// ** bytes in length. This means the database cannot be opened, -// ** as it will not be possible to open the journal file or even -// ** check for a hot-journal before reading. -// */ -// rc = SQLITE_CANTOPEN_BKPT; -// } -// if( rc!=SQLITE_OK ){ -// sqlite3DbFree(0, zPathname); -// return rc; -// } -// } + // /* Compute and store the full pathname in an allocated buffer pointed + // ** to by zPathname, length nPathname. Or, if this is a temporary file, + // ** leave both nPathname and zPathname set to 0. + // */ + // if( zFilename && zFilename[0] ){ + // const char *z; + // nPathname = pVfs->mxPathname+1; + // zPathname = sqlite3DbMallocRaw(0, nPathname*2); + // if( zPathname==0 ){ + // return SQLITE_NOMEM; + // } + // zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */ + // rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname); + // if( rc!=SQLITE_OK ){ + // if( rc==SQLITE_OK_SYMLINK ){ + // if( vfsFlags & SQLITE_OPEN_NOFOLLOW ){ + // rc = SQLITE_CANTOPEN_SYMLINK; + // }else{ + // rc = SQLITE_OK; + // } + // } + // } + // nPathname = sqlite3Strlen30(zPathname); + // z = zUri = &zFilename[sqlite3Strlen30(zFilename)+1]; + // while( *z ){ + // z += strlen(z)+1; + // z += strlen(z)+1; + // nUri++; + // } + // nUriByte = (int)(&z[1] - zUri); + // assert( nUriByte>=1 ); + // if( rc==SQLITE_OK && nPathname+8>pVfs->mxPathname ){ + // /* This branch is taken when the journal path required by + // ** the database being opened will be more than pVfs->mxPathname + // ** bytes in length. This means the database cannot be opened, + // ** as it will not be possible to open the journal file or even + // ** check for a hot-journal before reading. + // */ + // rc = SQLITE_CANTOPEN_BKPT; + // } + // if( rc!=SQLITE_OK ){ + // sqlite3DbFree(0, zPathname); + // return rc; + // } + // } -// /* Allocate memory for the Pager structure, PCache object, the -// ** three file descriptors, the database file name and the journal -// ** file name. The layout in memory is as follows: -// ** -// ** Pager object (sizeof(Pager) bytes) -// ** PCache object (sqlite3PcacheSize() bytes) -// ** Database file handle (pVfs->szOsFile bytes) -// ** Sub-journal file handle (journalFileSize bytes) -// ** Main journal file handle (journalFileSize bytes) -// ** Ptr back to the Pager (sizeof(Pager*) bytes) -// ** \0\0\0\0 database prefix (4 bytes) -// ** Database file name (nPathname+1 bytes) -// ** URI query parameters (nUriByte bytes) -// ** Journal filename (nPathname+8+1 bytes) -// ** WAL filename (nPathname+4+1 bytes) -// ** \0\0\0 terminator (3 bytes) -// ** -// ** Some 3rd-party software, over which we have no control, depends on -// ** the specific order of the filenames and the \0 separators between them -// ** so that it can (for example) find the database filename given the WAL -// ** filename without using the sqlite3_filename_database() API. This is a -// ** misuse of SQLite and a bug in the 3rd-party software, but the 3rd-party -// ** software is in widespread use, so we try to avoid changing the filename -// ** order and formatting if possible. In particular, the details of the -// ** filename format expected by 3rd-party software should be as follows: -// ** -// ** - Main Database Path -// ** - \0 -// ** - Multiple URI components consisting of: -// ** - Key -// ** - \0 -// ** - Value -// ** - \0 -// ** - \0 -// ** - Journal Path -// ** - \0 -// ** - WAL Path (zWALName) -// ** - \0 -// ** -// ** The sqlite3_create_filename() interface and the databaseFilename() utility -// ** that is used by sqlite3_filename_database() and kin also depend on the -// ** specific formatting and order of the various filenames, so if the format -// ** changes here, be sure to change it there as well. -// */ -// pPtr = (u8 *)sqlite3MallocZero( -// ROUND8(sizeof(*pPager)) + /* Pager structure */ -// ROUND8(pcacheSize) + /* PCache object */ -// ROUND8(pVfs->szOsFile) + /* The main db file */ -// journalFileSize * 2 + /* The two journal files */ -// sizeof(pPager) + /* Space to hold a pointer */ -// 4 + /* Database prefix */ -// nPathname + 1 + /* database filename */ -// nUriByte + /* query parameters */ -// nPathname + 8 + 1 + /* Journal filename */ -// #ifndef SQLITE_OMIT_WAL -// nPathname + 4 + 1 + /* WAL filename */ -// #endif -// 3 /* Terminator */ -// ); -// assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) ); -// if( !pPtr ){ -// sqlite3DbFree(0, zPathname); -// return SQLITE_NOMEM; -// } -// pPager = (Pager*)pPtr; pPtr += ROUND8(sizeof(*pPager)); -// pPager->pPCache = (PCache*)pPtr; pPtr += ROUND8(pcacheSize); -// pPager->fd = (sqlite3_file*)pPtr; pPtr += ROUND8(pVfs->szOsFile); -// pPager->sjfd = (sqlite3_file*)pPtr; pPtr += journalFileSize; -// pPager->jfd = (sqlite3_file*)pPtr; pPtr += journalFileSize; -// assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) ); -// memcpy(pPtr, &pPager, sizeof(pPager)); pPtr += sizeof(pPager); + // /* Allocate memory for the Pager structure, PCache object, the + // ** three file descriptors, the database file name and the journal + // ** file name. The layout in memory is as follows: + // ** + // ** Pager object (sizeof(Pager) bytes) + // ** PCache object (sqlite3PcacheSize() bytes) + // ** Database file handle (pVfs->szOsFile bytes) + // ** Sub-journal file handle (journalFileSize bytes) + // ** Main journal file handle (journalFileSize bytes) + // ** Ptr back to the Pager (sizeof(Pager*) bytes) + // ** \0\0\0\0 database prefix (4 bytes) + // ** Database file name (nPathname+1 bytes) + // ** URI query parameters (nUriByte bytes) + // ** Journal filename (nPathname+8+1 bytes) + // ** WAL filename (nPathname+4+1 bytes) + // ** \0\0\0 terminator (3 bytes) + // ** + // ** Some 3rd-party software, over which we have no control, depends on + // ** the specific order of the filenames and the \0 separators between them + // ** so that it can (for example) find the database filename given the WAL + // ** filename without using the sqlite3_filename_database() API. This is a + // ** misuse of SQLite and a bug in the 3rd-party software, but the 3rd-party + // ** software is in widespread use, so we try to avoid changing the filename + // ** order and formatting if possible. In particular, the details of the + // ** filename format expected by 3rd-party software should be as follows: + // ** + // ** - Main Database Path + // ** - \0 + // ** - Multiple URI components consisting of: + // ** - Key + // ** - \0 + // ** - Value + // ** - \0 + // ** - \0 + // ** - Journal Path + // ** - \0 + // ** - WAL Path (zWALName) + // ** - \0 + // ** + // ** The sqlite3_create_filename() interface and the databaseFilename() utility + // ** that is used by sqlite3_filename_database() and kin also depend on the + // ** specific formatting and order of the various filenames, so if the format + // ** changes here, be sure to change it there as well. + // */ + // pPtr = (u8 *)sqlite3MallocZero( + // ROUND8(sizeof(*pPager)) + /* Pager structure */ + // ROUND8(pcacheSize) + /* PCache object */ + // ROUND8(pVfs->szOsFile) + /* The main db file */ + // journalFileSize * 2 + /* The two journal files */ + // sizeof(pPager) + /* Space to hold a pointer */ + // 4 + /* Database prefix */ + // nPathname + 1 + /* database filename */ + // nUriByte + /* query parameters */ + // nPathname + 8 + 1 + /* Journal filename */ + // #ifndef SQLITE_OMIT_WAL + // nPathname + 4 + 1 + /* WAL filename */ + // #endif + // 3 /* Terminator */ + // ); + // assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) ); + // if( !pPtr ){ + // sqlite3DbFree(0, zPathname); + // return SQLITE_NOMEM; + // } + // pPager = (Pager*)pPtr; pPtr += ROUND8(sizeof(*pPager)); + // pPager->pPCache = (PCache*)pPtr; pPtr += ROUND8(pcacheSize); + // pPager->fd = (sqlite3_file*)pPtr; pPtr += ROUND8(pVfs->szOsFile); + // pPager->sjfd = (sqlite3_file*)pPtr; pPtr += journalFileSize; + // pPager->jfd = (sqlite3_file*)pPtr; pPtr += journalFileSize; + // assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) ); + // memcpy(pPtr, &pPager, sizeof(pPager)); pPtr += sizeof(pPager); -// /* Fill in the Pager.zFilename and pPager.zQueryParam fields */ -// pPtr += 4; /* Skip zero prefix */ -// pPager->zFilename = (char*)pPtr; -// if( nPathname>0 ){ -// memcpy(pPtr, zPathname, nPathname); pPtr += nPathname + 1; -// if( zUri ){ -// memcpy(pPtr, zUri, nUriByte); pPtr += nUriByte; -// }else{ -// pPtr++; -// } -// } + // /* Fill in the Pager.zFilename and pPager.zQueryParam fields */ + // pPtr += 4; /* Skip zero prefix */ + // pPager->zFilename = (char*)pPtr; + // if( nPathname>0 ){ + // memcpy(pPtr, zPathname, nPathname); pPtr += nPathname + 1; + // if( zUri ){ + // memcpy(pPtr, zUri, nUriByte); pPtr += nUriByte; + // }else{ + // pPtr++; + // } + // } + // /* Fill in Pager.zJournal */ + // if( nPathname>0 ){ + // pPager->zJournal = (char*)pPtr; + // memcpy(pPtr, zPathname, nPathname); pPtr += nPathname; + // memcpy(pPtr, "-journal",8); pPtr += 8 + 1; + // #ifdef SQLITE_ENABLE_8_3_NAMES + // sqlite3FileSuffix3(zFilename,pPager->zJournal); + // pPtr = (u8*)(pPager->zJournal + sqlite3Strlen30(pPager->zJournal)+1); + // #endif + // }else{ + // pPager->zJournal = 0; + // } -// /* Fill in Pager.zJournal */ -// if( nPathname>0 ){ -// pPager->zJournal = (char*)pPtr; -// memcpy(pPtr, zPathname, nPathname); pPtr += nPathname; -// memcpy(pPtr, "-journal",8); pPtr += 8 + 1; -// #ifdef SQLITE_ENABLE_8_3_NAMES -// sqlite3FileSuffix3(zFilename,pPager->zJournal); -// pPtr = (u8*)(pPager->zJournal + sqlite3Strlen30(pPager->zJournal)+1); -// #endif -// }else{ -// pPager->zJournal = 0; -// } + // #ifndef SQLITE_OMIT_WAL + // /* Fill in Pager.zWal */ + // if( nPathname>0 ){ + // pPager->zWal = (char*)pPtr; + // memcpy(pPtr, zPathname, nPathname); pPtr += nPathname; + // memcpy(pPtr, "-wal", 4); pPtr += 4 + 1; + // #ifdef SQLITE_ENABLE_8_3_NAMES + // sqlite3FileSuffix3(zFilename, pPager->zWal); + // pPtr = (u8*)(pPager->zWal + sqlite3Strlen30(pPager->zWal)+1); + // #endif + // }else{ + // pPager->zWal = 0; + // } + // #endif + // (void)pPtr; /* Suppress warning about unused pPtr value */ -// #ifndef SQLITE_OMIT_WAL -// /* Fill in Pager.zWal */ -// if( nPathname>0 ){ -// pPager->zWal = (char*)pPtr; -// memcpy(pPtr, zPathname, nPathname); pPtr += nPathname; -// memcpy(pPtr, "-wal", 4); pPtr += 4 + 1; -// #ifdef SQLITE_ENABLE_8_3_NAMES -// sqlite3FileSuffix3(zFilename, pPager->zWal); -// pPtr = (u8*)(pPager->zWal + sqlite3Strlen30(pPager->zWal)+1); -// #endif -// }else{ -// pPager->zWal = 0; -// } -// #endif -// (void)pPtr; /* Suppress warning about unused pPtr value */ + // if( nPathname ) sqlite3DbFree(0, zPathname); + // pPager->pVfs = pVfs; + // pPager->vfsFlags = vfsFlags; -// if( nPathname ) sqlite3DbFree(0, zPathname); -// pPager->pVfs = pVfs; -// pPager->vfsFlags = vfsFlags; + // /* Open the pager file. + // */ + // if( zFilename && zFilename[0] ){ + // int fout = 0; /* VFS flags returned by xOpen() */ + // rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout); + // assert( !memDb ); + // #ifndef SQLITE_OMIT_DESERIALIZE + // pPager->memVfs = memJM = (fout&SQLITE_OPEN_MEMORY)!=0; + // #endif + // readOnly = (fout&SQLITE_OPEN_READONLY)!=0; -// /* Open the pager file. -// */ -// if( zFilename && zFilename[0] ){ -// int fout = 0; /* VFS flags returned by xOpen() */ -// rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout); -// assert( !memDb ); -// #ifndef SQLITE_OMIT_DESERIALIZE -// pPager->memVfs = memJM = (fout&SQLITE_OPEN_MEMORY)!=0; -// #endif -// readOnly = (fout&SQLITE_OPEN_READONLY)!=0; + // /* If the file was successfully opened for read/write access, + // ** choose a default page size in case we have to create the + // ** database file. The default page size is the maximum of: + // ** + // ** + SQLITE_DEFAULT_PAGE_SIZE, + // ** + The value returned by sqlite3OsSectorSize() + // ** + The largest page size that can be written atomically. + // */ + // if( rc==SQLITE_OK ){ + // int iDc = sqlite3OsDeviceCharacteristics(pPager->fd); + // if( !readOnly ){ + // setSectorSize(pPager); + // assert(SQLITE_DEFAULT_PAGE_SIZE<=SQLITE_MAX_DEFAULT_PAGE_SIZE); + // if( szPageDfltsectorSize ){ + // if( pPager->sectorSize>SQLITE_MAX_DEFAULT_PAGE_SIZE ){ + // szPageDflt = SQLITE_MAX_DEFAULT_PAGE_SIZE; + // }else{ + // szPageDflt = (u32)pPager->sectorSize; + // } + // } + // #ifdef SQLITE_ENABLE_ATOMIC_WRITE + // { + // int ii; + // assert(SQLITE_IOCAP_ATOMIC512==(512>>8)); + // assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8)); + // assert(SQLITE_MAX_DEFAULT_PAGE_SIZE<=65536); + // for(ii=szPageDflt; ii<=SQLITE_MAX_DEFAULT_PAGE_SIZE; ii=ii*2){ + // if( iDc&(SQLITE_IOCAP_ATOMIC|(ii>>8)) ){ + // szPageDflt = ii; + // } + // } + // } + // #endif + // } + // pPager->noLock = sqlite3_uri_boolean(pPager->zFilename, "nolock", 0); + // if( (iDc & SQLITE_IOCAP_IMMUTABLE)!=0 + // || sqlite3_uri_boolean(pPager->zFilename, "immutable", 0) ){ + // vfsFlags |= SQLITE_OPEN_READONLY; + // goto act_like_temp_file; + // } + // } + // }else{ + // /* If a temporary file is requested, it is not opened immediately. + // ** In this case we accept the default page size and delay actually + // ** 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. + // ** + // ** This branch also runs for files marked as immutable. + // */ + // act_like_temp_file: + // tempFile = 1; + // pPager->eState = PAGER_READER; /* Pretend we already have a lock */ + // pPager->eLock = EXCLUSIVE_LOCK; /* Pretend we are in EXCLUSIVE mode */ + // pPager->noLock = 1; /* Do no locking */ + // readOnly = (vfsFlags&SQLITE_OPEN_READONLY); + // } -// /* If the file was successfully opened for read/write access, -// ** choose a default page size in case we have to create the -// ** database file. The default page size is the maximum of: -// ** -// ** + SQLITE_DEFAULT_PAGE_SIZE, -// ** + The value returned by sqlite3OsSectorSize() -// ** + The largest page size that can be written atomically. -// */ -// if( rc==SQLITE_OK ){ -// int iDc = sqlite3OsDeviceCharacteristics(pPager->fd); -// if( !readOnly ){ -// setSectorSize(pPager); -// assert(SQLITE_DEFAULT_PAGE_SIZE<=SQLITE_MAX_DEFAULT_PAGE_SIZE); -// if( szPageDfltsectorSize ){ -// if( pPager->sectorSize>SQLITE_MAX_DEFAULT_PAGE_SIZE ){ -// szPageDflt = SQLITE_MAX_DEFAULT_PAGE_SIZE; -// }else{ -// szPageDflt = (u32)pPager->sectorSize; -// } -// } -// #ifdef SQLITE_ENABLE_ATOMIC_WRITE -// { -// int ii; -// assert(SQLITE_IOCAP_ATOMIC512==(512>>8)); -// assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8)); -// assert(SQLITE_MAX_DEFAULT_PAGE_SIZE<=65536); -// for(ii=szPageDflt; ii<=SQLITE_MAX_DEFAULT_PAGE_SIZE; ii=ii*2){ -// if( iDc&(SQLITE_IOCAP_ATOMIC|(ii>>8)) ){ -// szPageDflt = ii; -// } -// } -// } -// #endif -// } -// pPager->noLock = sqlite3_uri_boolean(pPager->zFilename, "nolock", 0); -// if( (iDc & SQLITE_IOCAP_IMMUTABLE)!=0 -// || sqlite3_uri_boolean(pPager->zFilename, "immutable", 0) ){ -// vfsFlags |= SQLITE_OPEN_READONLY; -// goto act_like_temp_file; -// } -// } -// }else{ -// /* If a temporary file is requested, it is not opened immediately. -// ** In this case we accept the default page size and delay actually -// ** 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. -// ** -// ** This branch also runs for files marked as immutable. -// */ -// act_like_temp_file: -// tempFile = 1; -// pPager->eState = PAGER_READER; /* Pretend we already have a lock */ -// pPager->eLock = EXCLUSIVE_LOCK; /* Pretend we are in EXCLUSIVE mode */ -// pPager->noLock = 1; /* Do no locking */ -// readOnly = (vfsFlags&SQLITE_OPEN_READONLY); -// } + // /* The following call to PagerSetPagesize() serves to set the value of + // ** Pager.pageSize and to allocate the Pager.pTmpSpace buffer. + // */ + // if( rc==SQLITE_OK ){ + // assert( pPager->memDb==0 ); + // rc = sqlite3PagerSetPagesize(pPager, &szPageDflt, -1); + // testcase( rc!=SQLITE_OK ); + // } -// /* The following call to PagerSetPagesize() serves to set the value of -// ** Pager.pageSize and to allocate the Pager.pTmpSpace buffer. -// */ -// if( rc==SQLITE_OK ){ -// assert( pPager->memDb==0 ); -// rc = sqlite3PagerSetPagesize(pPager, &szPageDflt, -1); -// testcase( rc!=SQLITE_OK ); -// } + // /* Initialize the PCache object. */ + // if( rc==SQLITE_OK ){ + // nExtra = ROUND8(nExtra); + // assert( nExtra>=8 && nExtra<1000 ); + // rc = sqlite3PcacheOpen(szPageDflt, nExtra, !memDb, + // !memDb?pagerStress:0, (void *)pPager, pPager->pPCache); + // } -// /* Initialize the PCache object. */ -// if( rc==SQLITE_OK ){ -// nExtra = ROUND8(nExtra); -// assert( nExtra>=8 && nExtra<1000 ); -// rc = sqlite3PcacheOpen(szPageDflt, nExtra, !memDb, -// !memDb?pagerStress:0, (void *)pPager, pPager->pPCache); -// } + // /* If an error occurred above, free the Pager structure and close the file. + // */ + // if( rc!=SQLITE_OK ){ + // sqlite3OsClose(pPager->fd); + // sqlite3PageFree(pPager->pTmpSpace); + // sqlite3_free(pPager); + // return rc; + // } -// /* If an error occurred above, free the Pager structure and close the file. -// */ -// if( rc!=SQLITE_OK ){ -// sqlite3OsClose(pPager->fd); -// sqlite3PageFree(pPager->pTmpSpace); -// sqlite3_free(pPager); -// return rc; -// } + // PAGERTRACE(("OPEN %d %s\n", FILEHANDLEID(pPager->fd), pPager->zFilename)); + // IOTRACE(("OPEN %p %s\n", pPager, pPager->zFilename)) -// PAGERTRACE(("OPEN %d %s\n", FILEHANDLEID(pPager->fd), pPager->zFilename)); -// IOTRACE(("OPEN %p %s\n", pPager, pPager->zFilename)) + // pPager->useJournal = (u8)useJournal; + // /* pPager->stmtOpen = 0; */ + // /* pPager->stmtInUse = 0; */ + // /* pPager->nRef = 0; */ + // /* pPager->stmtSize = 0; */ + // /* pPager->stmtJSize = 0; */ + // /* pPager->nPage = 0; */ + // pPager->mxPgno = SQLITE_MAX_PAGE_COUNT; + // /* pPager->state = PAGER_UNLOCK; */ + // /* pPager->errMask = 0; */ + // pPager->tempFile = (u8)tempFile; + // assert( tempFile==PAGER_LOCKINGMODE_NORMAL + // || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE ); + // assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 ); + // pPager->exclusiveMode = (u8)tempFile; + // pPager->changeCountDone = pPager->tempFile; + // pPager->memDb = (u8)memDb; + // pPager->readOnly = (u8)readOnly; + // assert( useJournal || pPager->tempFile ); + // pPager->noSync = pPager->tempFile; + // if( pPager->noSync ){ + // assert( pPager->fullSync==0 ); + // assert( pPager->extraSync==0 ); + // assert( pPager->syncFlags==0 ); + // assert( pPager->walSyncFlags==0 ); + // }else{ + // pPager->fullSync = 1; + // pPager->extraSync = 0; + // pPager->syncFlags = SQLITE_SYNC_NORMAL; + // pPager->walSyncFlags = SQLITE_SYNC_NORMAL | (SQLITE_SYNC_NORMAL<<2); + // } + // /* pPager->pFirst = 0; */ + // /* pPager->pFirstSynced = 0; */ + // /* pPager->pLast = 0; */ + // pPager->nExtra = (u16)nExtra; + // pPager->journalSizeLimit = SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT; + // assert( isOpen(pPager->fd) || tempFile ); + // setSectorSize(pPager); + // if( !useJournal ){ + // pPager->journalMode = PAGER_JOURNALMODE_OFF; + // }else if( memDb || memJM ){ + // pPager->journalMode = PAGER_JOURNALMODE_MEMORY; + // } + // /* pPager->xBusyHandler = 0; */ + // /* pPager->pBusyHandlerArg = 0; */ + // pPager->xReiniter = xReinit; + // setGetterMethod(pPager); + // /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */ + // /* pPager->szMmap = SQLITE_DEFAULT_MMAP_SIZE // will be set by btree.c */ -// pPager->useJournal = (u8)useJournal; -// /* pPager->stmtOpen = 0; */ -// /* pPager->stmtInUse = 0; */ -// /* pPager->nRef = 0; */ -// /* pPager->stmtSize = 0; */ -// /* pPager->stmtJSize = 0; */ -// /* pPager->nPage = 0; */ -// pPager->mxPgno = SQLITE_MAX_PAGE_COUNT; -// /* pPager->state = PAGER_UNLOCK; */ -// /* pPager->errMask = 0; */ -// pPager->tempFile = (u8)tempFile; -// assert( tempFile==PAGER_LOCKINGMODE_NORMAL -// || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE ); -// assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 ); -// pPager->exclusiveMode = (u8)tempFile; -// pPager->changeCountDone = pPager->tempFile; -// pPager->memDb = (u8)memDb; -// pPager->readOnly = (u8)readOnly; -// assert( useJournal || pPager->tempFile ); -// pPager->noSync = pPager->tempFile; -// if( pPager->noSync ){ -// assert( pPager->fullSync==0 ); -// assert( pPager->extraSync==0 ); -// assert( pPager->syncFlags==0 ); -// assert( pPager->walSyncFlags==0 ); -// }else{ -// pPager->fullSync = 1; -// pPager->extraSync = 0; -// pPager->syncFlags = SQLITE_SYNC_NORMAL; -// pPager->walSyncFlags = SQLITE_SYNC_NORMAL | (SQLITE_SYNC_NORMAL<<2); -// } -// /* pPager->pFirst = 0; */ -// /* pPager->pFirstSynced = 0; */ -// /* pPager->pLast = 0; */ -// pPager->nExtra = (u16)nExtra; -// pPager->journalSizeLimit = SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT; -// assert( isOpen(pPager->fd) || tempFile ); -// setSectorSize(pPager); -// if( !useJournal ){ -// pPager->journalMode = PAGER_JOURNALMODE_OFF; -// }else if( memDb || memJM ){ -// pPager->journalMode = PAGER_JOURNALMODE_MEMORY; -// } -// /* pPager->xBusyHandler = 0; */ -// /* pPager->pBusyHandlerArg = 0; */ -// pPager->xReiniter = xReinit; -// setGetterMethod(pPager); -// /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */ -// /* pPager->szMmap = SQLITE_DEFAULT_MMAP_SIZE // will be set by btree.c */ - -// *ppPager = pPager; -// return SQLITE_OK; -// } + // *ppPager = pPager; + return SQLITE_OK; +} // /* // ** Return the sqlite3_file for the main database given the name @@ -5033,11 +5020,10 @@ // return pPager->fd; // } - // /* // ** This function is called after transitioning from PAGER_UNLOCK to // ** PAGER_SHARED state. It tests if there is a hot journal present in -// ** the file-system for the given pager. A hot journal is one that +// ** the file-system for the given pager. A hot journal is one that // ** needs to be played back. According to this function, a hot-journal // ** file exists if the following criteria are met: // ** @@ -5056,10 +5042,10 @@ // ** at the end of the file. If there is, and that super-journal file // ** does not exist, then the journal file is not really hot. In this // ** case this routine will return a false-positive. The pager_playback() -// ** routine will discover that the journal file is not really hot and -// ** will not roll it back. +// ** routine will discover that the journal file is not really hot and +// ** will not roll it back. // ** -// ** If a hot-journal file is found to exist, *pExists is set to 1 and +// ** If a hot-journal file is found to exist, *pExists is set to 1 and // ** SQLITE_OK returned. If no hot-journal file is present, *pExists is // ** set to 0 and SQLITE_OK returned. If an IO error occurs while trying // ** to determine whether or not a hot-journal file exists, the IO error @@ -5087,7 +5073,7 @@ // int locked = 0; /* True if some process holds a RESERVED lock */ // /* Race condition here: Another process might have been holding the -// ** the RESERVED lock and have a journal open at the sqlite3OsAccess() +// ** the RESERVED lock and have a journal open at the sqlite3OsAccess() // ** call above, but then delete the journal and drop the lock before // ** we get to the following sqlite3OsCheckReservedLock() call. If that // ** is the case, this routine might think there is a hot journal when @@ -5120,7 +5106,7 @@ // /* The journal file exists and no other connection has a reserved // ** or greater lock on the database file. Now check that there is // ** at least one non-zero bytes at the start of the journal file. -// ** If there is, then we consider this journal to be hot. If not, +// ** If there is, then we consider this journal to be hot. If not, // ** it can be ignored. // */ // if( !jrnlOpen ){ @@ -5170,7 +5156,7 @@ // ** on the database file), then an attempt is made to obtain a // ** SHARED lock on the database file. Immediately after obtaining // ** the SHARED lock, the file-system is checked for a hot-journal, -// ** which is played back if present. Following any hot-journal +// ** which is played back if present. Following any hot-journal // ** rollback, the contents of the cache are validated by checking // ** the 'change-counter' field of the database file header and // ** discarded if they are found to be invalid. @@ -5181,8 +5167,8 @@ // ** the contents of the page cache and rolling back any open journal // ** file. // ** -// ** If everything is successful, SQLITE_OK is returned. If an IO error -// ** occurs while locking the database, checking for a hot-journal file or +// ** If everything is successful, SQLITE_OK is returned. If an IO error +// ** occurs while locking the database, checking for a hot-journal file or // ** rolling back a journal file, the IO error code is returned. // */ // int sqlite3PagerSharedLock(Pager *pPager){ @@ -5190,7 +5176,7 @@ // /* This routine is only called from b-tree and only when there are no // ** outstanding pages. This implies that the pager state should either -// ** be OPEN or READER. READER is only possible if the pager is or was in +// ** be OPEN or READER. READER is only possible if the pager is or was in // ** exclusive access mode. */ // assert( sqlite3PcacheRefCount(pPager->pPCache)==0 ); // assert( assert_pager_state(pPager) ); @@ -5228,12 +5214,12 @@ // ** 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 the +// ** database is safe to read while this process is still rolling the // ** hot-journal back. -// ** +// ** // ** Because the intermediate RESERVED lock is not requested, any -// ** other process attempting to access the database file will get to -// ** this point in the code and fail to obtain its own EXCLUSIVE lock +// ** other process attempting to access the database file will get to +// ** this point in the code and fail to obtain its own EXCLUSIVE lock // ** on the database file. // ** // ** Unless the pager is in locking_mode=exclusive mode, the lock is @@ -5243,17 +5229,17 @@ // if( rc!=SQLITE_OK ){ // goto failed; // } - -// /* If it is not already open and the file exists on disk, open the -// ** journal for read/write access. Write access is required because -// ** in exclusive-access mode the file descriptor will be kept open -// ** and possibly used for a transaction later on. Also, write-access -// ** is usually required to finalize the journal in journal_mode=persist + +// /* If it is not already open and the file exists on disk, open the +// ** journal for read/write access. Write access is required because +// ** in exclusive-access mode the file descriptor will be kept open +// ** and possibly used for a transaction later on. Also, write-access +// ** is usually required to finalize the journal in journal_mode=persist // ** mode (and also for journal_mode=truncate on some systems). // ** -// ** If the journal does not exist, it usually means that some -// ** other connection managed to get in and roll it back before -// ** this connection obtained the exclusive lock above. Or, it +// ** If the journal does not exist, it usually means that some +// ** other connection managed to get in and roll it back before +// ** this connection obtained the exclusive lock above. Or, it // ** may mean that the pager was in the error-state when this // ** function was called and the journal file does not exist. // */ @@ -5274,7 +5260,7 @@ // } // } // } - + // /* Playback and delete the journal. Drop the database write // ** lock and reacquire the read lock. Purge the cache before // ** playing back the hot-journal so that we don't end up with @@ -5299,8 +5285,8 @@ // ** or roll back a hot-journal while holding an EXCLUSIVE lock. The // ** pager_unlock() routine will be called before returning to unlock // ** the file. If the unlock attempt fails, then Pager.eLock must be -// ** set to UNKNOWN_LOCK (see the comment above the #define for -// ** UNKNOWN_LOCK above for an explanation). +// ** set to UNKNOWN_LOCK (see the comment above the #define for +// ** UNKNOWN_LOCK above for an explanation). // ** // ** In order to get pager_unlock() to do this, set Pager.eState to // ** PAGER_ERROR now. This is not actually counted as a transition @@ -5308,7 +5294,7 @@ // ** since we know that the same call to pager_unlock() will very // ** shortly transition the pager object to the OPEN state. Calling // ** assert_pager_state() would fail now, as it should not be possible -// ** to be in ERROR state when there are zero outstanding page +// ** to be in ERROR state when there are zero outstanding page // ** references. // */ // pager_error(pPager, rc); @@ -5333,8 +5319,8 @@ // ** 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 +// ** +// ** 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. // */ @@ -5401,7 +5387,7 @@ // ** Except, in locking_mode=EXCLUSIVE when there is nothing to in // ** the rollback journal, the unlock is not performed and there is // ** nothing to rollback, so this routine is a no-op. -// */ +// */ // static void pagerUnlockIfUnused(Pager *pPager){ // if( sqlite3PcacheRefCount(pPager->pPCache)==0 ){ // assert( pPager->nMmapOut==0 ); /* because page1 is never memory mapped */ @@ -5411,7 +5397,7 @@ // /* // ** The page getter methods each try to acquire a reference to a -// ** page with page number pgno. If the requested reference is +// ** page with page number pgno. If the requested reference is // ** successfully obtained, it is copied to *ppPage and SQLITE_OK returned. // ** // ** There are different implementations of the getter method depending @@ -5421,22 +5407,22 @@ // ** getPageError() -- Used if the pager is in an error state // ** getPageMmap() -- Used if memory-mapped I/O is enabled // ** -// ** If the requested page is already in the cache, it is returned. +// ** If the requested page is already in the cache, it is returned. // ** Otherwise, a new page object is allocated and populated with data // ** read from the database file. In some cases, the pcache module may // ** choose not to allocate a new page object and may reuse an existing // ** object with no outstanding references. // ** -// ** The extra data appended to a page is always initialized to zeros the -// ** first time a page is loaded into memory. If the page requested is +// ** The extra data appended to a page is always initialized to zeros the +// ** first time a page is loaded into memory. If the page requested is // ** already in the cache when this function is called, then the extra // ** data is left as it was when the page object was last used. // ** -// ** If the database image is smaller than the requested page or if -// ** the flags parameter contains the PAGER_GET_NOCONTENT bit and the -// ** requested page is not already stored in the cache, then no -// ** actual disk read occurs. In this case the memory image of the -// ** page is initialized to all zeros. +// ** If the database image is smaller than the requested page or if +// ** the flags parameter contains the PAGER_GET_NOCONTENT bit and the +// ** requested page is not already stored in the cache, then no +// ** actual disk read occurs. In this case the memory image of the +// ** page is initialized to all zeros. // ** // ** If PAGER_GET_NOCONTENT is true, it means that we do not care about // ** the contents of the page. This occurs in two scenarios: @@ -5507,7 +5493,7 @@ // return SQLITE_OK; // }else{ -// /* The pager cache has created a new page. Its content needs to +// /* The pager cache has created a new page. Its content needs to // ** be initialized. But first some error checks: // ** // ** (*) obsolete. Was: maximum page number is 2^31 @@ -5528,9 +5514,9 @@ // } // if( noContent ){ // /* Failure to set the bits in the InJournal bit-vectors is benign. -// ** It merely means that we might do some extra work to journal a -// ** page that does not need to be journaled. Nevertheless, be sure -// ** to test the case where a malloc error occurs while trying to set +// ** It merely means that we might do some extra work to journal a +// ** page that does not need to be journaled. Nevertheless, be sure +// ** to test the case where a malloc error occurs while trying to set // ** a bit in a bit vector. // */ // sqlite3BeginBenignMalloc(); @@ -5580,7 +5566,7 @@ // /* It is acceptable to use a read-only (mmap) page for any page except // ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY -// ** flag was specified by the caller. And so long as the db is not a +// ** flag was specified by the caller. And so long as the db is not a // ** temporary or in-memory database. */ // const int bMmapOk = (pgno>1 // && (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY)) @@ -5609,7 +5595,7 @@ // } // if( bMmapOk && iFrame==0 ){ // void *pData = 0; -// rc = sqlite3OsFetch(pPager->fd, +// rc = sqlite3OsFetch(pPager->fd, // (i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData // ); // if( rc==SQLITE_OK && pData ){ @@ -5650,7 +5636,6 @@ // return pPager->errCode; // } - // /* Dispatch all page fetch requests to the appropriate getter method. // */ // int sqlite3PagerGet( @@ -5665,12 +5650,12 @@ // /* // ** Acquire a page if it is already in the in-memory cache. Do // ** not read the page from disk. Return a pointer to the page, -// ** or 0 if the page is not in cache. +// ** or 0 if the page is not in cache. // ** // ** See also sqlite3PagerGet(). The difference between this routine // ** and sqlite3PagerGet() is that _get() will go to the disk and read // ** in the page if the page is not already in cache. This routine -// ** returns NULL if the page is not in cache or if a disk I/O error +// ** returns NULL if the page is not in cache or if a disk I/O error // ** has ever happened. // */ // DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){ @@ -5723,24 +5708,24 @@ // /* // ** This function is called at the start of every write transaction. -// ** There must already be a RESERVED or EXCLUSIVE lock on the database +// ** There must already be a RESERVED or EXCLUSIVE lock on the database // ** file when this routine is called. // ** // ** Open the journal file for pager pPager and write a journal header // ** to the start of it. If there are active savepoints, open the sub-journal -// ** as well. This function is only used when the journal file is being -// ** opened to write a rollback log for a transaction. It is not used +// ** as well. This function is only used when the journal file is being +// ** opened to write a rollback log for a transaction. It is not used // ** when opening a hot journal file to roll it back. // ** // ** If the journal file is already open (as it may be in exclusive mode), // ** then this function just writes a journal header to the start of the -// ** already open file. +// ** already open file. // ** // ** Whether or not the journal file is opened by this function, the // ** Pager.pInJournal bitvec structure is allocated. // ** -// ** Return SQLITE_OK if everything is successful. Otherwise, return -// ** SQLITE_NOMEM if the attempt to allocate Pager.pInJournal fails, or +// ** Return SQLITE_OK if everything is successful. Otherwise, return +// ** SQLITE_NOMEM if the attempt to allocate Pager.pInJournal fails, or // ** an IO error code if opening or writing the journal file fails. // */ // static int pager_open_journal(Pager *pPager){ @@ -5750,7 +5735,7 @@ // assert( pPager->eState==PAGER_WRITER_LOCKED ); // assert( assert_pager_state(pPager) ); // assert( pPager->pInJournal==0 ); - + // /* If already in the error state, this function is a no-op. But on // ** the other hand, this routine is never called if we are already in // ** an error state. */ @@ -5761,7 +5746,7 @@ // if( pPager->pInJournal==0 ){ // return SQLITE_NOMEM; // } - + // /* Open the journal file if it is not already open. */ // if( !isOpen(pPager->jfd) ){ // if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){ @@ -5777,7 +5762,7 @@ // flags |= SQLITE_OPEN_MAIN_JOURNAL; // nSpill = jrnlBufferSize(pPager); // } - + // /* Verify that the database still has the same name as it did when // ** it was originally opened. */ // rc = databaseIsUnmoved(pPager); @@ -5789,9 +5774,8 @@ // } // assert( rc!=SQLITE_OK || isOpen(pPager->jfd) ); // } - - -// /* Write the first journal header to the journal file and open + +// /* Write the first journal header to the journal file and open // ** the sub-journal if necessary. // */ // if( rc==SQLITE_OK ){ @@ -5816,12 +5800,12 @@ // } // /* -// ** Begin a write-transaction on the specified pager object. If a +// ** Begin a write-transaction on the specified pager object. If a // ** write-transaction has already been opened, this function is a no-op. // ** // ** If the exFlag argument is false, then acquire at least a RESERVED // ** lock on the database file. If exFlag is true, then acquire at least -// ** an EXCLUSIVE lock. If such a lock is already held, no locking +// ** an EXCLUSIVE lock. If such a lock is already held, no locking // ** functions need be called. // ** // ** If the subjInMemory argument is non-zero, then any sub-journal opened @@ -5829,7 +5813,7 @@ // ** has no effect if the sub-journal is already opened (as it may be when // ** running in exclusive mode) or if the transaction does not require a // ** sub-journal. If the subjInMemory argument is zero, then any required -// ** sub-journal is implemented in-memory if pPager is an in-memory database, +// ** sub-journal is implemented in-memory if pPager is an in-memory database, // ** or using a temporary file otherwise. // */ // int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory){ @@ -5877,9 +5861,9 @@ // ** // ** WAL mode sets Pager.eState to PAGER_WRITER_LOCKED or CACHEMOD // ** when it has an open transaction, but never to DBMOD or FINISHED. -// ** This is because in those states the code to roll back savepoint -// ** transactions may copy data from the sub-journal into the database -// ** file as well as into the page cache. Which would be incorrect in +// ** This is because in those states the code to roll back savepoint +// ** transactions may copy data from the sub-journal into the database +// ** file as well as into the page cache. Which would be incorrect in // ** WAL mode. // */ // pPager->eState = PAGER_WRITER_LOCKED; @@ -5933,11 +5917,11 @@ // rc = write32bits(pPager->jfd, iOff+pPager->pageSize+4, cksum); // if( rc!=SQLITE_OK ) return rc; -// IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno, +// IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno, // pPager->journalOff, pPager->pageSize)); // PAGER_INCR(sqlite3_pager_writej_count); // PAGERTRACE(("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))); // pPager->journalOff += 8 + pPager->pageSize; @@ -5952,9 +5936,9 @@ // } // /* -// ** Mark a single data page as writeable. The page is written into the +// ** Mark a single data page as writeable. The page is written into the // ** main journal or sub-journal as required. If the page is written into -// ** one of the journals, the corresponding bit is set in the +// ** one of the journals, the corresponding bit is set in the // ** Pager.pInJournal bitvec and the PagerSavepoint.pInSavepoint bitvecs // ** of any open savepoints as appropriate. // */ @@ -5962,7 +5946,7 @@ // Pager *pPager = pPg->pPager; // int rc = SQLITE_OK; -// /* This routine is not called unless a write-transaction has already +// /* This routine is not called unless a write-transaction has already // ** been started. The journal file may or may not be open at this point. // ** It is never called in the ERROR state. // */ @@ -5979,7 +5963,7 @@ // ** obtained the necessary locks to begin the write-transaction, but the // ** rollback journal might not yet be open. Open it now if this is the case. // ** -// ** This is done before calling sqlite3PcacheMakeDirty() on the page. +// ** This is done before calling sqlite3PcacheMakeDirty() on the page. // ** Otherwise, if it were done after calling sqlite3PcacheMakeDirty(), then // ** an error might occur and the pager would end up in WRITER_LOCKED state // ** with pages marked as dirty in the cache. @@ -6024,7 +6008,7 @@ // ** PGHDR_WRITEABLE bit that indicates that the page can be safely modified. // */ // pPg->flags |= PGHDR_WRITEABLE; - + // /* If the statement journal is open and the page is not in it, // ** then write the page into the statement journal. // */ @@ -6108,7 +6092,7 @@ // } // } -// /* If the PGHDR_NEED_SYNC flag is set for any of the nPage pages +// /* If the PGHDR_NEED_SYNC flag is set for any of the nPage pages // ** starting at pg1, then it needs to be set for all of them. Because // ** writing to any of these nPage pages may damage the others, the // ** journal file must contain sync()ed copies of all of them @@ -6131,9 +6115,9 @@ // } // /* -// ** Mark a data page as writeable. This routine must be called before -// ** making changes to a page. The caller must check the return value -// ** of this function and be careful not to change any page data unless +// ** Mark a data page as writeable. This routine must be called before +// ** making changes to a page. The caller must check the return value +// ** of this function and be careful not to change any page data unless // ** this routine returns SQLITE_OK. // ** // ** The difference between this function and pager_write() is that this @@ -6184,13 +6168,13 @@ // ** on the given page is unused. The pager marks the page as clean so // ** that it does not get written to disk. // ** -// ** Tests show that this optimization can quadruple the speed of large +// ** Tests show that this optimization can quadruple the speed of large // ** DELETE operations. // ** // ** This optimization cannot be used with a temp-file, as the page may // ** have been dirty at the start of the transaction. In that case, if -// ** memory pressure forces page pPg out of the cache, the data does need -// ** to be written out to disk so that it may be read back in if the +// ** memory pressure forces page pPg out of the cache, the data does need +// ** to be written out to disk so that it may be read back in if the // ** current transaction is rolled back. // */ // void sqlite3PagerDontWrite(PgHdr *pPg){ @@ -6206,17 +6190,17 @@ // } // /* -// ** This routine is called to increment the value of the database file -// ** change-counter, stored as a 4-byte big-endian integer starting at +// ** This routine is called to increment the value of the database file +// ** change-counter, stored as a 4-byte big-endian integer starting at // ** byte offset 24 of the pager file. The secondary change counter at // ** 92 is also updated, as is the SQLite version number at offset 96. // ** // ** But this only happens if the pPager->changeCountDone flag is false. // ** To avoid excess churning of page 1, the update only happens once. -// ** See also the pager_write_changecounter() routine that does an +// ** See also the pager_write_changecounter() routine that does an // ** unconditional update of the change counters. // ** -// ** If the isDirectMode flag is zero, then this is done by calling +// ** If the isDirectMode flag is zero, then this is done by calling // ** sqlite3PagerWrite() on page 1, then modifying the contents of the // ** page data. In this case the file will be updated when the current // ** transaction is committed. @@ -6224,7 +6208,7 @@ // ** The isDirectMode flag may only be non-zero if the library was compiled // ** with the SQLITE_ENABLE_ATOMIC_WRITE macro defined. In this case, // ** if isDirect is non-zero, then the database file is updated directly -// ** by writing an updated version of page 1 using a call to the +// ** by writing an updated version of page 1 using a call to the // ** sqlite3OsWrite() function. // */ // static int pager_incr_changecounter(Pager *pPager, int isDirectMode){ @@ -6263,7 +6247,7 @@ // assert( pPgHdr==0 || rc==SQLITE_OK ); // /* If page one was fetched successfully, and this function is not -// ** operating in direct-mode, make page 1 writable. When not in +// ** operating in direct-mode, make page 1 writable. When not in // ** direct mode, page 1 is always held in cache and hence the PagerGet() // ** above is always successful - hence the ALWAYS on rc==SQLITE_OK. // */ @@ -6324,22 +6308,22 @@ // /* // ** This function may only be called while a write-transaction is active in -// ** rollback. If the connection is in WAL mode, this call is a no-op. -// ** Otherwise, if the connection does not already have an EXCLUSIVE lock on +// ** rollback. If the connection is in WAL mode, this call is a no-op. +// ** Otherwise, if the connection does not already have an EXCLUSIVE lock on // ** the database file, an attempt is made to obtain one. // ** // ** If the EXCLUSIVE lock is already held or the attempt to obtain it is // ** successful, or the connection is in WAL mode, SQLITE_OK is returned. -// ** Otherwise, either SQLITE_BUSY or an SQLITE_IOERR_XXX error code is +// ** Otherwise, either SQLITE_BUSY or an SQLITE_IOERR_XXX error code is // ** returned. // */ // int sqlite3PagerExclusiveLock(Pager *pPager){ // int rc = pPager->errCode; // assert( assert_pager_state(pPager) ); // if( rc==SQLITE_OK ){ -// assert( pPager->eState==PAGER_WRITER_CACHEMOD -// || pPager->eState==PAGER_WRITER_DBMOD -// || pPager->eState==PAGER_WRITER_LOCKED +// assert( pPager->eState==PAGER_WRITER_CACHEMOD +// || pPager->eState==PAGER_WRITER_DBMOD +// || pPager->eState==PAGER_WRITER_LOCKED // ); // assert( assert_pager_state(pPager) ); // if( 0==pagerUseWal(pPager) ){ @@ -6352,19 +6336,19 @@ // /* // ** Sync the database file for the pager pPager. zSuper points to the name // ** of a super-journal file that should be written into the individual -// ** journal file. zSuper may be NULL, which is interpreted as no +// ** journal file. zSuper may be NULL, which is interpreted as no // ** super-journal (a single database transaction). // ** // ** This routine ensures that: // ** // ** * The database file change-counter is updated, // ** * the journal is synced (unless the atomic-write optimization is used), -// ** * all dirty pages are written to the database file, +// ** * all dirty pages are written to the database file, // ** * the database file is truncated (if required), and -// ** * the database file synced. +// ** * the database file synced. // ** -// ** The only thing that remains to commit the transaction is to finalize -// ** (delete, truncate or zero the first part of) the journal file (or +// ** The only thing that remains to commit the transaction is to finalize +// ** (delete, truncate or zero the first part of) the journal file (or // ** delete the super-journal file if specified). // ** // ** Note that if zSuper==NULL, this does not overwrite a previous value @@ -6395,7 +6379,7 @@ // /* Provide the ability to easily simulate an I/O error during testing */ // if( sqlite3FaultSim(400) ) return SQLITE_IOERR; -// PAGERTRACE(("DATABASE SYNC: File=%s zSuper=%s nSize=%d\n", +// PAGERTRACE(("DATABASE SYNC: File=%s zSuper=%s nSize=%d\n", // pPager->zFilename, zSuper, pPager->dbSize)); // /* If no database changes have been made, return early. */ @@ -6446,11 +6430,11 @@ // #ifdef SQLITE_ENABLE_ATOMIC_WRITE // /* The following block updates the change-counter. Exactly how it // ** does this depends on whether or not the atomic-update optimization -// ** was enabled at compile time, and if this transaction meets the -// ** runtime criteria to use the operation: +// ** was enabled at compile time, and if this transaction meets the +// ** runtime criteria to use the operation: // ** // ** * The file-system supports the atomic-write property for -// ** blocks of size page-size, and +// ** blocks of size page-size, and // ** * This commit is not part of a multi-file transaction, and // ** * Exactly one page has been modified and store in the journal file. // ** @@ -6460,7 +6444,7 @@ // ** is not applicable to this transaction, call sqlite3JournalCreate() // ** to make sure the journal file has actually been created, then call // ** pager_incr_changecounter() to update the change-counter in indirect -// ** mode. +// ** mode. // ** // ** Otherwise, if the optimization is both enabled and applicable, // ** then call pager_incr_changecounter() to update the change-counter @@ -6469,19 +6453,19 @@ // */ // if( bBatch==0 ){ // PgHdr *pPg; -// assert( isOpen(pPager->jfd) -// || pPager->journalMode==PAGER_JOURNALMODE_OFF -// || pPager->journalMode==PAGER_JOURNALMODE_WAL +// assert( isOpen(pPager->jfd) +// || pPager->journalMode==PAGER_JOURNALMODE_OFF +// || pPager->journalMode==PAGER_JOURNALMODE_WAL // ); -// if( !zSuper && isOpen(pPager->jfd) -// && pPager->journalOff==jrnlBufferSize(pPager) +// if( !zSuper && isOpen(pPager->jfd) +// && pPager->journalOff==jrnlBufferSize(pPager) // && pPager->dbSize>=pPager->dbOrigSize // && (!(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty) // ){ -// /* Update the db file change counter via the direct-write method. The -// ** following call will modify the in-memory representation of page 1 -// ** to include the updated change counter and then write page 1 -// ** directly to the database file. Because of the atomic-write +// /* Update the db file change counter via the direct-write method. The +// ** following call will modify the in-memory representation of page 1 +// ** to include the updated change counter and then write page 1 +// ** directly to the database file. Because of the atomic-write // ** property of the host file-system, this is safe. // */ // rc = pager_incr_changecounter(pPager, 1); @@ -6503,24 +6487,24 @@ // rc = pager_incr_changecounter(pPager, 0); // #endif /* !SQLITE_ENABLE_ATOMIC_WRITE */ // if( rc!=SQLITE_OK ) goto commit_phase_one_exit; - + // /* Write the super-journal name into the journal file. If a -// ** super-journal file name has already been written to the journal file, +// ** super-journal file name has already been written to the journal file, // ** or if zSuper is NULL (no super-journal), then this call is a no-op. // */ // rc = writeSuperJournal(pPager, zSuper); // if( rc!=SQLITE_OK ) goto commit_phase_one_exit; - + // /* Sync the journal file and write all dirty pages to the database. -// ** If the atomic-update optimization is being used, this sync will not +// ** If the atomic-update optimization is being used, this sync will not // ** create the journal file or perform any real IO. // ** // ** Because the change-counter page was just modified, unless the // ** atomic-update optimization is used it is almost certain that the // ** journal requires a sync here. However, in locking_mode=exclusive -// ** on a system under memory pressure it is just possible that this is +// ** on a system under memory pressure it is just possible that this is // ** not the case. In this case it is likely enough that the redundant -// ** xSync() call will be changed to a no-op by the OS anyhow. +// ** xSync() call will be changed to a no-op by the OS anyhow. // */ // rc = syncJournal(pPager, 0); // if( rc!=SQLITE_OK ) goto commit_phase_one_exit; @@ -6561,7 +6545,7 @@ // } // sqlite3PcacheCleanAll(pPager->pPCache); -// /* If the file on disk is smaller than the database image, use +// /* If the file on disk is smaller than the database image, use // ** pager_truncate to grow the file here. This can happen if the database // ** image was extended as part of the current transaction and then the // ** last page in the db image moved to the free-list. In this case the @@ -6573,7 +6557,7 @@ // rc = pager_truncate(pPager, nNew); // if( rc!=SQLITE_OK ) goto commit_phase_one_exit; // } - + // /* Finally, sync the database file. */ // if( !noSync ){ // rc = sqlite3PagerSync(pPager, zSuper); @@ -6589,16 +6573,15 @@ // return rc; // } - // /* // ** When this function is called, the database file has been completely // ** updated to reflect the changes made by the current transaction and -// ** synced to disk. The journal file still exists in the file-system +// ** synced to disk. The journal file still exists in the file-system // ** though, and if a failure occurs at this point it will eventually // ** be used as a hot-journal and the current transaction rolled back. // ** -// ** This function finalizes the journal file, either by deleting, -// ** truncating or partially zeroing it, so that it cannot be used +// ** This function finalizes the journal file, either by deleting, +// ** truncating or partially zeroing it, so that it cannot be used // ** for hot-journal rollback. Once this is done the transaction is // ** irrevocably committed. // ** @@ -6624,15 +6607,15 @@ // ** this transaction, the pager is running in exclusive-mode and is // ** using persistent journals, then this function is a no-op. // ** -// ** The start of the journal file currently contains a single journal +// ** The start of the journal file currently contains a single journal // ** header with the nRec field set to 0. If such a journal is used as // ** a hot-journal during hot-journal rollback, 0 changes will be made -// ** to the database file. So there is no need to zero the journal +// ** to the database file. So there is no need to zero the journal // ** header. Since the pager is in exclusive mode, there is no need // ** to drop any locks either. // */ -// if( pPager->eState==PAGER_WRITER_LOCKED -// && pPager->exclusiveMode +// if( pPager->eState==PAGER_WRITER_LOCKED +// && pPager->exclusiveMode // && pPager->journalMode==PAGER_JOURNALMODE_PERSIST // ){ // assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) || !pPager->journalOff ); @@ -6646,7 +6629,7 @@ // } // /* -// ** If a write transaction is open, then all changes made within the +// ** If a write transaction is open, then all changes made within the // ** transaction are reverted and the current write-transaction is closed. // ** The pager falls back to PAGER_READER state if successful, or PAGER_ERROR // ** state if an error occurs. @@ -6656,14 +6639,14 @@ // ** // ** Otherwise, in rollback mode, this function performs two functions: // ** -// ** 1) It rolls back the journal file, restoring all database file and +// ** 1) It rolls back the journal file, restoring all database file and // ** in-memory cache pages to the state they were in when the transaction // ** was opened, and // ** // ** 2) It finalizes the journal file, so that it is not used for hot // ** rollback at any point in the future. // ** -// ** Finalization of the journal file (task 2) is only performed if the +// ** Finalization of the journal file (task 2) is only performed if the // ** rollback is successful. // ** // ** In WAL mode, all cache-entries containing data modified within the @@ -6676,7 +6659,7 @@ // PAGERTRACE(("ROLLBACK %d\n", PAGERID(pPager))); // /* PagerRollback() is a no-op if called in READER or OPEN state. If -// ** the pager is already in the ERROR state, the rollback is not +// ** the pager is already in the ERROR state, the rollback is not // ** attempted here. Instead, the error code is returned to the caller. // */ // assert( assert_pager_state(pPager) ); @@ -6692,7 +6675,7 @@ // int eState = pPager->eState; // rc = pager_end_transaction(pPager, 0, 0); // if( !MEMDB && eState>PAGER_WRITER_LOCKED ){ -// /* This can happen using journal_mode=off. Move the pager to the error +// /* This can happen using journal_mode=off. Move the pager to the error // ** state to indicate that the contents of the cache may not be trusted. // ** Any active readers will get SQLITE_ABORT. // */ @@ -6707,7 +6690,7 @@ // assert( pPager->eState==PAGER_READER || rc!=SQLITE_OK ); // assert( rc==SQLITE_OK || rc==SQLITE_FULL || rc==SQLITE_CORRUPT -// || rc==SQLITE_NOMEM || (rc&0xFF)==SQLITE_IOERR +// || rc==SQLITE_NOMEM || (rc&0xFF)==SQLITE_IOERR // || rc==SQLITE_CANTOPEN // ); @@ -6781,8 +6764,8 @@ // ** it was added later. // ** // ** Before returning, *pnVal is incremented by the -// ** current cache hit or miss count, according to the value of eStat. If the -// ** reset parameter is non-zero, the cache hit or miss count is zeroed before +// ** current cache hit or miss count, according to the value of eStat. If the +// ** reset parameter is non-zero, the cache hit or miss count is zeroed before // ** returning. // */ // void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, int *pnVal){ @@ -6818,7 +6801,7 @@ // ** to make up the difference. If the number of savepoints is already // ** equal to nSavepoint, then this function is a no-op. // ** -// ** If a memory allocation fails, SQLITE_NOMEM is returned. If an error +// ** If a memory allocation fails, SQLITE_NOMEM is returned. If an error // ** occurs while opening the sub-journal file, then an IO error code is // ** returned. Otherwise, SQLITE_OK. // */ @@ -6833,7 +6816,7 @@ // assert( nSavepoint>nCurrent && pPager->useJournal ); // /* Grow the Pager.aSavepoint array using realloc(). Return SQLITE_NOMEM -// ** if the allocation fails. Otherwise, zero the new portion in case a +// ** if the allocation fails. Otherwise, zero the new portion in case a // ** malloc failure occurs while populating it in the for(...) loop below. // */ // aNew = (PagerSavepoint *)sqlite3Realloc( @@ -6879,10 +6862,9 @@ // } // } - // /* // ** This function is called to rollback or release (commit) a savepoint. -// ** The savepoint to release or rollback need not be the most recently +// ** The savepoint to release or rollback need not be the most recently // ** created savepoint. // ** // ** Parameter op is always either SAVEPOINT_ROLLBACK or SAVEPOINT_RELEASE. @@ -6890,29 +6872,29 @@ // ** index iSavepoint. If it is SAVEPOINT_ROLLBACK, then rollback all changes // ** that have occurred since the specified savepoint was created. // ** -// ** The savepoint to rollback or release is identified by parameter +// ** The savepoint to rollback or release is identified by parameter // ** iSavepoint. A value of 0 means to operate on the outermost savepoint // ** (the first created). A value of (Pager.nSavepoint-1) means operate // ** on the most recently created savepoint. If iSavepoint is greater than // ** (Pager.nSavepoint-1), then this function is a no-op. // ** // ** If a negative value is passed to this function, then the current -// ** transaction is rolled back. This is different to calling +// ** transaction is rolled back. This is different to calling // ** sqlite3PagerRollback() because this function does not terminate -// ** the transaction or unlock the database, it just restores the -// ** contents of the database to its original state. +// ** the transaction or unlock the database, it just restores the +// ** contents of the database to its original state. // ** -// ** In any case, all savepoints with an index greater than iSavepoint +// ** In any case, all savepoints with an index greater than iSavepoint // ** are destroyed. If this is a release operation (op==SAVEPOINT_RELEASE), // ** then savepoint iSavepoint is also destroyed. // ** // ** This function may return SQLITE_NOMEM if a memory allocation fails, -// ** or an IO error code if an IO error occurs while rolling back a +// ** or an IO error code if an IO error occurs while rolling back a // ** savepoint. If no errors occur, SQLITE_OK is returned. -// */ +// */ // int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){ // int rc = pPager->errCode; - + // #ifdef SQLITE_ENABLE_ZIPVFS // if( op==SAVEPOINT_RELEASE ) rc = SQLITE_OK; // #endif @@ -6925,7 +6907,7 @@ // int nNew; /* Number of remaining savepoints after this op. */ // /* Figure out how many savepoints will still be active after this -// ** operation. Store this value in nNew. Then free resources associated +// ** operation. Store this value in nNew. Then free resources associated // ** with any savepoints that are destroyed by this operation. // */ // nNew = iSavepoint + (( op==SAVEPOINT_RELEASE ) ? 0 : 1); @@ -6958,14 +6940,14 @@ // rc = pagerPlaybackSavepoint(pPager, pSavepoint); // assert(rc!=SQLITE_DONE); // } - + // #ifdef SQLITE_ENABLE_ZIPVFS -// /* If the cache has been modified but the savepoint cannot be rolled +// /* If the cache has been modified but the savepoint cannot be rolled // ** back journal_mode=off, put the pager in the error state. This way, // ** if the VFS used by this pager includes ZipVFS, the entire transaction // ** can be rolled back at the ZipVFS level. */ -// else if( -// pPager->journalMode==PAGER_JOURNALMODE_OFF +// else if( +// pPager->journalMode==PAGER_JOURNALMODE_OFF // && pPager->eState>=PAGER_WRITER_CACHEMOD // ){ // pPager->errCode = SQLITE_ABORT; @@ -7050,8 +7032,8 @@ // ** transaction is active). // ** // ** If the fourth argument, isCommit, is non-zero, then this page is being -// ** moved as part of a database reorganization just before the transaction -// ** is being committed. In this case, it is guaranteed that the database page +// ** moved as part of a database reorganization just before the transaction +// ** is being committed. In this case, it is guaranteed that the database page // ** pPg refers to will not be written to again within this transaction. // ** // ** This function may return SQLITE_NOMEM or an IO error code if an error @@ -7079,7 +7061,7 @@ // } // /* If the page being moved is dirty and has not been saved by the latest -// ** savepoint, then save the current contents of the page into the +// ** savepoint, then save the current contents of the page into the // ** sub-journal now. This is required to handle the following scenario: // ** // ** BEGIN; @@ -7102,7 +7084,7 @@ // return rc; // } -// PAGERTRACE(("MOVE %d page %d (needSync=%d) moves to %d\n", +// PAGERTRACE(("MOVE %d page %d (needSync=%d) moves to %d\n", // PAGERID(pPager), pPg->pgno, (pPg->flags&PGHDR_NEED_SYNC)?1:0, pgno)); // IOTRACE(("MOVE %p %d %d\n", pPager, pPg->pgno, pgno)) @@ -7110,7 +7092,7 @@ // ** be written to, store pPg->pgno in local variable needSyncPgno. // ** // ** If the isCommit flag is set, there is no need to remember that -// ** the journal needs to be sync()ed before database page pPg->pgno +// ** the journal needs to be sync()ed before database page pPg->pgno // ** can be written to. The caller has already promised not to write to it. // */ // if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){ @@ -7121,8 +7103,8 @@ // } // /* If the cache contains a page with page-number pgno, remove it -// ** from its hash chain. Also, if the PGHDR_NEED_SYNC flag was set for -// ** page pgno before the 'move' operation, it needs to be retained +// ** from its hash chain. Also, if the PGHDR_NEED_SYNC flag was set for +// ** page pgno before the 'move' operation, it needs to be retained // ** for the page moved there. // */ // pPg->flags &= ~PGHDR_NEED_SYNC; @@ -7157,9 +7139,9 @@ // } // if( needSyncPgno ){ -// /* If needSyncPgno is non-zero, then the journal file needs to be +// /* If needSyncPgno is non-zero, then the journal file needs to be // ** sync()ed before any data is written to database file page needSyncPgno. -// ** Currently, no such page exists in the page-cache and the +// ** Currently, no such page exists in the page-cache and the // ** "is journaled" bitvec flag has been set. This needs to be remedied by // ** loading the page into the pager-cache and setting the PGHDR_NEED_SYNC // ** flag. @@ -7190,9 +7172,9 @@ // #endif // /* -// ** The page handle passed as the first argument refers to a dirty page -// ** with a page number other than iNew. This function changes the page's -// ** page number to iNew and sets the value of the PgHdr.flags field to +// ** The page handle passed as the first argument refers to a dirty page +// ** with a page number other than iNew. This function changes the page's +// ** page number to iNew and sets the value of the PgHdr.flags field to // ** the value passed as the third parameter. // */ // void sqlite3PagerRekey(DbPage *pPg, Pgno iNew, u16 flags){ @@ -7210,7 +7192,7 @@ // } // /* -// ** Return a pointer to the Pager.nExtra bytes of "extra" space +// ** Return a pointer to the Pager.nExtra bytes of "extra" space // ** allocated along with the specified page. // */ // void *sqlite3PagerGetExtra(DbPage *pPg){ @@ -7219,7 +7201,7 @@ // /* // ** Get/set the locking-mode for this pager. Parameter eMode must be one -// ** of PAGER_LOCKINGMODE_QUERY, PAGER_LOCKINGMODE_NORMAL or +// ** of PAGER_LOCKINGMODE_QUERY, PAGER_LOCKINGMODE_NORMAL or // ** PAGER_LOCKINGMODE_EXCLUSIVE. If the parameter is not _QUERY, then // ** the locking-mode is set to the value specified. // ** @@ -7267,8 +7249,8 @@ // assert( eMode==PAGER_JOURNALMODE_DELETE // || eMode==PAGER_JOURNALMODE_TRUNCATE // || eMode==PAGER_JOURNALMODE_PERSIST -// || eMode==PAGER_JOURNALMODE_OFF -// || eMode==PAGER_JOURNALMODE_WAL +// || eMode==PAGER_JOURNALMODE_OFF +// || eMode==PAGER_JOURNALMODE_WAL // || eMode==PAGER_JOURNALMODE_MEMORY ); // /* This routine is only called from the OP_JournalMode opcode, and @@ -7401,7 +7383,6 @@ // } // #endif - // #ifndef SQLITE_OMIT_WAL // /* // ** This function is called when the user invokes "PRAGMA wal_checkpoint", @@ -7453,7 +7434,7 @@ // assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK ); // rc = pagerLockDb(pPager, EXCLUSIVE_LOCK); // if( rc!=SQLITE_OK ){ -// /* If the attempt to grab the exclusive lock failed, release the +// /* If the attempt to grab the exclusive lock failed, release the // ** pending lock that may have been obtained instead. */ // pagerUnlockDb(pPager, SHARED_LOCK); // } @@ -7462,7 +7443,7 @@ // } // /* -// ** Call sqlite3WalOpen() to open the WAL handle. If the pager is in +// ** Call sqlite3WalOpen() to open the WAL handle. If the pager is in // ** exclusive-locking mode when this function is called, take an EXCLUSIVE // ** lock on the database file and use heap-memory to store the wal-index // ** in. Otherwise, use the normal shared-memory. @@ -7473,8 +7454,8 @@ // assert( pPager->pWal==0 && pPager->tempFile==0 ); // assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK ); -// /* If the pager is already in exclusive-mode, the WAL module will use -// ** heap-memory for the wal-index instead of the VFS shared-memory +// /* If the pager is already in exclusive-mode, the WAL module will use +// ** heap-memory for the wal-index instead of the VFS shared-memory // ** implementation. Take the exclusive lock now, before opening the WAL // ** file, to make sure this is safe. // */ @@ -7482,7 +7463,7 @@ // rc = pagerExclusiveLock(pPager); // } -// /* Open the connection to the log file. If this operation fails, +// /* Open the connection to the log file. If this operation fails, // ** (e.g. due to malloc() failure), return an error code. // */ // if( rc==SQLITE_OK ){ @@ -7496,7 +7477,6 @@ // return rc; // } - // /* // ** The caller must be holding a SHARED lock on the database file to call // ** this function. @@ -7504,7 +7484,7 @@ // ** If the pager passed as the first argument is open on a real database // ** file (not a temp file or an in-memory database), and the WAL file // ** is not already open, make an attempt to open it now. If successful, -// ** return SQLITE_OK. If an error occurs or the VFS used by the pager does +// ** return SQLITE_OK. If an error occurs or the VFS used by the pager does // ** not support the xShmXXX() methods, return an error code. *pbOpen is // ** not modified in either case. // ** @@ -7546,7 +7526,7 @@ // ** This function is called to close the connection to the log file prior // ** to switching from WAL to rollback mode. // ** -// ** Before closing the log file, this function attempts to take an +// ** Before closing the log file, this function attempts to take an // ** EXCLUSIVE lock on the database file. If this cannot be obtained, an // ** error (SQLITE_BUSY) is returned and the log connection is not closed. // ** If successful, the EXCLUSIVE lock is not released before returning. @@ -7572,7 +7552,7 @@ // rc = pagerOpenWal(pPager); // } // } - + // /* Checkpoint and close the log. Because an EXCLUSIVE lock is held on // ** the database file, the log and log-summary files will be deleted. // */ @@ -7592,7 +7572,7 @@ // #ifdef SQLITE_ENABLE_SETLK_TIMEOUT // /* // ** If pager pPager is a wal-mode database not in exclusive locking mode, -// ** invoke the sqlite3WalWriteLock() function on the associated Wal object +// ** invoke the sqlite3WalWriteLock() function on the associated Wal object // ** with the same db and bLock parameters as were passed to this function. // ** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise. // */ @@ -7605,7 +7585,7 @@ // } // /* -// ** Set the database handle used by the wal layer to determine if +// ** Set the database handle used by the wal layer to determine if // ** blocking locks are required. // */ // void sqlite3PagerWalDb(Pager *pPager, sqlite3 *db){ @@ -7630,11 +7610,11 @@ // /* // ** If this is a WAL database, store a pointer to pSnapshot. Next time a -// ** read transaction is opened, attempt to read from the snapshot it +// ** read transaction is opened, attempt to read from the snapshot it // ** identifies. If this is not a WAL database, return an error. // */ // int sqlite3PagerSnapshotOpen( -// Pager *pPager, +// Pager *pPager, // sqlite3_snapshot *pSnapshot // ){ // int rc = SQLITE_OK; @@ -7647,7 +7627,7 @@ // } // /* -// ** If this is a WAL database, call sqlite3WalSnapshotRecover(). If this +// ** If this is a WAL database, call sqlite3WalSnapshotRecover(). If this // ** is not a WAL database, return an error. // */ // int sqlite3PagerSnapshotRecover(Pager *pPager){ @@ -7664,7 +7644,7 @@ // ** The caller currently has a read transaction open on the database. // ** If this is not a WAL database, SQLITE_ERROR is returned. Otherwise, // ** this function takes a SHARED lock on the CHECKPOINTER slot and then -// ** checks if the snapshot passed as the second argument is still +// ** checks if the snapshot passed as the second argument is still // ** available. If so, SQLITE_OK is returned. // ** // ** If the snapshot is not available, SQLITE_ERROR is returned. Or, if diff --git a/source/libs/tdb/src/sqliteinc/sqliteInt.h b/source/libs/tdb/src/sqliteinc/sqliteInt.h index 634c783add..6f29dd5e19 100644 --- a/source/libs/tdb/src/sqliteinc/sqliteInt.h +++ b/source/libs/tdb/src/sqliteinc/sqliteInt.h @@ -46,6 +46,8 @@ typedef struct sqlite3_pcache_page { typedef struct sqlite3_vfs sqlite3_vfs; typedef struct sqlite3 sqlite3; +#define SQLITE_DEFAULT_PAGE_SIZE 4096 + #include "pager.h" #include "pcache.h"