提交 c7cb16d4 编写于 作者: H Hongze Cheng

more

上级 e3771119
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#include "sqliteInt.h" #include "sqliteInt.h"
// #include "wal.h" // #include "wal.h"
// /******************* NOTES ON THE DESIGN OF THE PAGER ************************ // /******************* NOTES ON THE DESIGN OF THE PAGER ************************
// ** // **
// ** This comment block describes invariants that hold when using a rollback // ** This comment block describes invariants that hold when using a rollback
...@@ -413,7 +412,6 @@ ...@@ -413,7 +412,6 @@
// */ // */
// #define MAX_SECTOR_SIZE 0x10000 // #define MAX_SECTOR_SIZE 0x10000
// /* // /*
// ** An instance of the following structure is allocated for each active // ** An instance of the following structure is allocated for each active
// ** savepoint and statement transaction in the system. All such structures // ** savepoint and statement transaction in the system. All such structures
...@@ -447,258 +445,258 @@ ...@@ -447,258 +445,258 @@
// #define SPILLFLAG_ROLLBACK 0x02 /* Current rolling back, so do not spill */ // #define SPILLFLAG_ROLLBACK 0x02 /* Current rolling back, so do not spill */
// #define SPILLFLAG_NOSYNC 0x04 /* Spill is ok, but do not sync */ // #define SPILLFLAG_NOSYNC 0x04 /* Spill is ok, but do not sync */
// /* /*
// ** An open page cache is an instance of struct Pager. A description of ** An open page cache is an instance of struct Pager. A description of
// ** some of the more important member variables follows: ** some of the more important member variables follows:
// ** **
// ** eState ** eState
// ** **
// ** The current 'state' of the pager object. See the comment and state ** The current 'state' of the pager object. See the comment and state
// ** diagram above for a description of the pager state. ** diagram above for a description of the pager state.
// ** **
// ** eLock ** eLock
// ** **
// ** For a real on-disk database, the current lock held on the database file - ** For a real on-disk database, the current lock held on the database file -
// ** NO_LOCK, SHARED_LOCK, RESERVED_LOCK or EXCLUSIVE_LOCK. ** NO_LOCK, SHARED_LOCK, RESERVED_LOCK or EXCLUSIVE_LOCK.
// ** **
// ** For a temporary or in-memory database (neither of which require any ** For a temporary or in-memory database (neither of which require any
// ** locks), this variable is always set to EXCLUSIVE_LOCK. Since such ** locks), this variable is always set to EXCLUSIVE_LOCK. Since such
// ** databases always have Pager.exclusiveMode==1, this tricks the pager ** databases always have Pager.exclusiveMode==1, this tricks the pager
// ** logic into thinking that it already has all the locks it will ever ** logic into thinking that it already has all the locks it will ever
// ** need (and no reason to release them). ** need (and no reason to release them).
// ** **
// ** In some (obscure) circumstances, this variable may also be set to ** In some (obscure) circumstances, this variable may also be set to
// ** UNKNOWN_LOCK. See the comment above the #define of UNKNOWN_LOCK for ** UNKNOWN_LOCK. See the comment above the #define of UNKNOWN_LOCK for
// ** details. ** details.
// ** **
// ** changeCountDone ** changeCountDone
// ** **
// ** This boolean variable is used to make sure that the change-counter ** 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 ** (the 4-byte header field at byte offset 24 of the database file) is
// ** not updated more often than necessary. ** not updated more often than necessary.
// ** **
// ** It is set to true when the change-counter field is updated, which ** 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. ** can only happen if an exclusive lock is held on the database file.
// ** It is cleared (set to false) whenever an exclusive lock is ** It is cleared (set to false) whenever an exclusive lock is
// ** relinquished on the database file. Each time a transaction is committed, ** relinquished on the database file. Each time a transaction is committed,
// ** The changeCountDone flag is inspected. If it is true, the work of ** The changeCountDone flag is inspected. If it is true, the work of
// ** updating the change-counter is omitted for the current transaction. ** updating the change-counter is omitted for the current transaction.
// ** **
// ** This mechanism means that when running in exclusive mode, a connection ** This mechanism means that when running in exclusive mode, a connection
// ** need only update the change-counter once, for the first transaction ** need only update the change-counter once, for the first transaction
// ** committed. ** committed.
// ** **
// ** setSuper ** setSuper
// ** **
// ** When PagerCommitPhaseOne() is called to commit a transaction, it may ** When PagerCommitPhaseOne() is called to commit a transaction, it may
// ** (or may not) specify a super-journal name to be written into the ** (or may not) specify a super-journal name to be written into the
// ** journal file before it is synced to disk. ** journal file before it is synced to disk.
// ** **
// ** Whether or not a journal file contains a super-journal pointer affects ** 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 ** the way in which the journal file is finalized after the transaction is
// ** committed or rolled back when running in "journal_mode=PERSIST" mode. ** committed or rolled back when running in "journal_mode=PERSIST" mode.
// ** If a journal file does not contain a super-journal pointer, it is ** If a journal file does not contain a super-journal pointer, it is
// ** finalized by overwriting the first journal header with zeroes. If ** finalized by overwriting the first journal header with zeroes. If
// ** it does contain a super-journal pointer the journal file is finalized ** it does contain a super-journal pointer the journal file is finalized
// ** by truncating it to zero bytes, just as if the connection were ** by truncating it to zero bytes, just as if the connection were
// ** running in "journal_mode=truncate" mode. ** running in "journal_mode=truncate" mode.
// ** **
// ** Journal files that contain super-journal pointers cannot be finalized ** Journal files that contain super-journal pointers cannot be finalized
// ** simply by overwriting the first journal-header with zeroes, as the ** simply by overwriting the first journal-header with zeroes, as the
// ** super-journal pointer could interfere with hot-journal rollback of any ** super-journal pointer could interfere with hot-journal rollback of any
// ** subsequently interrupted transaction that reuses the journal file. ** subsequently interrupted transaction that reuses the journal file.
// ** **
// ** The flag is cleared as soon as the journal file is finalized (either ** The flag is cleared as soon as the journal file is finalized (either
// ** by PagerCommitPhaseTwo or PagerRollback). If an IO error prevents the ** by PagerCommitPhaseTwo or PagerRollback). If an IO error prevents the
// ** journal file from being successfully finalized, the setSuper flag ** journal file from being successfully finalized, the setSuper flag
// ** is cleared anyway (and the pager will move to ERROR state). ** is cleared anyway (and the pager will move to ERROR state).
// ** **
// ** doNotSpill ** doNotSpill
// ** **
// ** This variables control the behavior of cache-spills (calls made by ** This variables control the behavior of cache-spills (calls made by
// ** the pcache module to the pagerStress() routine to write cached data ** the pcache module to the pagerStress() routine to write cached data
// ** to the file-system in order to free up memory). ** to the file-system in order to free up memory).
// ** **
// ** When bits SPILLFLAG_OFF or SPILLFLAG_ROLLBACK of doNotSpill are set, ** When bits SPILLFLAG_OFF or SPILLFLAG_ROLLBACK of doNotSpill are set,
// ** writing to the database from pagerStress() is disabled altogether. ** writing to the database from pagerStress() is disabled altogether.
// ** The SPILLFLAG_ROLLBACK case is done in a very obscure case that ** The SPILLFLAG_ROLLBACK case is done in a very obscure case that
// ** comes up during savepoint rollback that requires the pcache module ** comes up during savepoint rollback that requires the pcache module
// ** to allocate a new page to prevent the journal file from being written ** 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 ** while it is being traversed by code in pager_playback(). The SPILLFLAG_OFF
// ** case is a user preference. ** case is a user preference.
// ** **
// ** If the SPILLFLAG_NOSYNC bit is set, writing to the database from ** If the SPILLFLAG_NOSYNC bit is set, writing to the database from
// ** pagerStress() is permitted, but syncing the journal file is not. ** pagerStress() is permitted, but syncing the journal file is not.
// ** This flag is set by sqlite3PagerWrite() when the file-system sector-size ** 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 ** 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. ** from happening in between the journalling of two pages on the same sector.
// ** **
// ** subjInMemory ** subjInMemory
// ** **
// ** This is a boolean variable. If true, then any required sub-journal ** 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 ** is opened as an in-memory journal file. If false, then in-memory
// ** sub-journals are only used for in-memory pager files. ** sub-journals are only used for in-memory pager files.
// ** **
// ** This variable is updated by the upper layer each time a new ** This variable is updated by the upper layer each time a new
// ** write-transaction is opened. ** write-transaction is opened.
// ** **
// ** dbSize, dbOrigSize, dbFileSize ** dbSize, dbOrigSize, dbFileSize
// ** **
// ** Variable dbSize is set to the number of pages in the database file. ** 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 ** It is valid in PAGER_READER and higher states (all states except for
// ** OPEN and ERROR). ** OPEN and ERROR).
// ** **
// ** dbSize is set based on the size of the database file, which may be ** 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 ** 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 ** 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 ** 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). ** 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 ** 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 have at least one page. (i.e. a 1KB file with 2K page-size leads
// ** to dbSize==1). ** to dbSize==1).
// ** **
// ** During a write-transaction, if pages with page-numbers greater than ** During a write-transaction, if pages with page-numbers greater than
// ** dbSize are modified in the cache, dbSize is updated accordingly. ** dbSize are modified in the cache, dbSize is updated accordingly.
// ** Similarly, if the database is truncated using PagerTruncateImage(), ** Similarly, if the database is truncated using PagerTruncateImage(),
// ** dbSize is updated. ** dbSize is updated.
// ** **
// ** Variables dbOrigSize and dbFileSize are valid in states ** Variables dbOrigSize and dbFileSize are valid in states
// ** PAGER_WRITER_LOCKED and higher. dbOrigSize is a copy of the dbSize ** PAGER_WRITER_LOCKED and higher. dbOrigSize is a copy of the dbSize
// ** variable at the start of the transaction. It is used during rollback, ** variable at the start of the transaction. It is used during rollback,
// ** and to determine whether or not pages need to be journalled before ** and to determine whether or not pages need to be journalled before
// ** being modified. ** being modified.
// ** **
// ** Throughout a write-transaction, dbFileSize contains the size of ** 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 ** 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 ** write-transaction is first opened, and updated when VFS calls are made
// ** to write or truncate the database file on disk. ** to write or truncate the database file on disk.
// ** **
// ** The only reason the dbFileSize variable is required is to suppress ** The only reason the dbFileSize variable is required is to suppress
// ** unnecessary calls to xTruncate() after committing a transaction. If, ** unnecessary calls to xTruncate() after committing a transaction. If,
// ** when a transaction is committed, the dbFileSize variable indicates ** when a transaction is committed, the dbFileSize variable indicates
// ** that the database file is larger than the database image (Pager.dbSize), ** that the database file is larger than the database image (Pager.dbSize),
// ** pager_truncate() is called. The pager_truncate() call uses xFilesize() ** pager_truncate() is called. The pager_truncate() call uses xFilesize()
// ** to measure the database file on disk, and then truncates it if required. ** 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 ** dbFileSize is not used when rolling back a transaction. In this case
// ** pager_truncate() is called unconditionally (which means there may be ** pager_truncate() is called unconditionally (which means there may be
// ** a call to xFilesize() that is not strictly required). In either case, ** a call to xFilesize() that is not strictly required). In either case,
// ** pager_truncate() may cause the file to become smaller or larger. ** pager_truncate() may cause the file to become smaller or larger.
// ** **
// ** dbHintSize ** dbHintSize
// ** **
// ** The dbHintSize variable is used to limit the number of calls made to ** The dbHintSize variable is used to limit the number of calls made to
// ** the VFS xFileControl(FCNTL_SIZE_HINT) method. ** the VFS xFileControl(FCNTL_SIZE_HINT) method.
// ** **
// ** dbHintSize is set to a copy of the dbSize variable when a ** dbHintSize is set to a copy of the dbSize variable when a
// ** write-transaction is opened (at the same time as dbFileSize and ** write-transaction is opened (at the same time as dbFileSize and
// ** dbOrigSize). If the xFileControl(FCNTL_SIZE_HINT) method is called, ** dbOrigSize). If the xFileControl(FCNTL_SIZE_HINT) method is called,
// ** dbHintSize is increased to the number of pages that correspond to the ** dbHintSize is increased to the number of pages that correspond to the
// ** size-hint passed to the method call. See pager_write_pagelist() for ** size-hint passed to the method call. See pager_write_pagelist() for
// ** details. ** details.
// ** **
// ** errCode ** errCode
// ** **
// ** The Pager.errCode variable is only ever used in PAGER_ERROR state. It ** 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 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 ** is always set to SQLITE_FULL, SQLITE_IOERR or one of the SQLITE_IOERR_XXX
// ** sub-codes. ** sub-codes.
// ** **
// ** syncFlags, walSyncFlags ** syncFlags, walSyncFlags
// ** **
// ** syncFlags is either SQLITE_SYNC_NORMAL (0x02) or SQLITE_SYNC_FULL (0x03). ** syncFlags is either SQLITE_SYNC_NORMAL (0x02) or SQLITE_SYNC_FULL (0x03).
// ** syncFlags is used for rollback mode. walSyncFlags is used for WAL mode ** syncFlags is used for rollback mode. walSyncFlags is used for WAL mode
// ** and contains the flags used to sync the checkpoint operations in the ** 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 ** 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 ** 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 ** for checkpoint operations, use (walSyncFlags&0x03) and to get the correct
// ** sync flags for transaction commit, use ((walSyncFlags>>2)&0x03). Note ** sync flags for transaction commit, use ((walSyncFlags>>2)&0x03). Note
// ** that with synchronous=NORMAL in WAL mode, transaction commit is not synced ** that with synchronous=NORMAL in WAL mode, transaction commit is not synced
// ** meaning that the 0x04 and 0x08 bits are both zero. ** meaning that the 0x04 and 0x08 bits are both zero.
// */ */
// struct Pager { struct Pager {
// sqlite3_vfs *pVfs; /* OS functions to use for IO */ // sqlite3_vfs *pVfs; /* OS functions to use for IO */
// u8 exclusiveMode; /* Boolean. True if locking_mode==EXCLUSIVE */ // u8 exclusiveMode; /* Boolean. True if locking_mode==EXCLUSIVE */
// u8 journalMode; /* One of the PAGER_JOURNALMODE_* values */ // u8 journalMode; /* One of the PAGER_JOURNALMODE_* values */
// u8 useJournal; /* Use a rollback journal on this file */ // u8 useJournal; /* Use a rollback journal on this file */
// u8 noSync; /* Do not sync the journal if true */ // u8 noSync; /* Do not sync the journal if true */
// u8 fullSync; /* Do extra syncs of the journal for robustness */ // u8 fullSync; /* Do extra syncs of the journal for robustness */
// u8 extraSync; /* sync directory after journal delete */ // u8 extraSync; /* sync directory after journal delete */
// u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */ // u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */
// u8 walSyncFlags; /* See description above */ // u8 walSyncFlags; /* See description above */
// u8 tempFile; /* zFilename is a temporary or immutable file */ // u8 tempFile; /* zFilename is a temporary or immutable file */
// u8 noLock; /* Do not lock (except in WAL mode) */ // u8 noLock; /* Do not lock (except in WAL mode) */
// u8 readOnly; /* True for a read-only database */ // u8 readOnly; /* True for a read-only database */
// u8 memDb; /* True to inhibit all file I/O */ // u8 memDb; /* True to inhibit all file I/O */
// u8 memVfs; /* VFS-implemented memory database */ // u8 memVfs; /* VFS-implemented memory database */
// /************************************************************************** // /**************************************************************************
// ** The following block contains those class members that change during // ** The following block contains those class members that change during
// ** routine operation. Class members not in this block are either fixed // ** 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 // ** 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, // ** significant mode change (such as changing the page_size, locking_mode,
// ** or the journal_mode). From another view, these class members describe // ** or the journal_mode). From another view, these class members describe
// ** the "state" of the pager, while other class members describe the // ** the "state" of the pager, while other class members describe the
// ** "configuration" of the pager. // ** "configuration" of the pager.
// */ // */
// u8 eState; /* Pager state (OPEN, READER, WRITER_LOCKED..) */ // u8 eState; /* Pager state (OPEN, READER, WRITER_LOCKED..) */
// u8 eLock; /* Current lock held on database file */ // u8 eLock; /* Current lock held on database file */
// u8 changeCountDone; /* Set after incrementing the change-counter */ // u8 changeCountDone; /* Set after incrementing the change-counter */
// u8 setSuper; /* Super-jrnl name is written into jrnl */ // u8 setSuper; /* Super-jrnl name is written into jrnl */
// u8 doNotSpill; /* Do not spill the cache when non-zero */ // u8 doNotSpill; /* Do not spill the cache when non-zero */
// u8 subjInMemory; /* True to use in-memory sub-journals */ // u8 subjInMemory; /* True to use in-memory sub-journals */
// u8 bUseFetch; /* True to use xFetch() */ // u8 bUseFetch; /* True to use xFetch() */
// u8 hasHeldSharedLock; /* True if a shared lock has ever been held */ // u8 hasHeldSharedLock; /* True if a shared lock has ever been held */
// Pgno dbSize; /* Number of pages in the database */ // Pgno dbSize; /* Number of pages in the database */
// Pgno dbOrigSize; /* dbSize before the current transaction */ // Pgno dbOrigSize; /* dbSize before the current transaction */
// Pgno dbFileSize; /* Number of pages in the database file */ // Pgno dbFileSize; /* Number of pages in the database file */
// Pgno dbHintSize; /* Value passed to FCNTL_SIZE_HINT call */ // Pgno dbHintSize; /* Value passed to FCNTL_SIZE_HINT call */
// int errCode; /* One of several kinds of errors */ // int errCode; /* One of several kinds of errors */
// int nRec; /* Pages journalled since last j-header written */ // int nRec; /* Pages journalled since last j-header written */
// u32 cksumInit; /* Quasi-random value added to every checksum */ // u32 cksumInit; /* Quasi-random value added to every checksum */
// u32 nSubRec; /* Number of records written to sub-journal */ // u32 nSubRec; /* Number of records written to sub-journal */
// Bitvec *pInJournal; /* One bit for each page in the database file */ // Bitvec *pInJournal; /* One bit for each page in the database file */
// sqlite3_file *fd; /* File descriptor for database */ // sqlite3_file *fd; /* File descriptor for database */
// sqlite3_file *jfd; /* File descriptor for main journal */ // sqlite3_file *jfd; /* File descriptor for main journal */
// sqlite3_file *sjfd; /* File descriptor for sub-journal */ // sqlite3_file *sjfd; /* File descriptor for sub-journal */
// i64 journalOff; /* Current write offset in the journal file */ // i64 journalOff; /* Current write offset in the journal file */
// i64 journalHdr; /* Byte offset to previous journal header */ // i64 journalHdr; /* Byte offset to previous journal header */
// sqlite3_backup *pBackup; /* Pointer to list of ongoing backup processes */ // sqlite3_backup *pBackup; /* Pointer to list of ongoing backup processes */
// PagerSavepoint *aSavepoint; /* Array of active savepoints */ // PagerSavepoint *aSavepoint; /* Array of active savepoints */
// int nSavepoint; /* Number of elements in aSavepoint[] */ // int nSavepoint; /* Number of elements in aSavepoint[] */
// u32 iDataVersion; /* Changes whenever database content changes */ // u32 iDataVersion; /* Changes whenever database content changes */
// char dbFileVers[16]; /* Changes whenever database file changes */ // char dbFileVers[16]; /* Changes whenever database file changes */
// int nMmapOut; /* Number of mmap pages currently outstanding */ // int nMmapOut; /* Number of mmap pages currently outstanding */
// sqlite3_int64 szMmap; /* Desired maximum mmap size */ // sqlite3_int64 szMmap; /* Desired maximum mmap size */
// PgHdr *pMmapFreelist; /* List of free mmap page headers (pDirty) */ // PgHdr *pMmapFreelist; /* List of free mmap page headers (pDirty) */
// /* // /*
// ** End of the routinely-changing class members // ** End of the routinely-changing class members
// ***************************************************************************/ // ***************************************************************************/
// u16 nExtra; /* Add this many bytes to each in-memory page */ // u16 nExtra; /* Add this many bytes to each in-memory page */
// i16 nReserve; /* Number of unused bytes at end of each page */ // i16 nReserve; /* Number of unused bytes at end of each page */
// u32 vfsFlags; /* Flags for sqlite3_vfs.xOpen() */ // u32 vfsFlags; /* Flags for sqlite3_vfs.xOpen() */
// u32 sectorSize; /* Assumed sector size during rollback */ // u32 sectorSize; /* Assumed sector size during rollback */
// Pgno mxPgno; /* Maximum allowed size of the database */ // Pgno mxPgno; /* Maximum allowed size of the database */
// i64 pageSize; /* Number of bytes in a page */ // i64 pageSize; /* Number of bytes in a page */
// i64 journalSizeLimit; /* Size limit for persistent journal files */ // i64 journalSizeLimit; /* Size limit for persistent journal files */
// char *zFilename; /* Name of the database file */ // char *zFilename; /* Name of the database file */
// char *zJournal; /* Name of the journal file */ // char *zJournal; /* Name of the journal file */
// int (*xBusyHandler)(void*); /* Function to call when busy */ // int (*xBusyHandler)(void*); /* Function to call when busy */
// void *pBusyHandlerArg; /* Context argument for xBusyHandler */ // void *pBusyHandlerArg; /* Context argument for xBusyHandler */
// int aStat[4]; /* Total cache hits, misses, writes, spills */ // int aStat[4]; /* Total cache hits, misses, writes, spills */
// #ifdef SQLITE_TEST // #ifdef SQLITE_TEST
// int nRead; /* Database pages read */ // int nRead; /* Database pages read */
// #endif // #endif
// void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */ // void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */
// int (*xGet)(Pager*,Pgno,DbPage**,int); /* Routine to fetch a patch */ // int (*xGet)(Pager*,Pgno,DbPage**,int); /* Routine to fetch a patch */
// char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ // char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */
// PCache *pPCache; /* Pointer to page cache object */ // PCache *pPCache; /* Pointer to page cache object */
// #ifndef SQLITE_OMIT_WAL // #ifndef SQLITE_OMIT_WAL
// Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */ // Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */
// char *zWal; /* File name for write-ahead log */ // char *zWal; /* File name for write-ahead log */
// #endif // #endif
// }; };
// /* // /*
// ** Indexes for use with Pager.aStat[]. The Pager.aStat[] array contains // ** Indexes for use with Pager.aStat[]. The Pager.aStat[] array contains
...@@ -724,8 +722,6 @@ ...@@ -724,8 +722,6 @@
// # define PAGER_INCR(v) // # define PAGER_INCR(v)
// #endif // #endif
// /* // /*
// ** Journal files begin with the following magic string. The data // ** Journal files begin with the following magic string. The data
// ** was obtained from /dev/random. It is used only as a sanity check. // ** was obtained from /dev/random. It is used only as a sanity check.
...@@ -1110,7 +1106,6 @@ ...@@ -1110,7 +1106,6 @@
// */ // */
// #define put32bits(A,B) sqlite3Put4byte((u8*)A,B) // #define put32bits(A,B) sqlite3Put4byte((u8*)A,B)
// /* // /*
// ** Write a 32-bit integer into the given file descriptor. Return SQLITE_OK // ** Write a 32-bit integer into the given file descriptor. Return SQLITE_OK
// ** on success or an error code is something goes wrong. // ** on success or an error code is something goes wrong.
...@@ -1658,7 +1653,6 @@ ...@@ -1658,7 +1653,6 @@
// return rc; // return rc;
// } // }
// /* // /*
// ** Write the supplied super-journal name into the journal file for pager // ** 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 // ** pPager at the current location. The super-journal name must be the last
...@@ -2578,7 +2572,6 @@ ...@@ -2578,7 +2572,6 @@
// return rc; // 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, // ** file in the file-system. This only happens when committing a transaction,
...@@ -2946,7 +2939,6 @@ ...@@ -2946,7 +2939,6 @@
// return rc; // return rc;
// } // }
// /* // /*
// ** Read the content for page pPg out of the database file (or out of // ** 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
...@@ -3857,7 +3849,6 @@ ...@@ -3857,7 +3849,6 @@
// *pnPage = (int)pPager->dbSize; // *pnPage = (int)pPager->dbSize;
// } // }
// /* // /*
// ** Try to obtain a lock of type locktype on the database file. If // ** 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 // ** a similar or greater lock is already held, this function is a no-op
...@@ -3953,7 +3944,6 @@ ...@@ -3953,7 +3944,6 @@
// ** is no longer correct. */ // ** is no longer correct. */
// } // }
// /* // /*
// ** This function is called before attempting a hot-journal rollback. It // ** This function is called before attempting a hot-journal rollback. It
// ** syncs the journal file to disk, then sets pPager->journalHdr to the // ** syncs the journal file to disk, then sets pPager->journalHdr to the
...@@ -4080,77 +4070,76 @@ ...@@ -4080,77 +4070,76 @@
// return rc; // return rc;
// } // }
/*
// /* ** Shutdown the page cache. Free all memory and close all files.
// ** Shutdown the page cache. Free all memory and close all files. **
// ** ** If a transaction was in progress when this routine is called, that
// ** If a transaction was in progress when this routine is called, that ** transaction is rolled back. All outstanding pages are invalidated
// ** transaction is rolled back. All outstanding pages are invalidated ** and their memory is freed. Any attempt to use a page associated
// ** and their memory is freed. Any attempt to use a page associated ** with this page cache after this function returns will likely
// ** with this page cache after this function returns will likely ** result in a coredump.
// ** result in a coredump. **
// ** ** This function always succeeds. If a transaction is active an attempt
// ** This function always succeeds. If a transaction is active an attempt ** is made to roll it back. If an error occurs during the rollback
// ** 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
// ** a hot journal may be left in the filesystem but no error is returned ** to the caller.
// ** to the caller. */
// */ int sqlite3PagerClose(Pager *pPager, sqlite3 *db) {
// int sqlite3PagerClose(Pager *pPager, sqlite3 *db){ // u8 *pTmp = (u8*)pPager->pTmpSpace;
// u8 *pTmp = (u8*)pPager->pTmpSpace; // assert( db || pagerUseWal(pPager)==0 );
// assert( db || pagerUseWal(pPager)==0 ); // assert( assert_pager_state(pPager) );
// assert( assert_pager_state(pPager) ); // disable_simulated_io_errors();
// disable_simulated_io_errors(); // sqlite3BeginBenignMalloc();
// sqlite3BeginBenignMalloc(); // pagerFreeMapHdrs(pPager);
// pagerFreeMapHdrs(pPager); // /* pPager->errCode = 0; */
// /* pPager->errCode = 0; */ // pPager->exclusiveMode = 0;
// pPager->exclusiveMode = 0; // #ifndef SQLITE_OMIT_WAL
// #ifndef SQLITE_OMIT_WAL // {
// { // u8 *a = 0;
// u8 *a = 0; // assert( db || pPager->pWal==0 );
// assert( db || pPager->pWal==0 ); // if( db && 0==(db->flags & SQLITE_NoCkptOnClose)
// if( db && 0==(db->flags & SQLITE_NoCkptOnClose) // && SQLITE_OK==databaseIsUnmoved(pPager)
// && SQLITE_OK==databaseIsUnmoved(pPager) // ){
// ){ // a = pTmp;
// a = pTmp; // }
// } // sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize,a);
// sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize,a); // pPager->pWal = 0;
// pPager->pWal = 0; // }
// } // #endif
// #endif // pager_reset(pPager);
// pager_reset(pPager); // if( MEMDB ){
// if( MEMDB ){ // pager_unlock(pPager);
// pager_unlock(pPager); // }else{
// }else{ // /* If it is open, sync the journal file before calling UnlockAndRollback.
// /* If it is open, sync the journal file before calling UnlockAndRollback. // ** If this is not done, then an unsynced portion of the open journal
// ** 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
// ** file may be played back into the database. If a power failure occurs // ** while this is happening, the database could become corrupt.
// ** while this is happening, the database could become corrupt. // **
// ** // ** If an error occurs while trying to sync the journal, shift the pager
// ** If an error occurs while trying to sync the journal, shift the pager // ** into the ERROR state. This causes UnlockAndRollback to unlock the
// ** into the ERROR state. This causes UnlockAndRollback to unlock the // ** database and close the journal file without attempting to roll it
// ** 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
// ** back or finalize it. The next database user will have to do hot-journal // ** rollback before accessing the database file.
// ** rollback before accessing the database file. // */
// */ // if( isOpen(pPager->jfd) ){
// if( isOpen(pPager->jfd) ){ // pager_error(pPager, pagerSyncHotJournal(pPager));
// pager_error(pPager, pagerSyncHotJournal(pPager)); // }
// } // pagerUnlockAndRollback(pPager);
// pagerUnlockAndRollback(pPager); // }
// } // sqlite3EndBenignMalloc();
// sqlite3EndBenignMalloc(); // enable_simulated_io_errors();
// enable_simulated_io_errors(); // PAGERTRACE(("CLOSE %d\n", PAGERID(pPager)));
// PAGERTRACE(("CLOSE %d\n", PAGERID(pPager))); // IOTRACE(("CLOSE %p\n", pPager))
// IOTRACE(("CLOSE %p\n", pPager)) // sqlite3OsClose(pPager->jfd);
// sqlite3OsClose(pPager->jfd); // sqlite3OsClose(pPager->fd);
// sqlite3OsClose(pPager->fd); // sqlite3PageFree(pTmp);
// sqlite3PageFree(pTmp); // sqlite3PcacheClose(pPager->pPCache);
// sqlite3PcacheClose(pPager->pPCache); // assert( !pPager->aSavepoint && !pPager->pInJournal );
// assert( !pPager->aSavepoint && !pPager->pInJournal ); // assert( !isOpen(pPager->jfd) && !isOpen(pPager->sjfd) );
// assert( !isOpen(pPager->jfd) && !isOpen(pPager->sjfd) );
// sqlite3_free(pPager);
// sqlite3_free(pPager); return SQLITE_OK;
// return SQLITE_OK; }
// }
// #if !defined(NDEBUG) || defined(SQLITE_TEST) // #if !defined(NDEBUG) || defined(SQLITE_TEST)
// /* // /*
...@@ -4620,404 +4609,402 @@ ...@@ -4620,404 +4609,402 @@
// return rc; // return rc;
// } // }
// /* /*
// ** Allocate and initialize a new Pager object and put a pointer to it ** Allocate and initialize a new Pager object and put a pointer to it
// ** in *ppPager. The pager should eventually be freed by passing it ** in *ppPager. The pager should eventually be freed by passing it
// ** to sqlite3PagerClose(). ** to sqlite3PagerClose().
// ** **
// ** The zFilename argument is the path to the database file to open. ** The zFilename argument is the path to the database file to open.
// ** If zFilename is NULL then a randomly-named temporary file is created ** 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 ** and used as the file to be cached. Temporary files are be deleted
// ** automatically when they are closed. If zFilename is ":memory:" then ** automatically when they are closed. If zFilename is ":memory:" then
// ** all information is held in cache. It is never written to disk. ** all information is held in cache. It is never written to disk.
// ** This can be used to implement an in-memory database. ** This can be used to implement an in-memory database.
// ** **
// ** The nExtra parameter specifies the number of bytes of space allocated ** The nExtra parameter specifies the number of bytes of space allocated
// ** along with each page reference. This space is available to the user ** along with each page reference. This space is available to the user
// ** via the sqlite3PagerGetExtra() API. When a new page is allocated, the ** via the sqlite3PagerGetExtra() API. When a new page is allocated, the
// ** first 8 bytes of this space are zeroed but the remainder is uninitialized. ** 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 extra space is used by btree as the MemPage object.)
// ** **
// ** The flags argument is used to specify properties that affect the ** The flags argument is used to specify properties that affect the
// ** operation of the pager. It should be passed some bitwise combination ** operation of the pager. It should be passed some bitwise combination
// ** of the PAGER_* flags. ** of the PAGER_* flags.
// ** **
// ** The vfsFlags parameter is a bitmask to pass to the flags parameter ** The vfsFlags parameter is a bitmask to pass to the flags parameter
// ** of the xOpen() method of the supplied VFS when opening files. ** of the xOpen() method of the supplied VFS when opening files.
// ** **
// ** If the pager object is allocated and the specified file opened ** If the pager object is allocated and the specified file opened
// ** successfully, SQLITE_OK is returned and *ppPager set to point to ** successfully, SQLITE_OK is returned and *ppPager set to point to
// ** the new pager object. If an error occurs, *ppPager is set to NULL ** the new pager object. If an error occurs, *ppPager is set to NULL
// ** and error code returned. This function may return SQLITE_NOMEM ** and error code returned. This function may return SQLITE_NOMEM
// ** (sqlite3Malloc() is used to allocate memory), SQLITE_CANTOPEN or ** (sqlite3Malloc() is used to allocate memory), SQLITE_CANTOPEN or
// ** various SQLITE_IO_XXX errors. ** various SQLITE_IO_XXX errors.
// */ */
// int sqlite3PagerOpen( int sqlite3PagerOpen(sqlite3_vfs *pVfs, /* The virtual file system to use */
// sqlite3_vfs *pVfs, /* The virtual file system to use */ Pager ** ppPager, /* OUT: Return the Pager structure here */
// Pager **ppPager, /* OUT: Return the Pager structure here */ const char * zFilename, /* Name of the database file to open */
// const char *zFilename, /* Name of the database file to open */ int nExtra, /* Extra bytes append to each in-memory page */
// int nExtra, /* Extra bytes append to each in-memory page */ int flags, /* flags controlling this file */
// int flags, /* flags controlling this file */ int vfsFlags, /* flags passed through to sqlite3_vfs.xOpen() */
// int vfsFlags, /* flags passed through to sqlite3_vfs.xOpen() */ void (*xReinit)(DbPage *) /* Function to reinitialize pages */
// void (*xReinit)(DbPage*) /* Function to reinitialize pages */ ) {
// ){ // u8 *pPtr;
// u8 *pPtr; // Pager *pPager = 0; /* Pager object to allocate and return */
// Pager *pPager = 0; /* Pager object to allocate and return */ // int rc = SQLITE_OK; /* Return code */
// int rc = SQLITE_OK; /* Return code */ // int tempFile = 0; /* True for temp files (incl. in-memory files) */
// int tempFile = 0; /* True for temp files (incl. in-memory files) */ // int memDb = 0; /* True if this is an in-memory file */
// int memDb = 0; /* True if this is an in-memory file */ // #ifndef SQLITE_OMIT_DESERIALIZE
// #ifndef SQLITE_OMIT_DESERIALIZE // int memJM = 0; /* Memory journal mode */
// int memJM = 0; /* Memory journal mode */ // #else
// #else // # define memJM 0
// # define memJM 0 // #endif
// #endif // int readOnly = 0; /* True if this is a read-only file */
// int readOnly = 0; /* True if this is a read-only file */ // int journalFileSize; /* Bytes to allocate for each journal fd */
// int journalFileSize; /* Bytes to allocate for each journal fd */ // char *zPathname = 0; /* Full path to database file */
// char *zPathname = 0; /* Full path to database file */ // int nPathname = 0; /* Number of bytes in zPathname */
// int nPathname = 0; /* Number of bytes in zPathname */ // int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */
// int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */ // int pcacheSize = sqlite3PcacheSize(); /* Bytes to allocate for PCache */
// int pcacheSize = sqlite3PcacheSize(); /* Bytes to allocate for PCache */ // u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE; /* Default page size */
// u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE; /* Default page size */ // const char *zUri = 0; /* URI args to copy */
// const char *zUri = 0; /* URI args to copy */ // int nUriByte = 1; /* Number of bytes of URI args at *zUri */
// int nUriByte = 1; /* Number of bytes of URI args at *zUri */ // int nUri = 0; /* Number of URI parameters */
// int nUri = 0; /* Number of URI parameters */
// /* Figure out how much space is required for each journal file-handle
// /* Figure out how much space is required for each journal file-handle // ** (there are two of them, the main journal and the sub-journal). */
// ** (there are two of them, the main journal and the sub-journal). */ // journalFileSize = ROUND8(sqlite3JournalSize(pVfs));
// journalFileSize = ROUND8(sqlite3JournalSize(pVfs));
// /* Set the output variable to NULL in case an error occurs. */
// /* Set the output variable to NULL in case an error occurs. */ // *ppPager = 0;
// *ppPager = 0;
// #ifndef SQLITE_OMIT_MEMORYDB
// #ifndef SQLITE_OMIT_MEMORYDB // if( flags & PAGER_MEMORY ){
// if( flags & PAGER_MEMORY ){ // memDb = 1;
// memDb = 1; // if( zFilename && zFilename[0] ){
// if( zFilename && zFilename[0] ){ // zPathname = sqlite3DbStrDup(0, zFilename);
// zPathname = sqlite3DbStrDup(0, zFilename); // if( zPathname==0 ) return SQLITE_NOMEM;
// if( zPathname==0 ) return SQLITE_NOMEM; // nPathname = sqlite3Strlen30(zPathname);
// nPathname = sqlite3Strlen30(zPathname); // zFilename = 0;
// zFilename = 0; // }
// } // }
// } // #endif
// #endif
// /* Compute and store the full pathname in an allocated buffer pointed
// /* Compute and store the full pathname in an allocated buffer pointed // ** to by zPathname, length nPathname. Or, if this is a temporary file,
// ** to by zPathname, length nPathname. Or, if this is a temporary file, // ** leave both nPathname and zPathname set to 0.
// ** leave both nPathname and zPathname set to 0. // */
// */ // if( zFilename && zFilename[0] ){
// if( zFilename && zFilename[0] ){ // const char *z;
// const char *z; // nPathname = pVfs->mxPathname+1;
// nPathname = pVfs->mxPathname+1; // zPathname = sqlite3DbMallocRaw(0, nPathname*2);
// zPathname = sqlite3DbMallocRaw(0, nPathname*2); // if( zPathname==0 ){
// if( zPathname==0 ){ // return SQLITE_NOMEM;
// return SQLITE_NOMEM; // }
// } // zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */
// zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */ // rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname);
// rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname); // if( rc!=SQLITE_OK ){
// if( rc!=SQLITE_OK ){ // if( rc==SQLITE_OK_SYMLINK ){
// if( rc==SQLITE_OK_SYMLINK ){ // if( vfsFlags & SQLITE_OPEN_NOFOLLOW ){
// if( vfsFlags & SQLITE_OPEN_NOFOLLOW ){ // rc = SQLITE_CANTOPEN_SYMLINK;
// rc = SQLITE_CANTOPEN_SYMLINK; // }else{
// }else{ // rc = SQLITE_OK;
// rc = SQLITE_OK; // }
// } // }
// } // }
// } // nPathname = sqlite3Strlen30(zPathname);
// nPathname = sqlite3Strlen30(zPathname); // z = zUri = &zFilename[sqlite3Strlen30(zFilename)+1];
// z = zUri = &zFilename[sqlite3Strlen30(zFilename)+1]; // while( *z ){
// while( *z ){ // z += strlen(z)+1;
// z += strlen(z)+1; // z += strlen(z)+1;
// z += strlen(z)+1; // nUri++;
// nUri++; // }
// } // nUriByte = (int)(&z[1] - zUri);
// nUriByte = (int)(&z[1] - zUri); // assert( nUriByte>=1 );
// assert( nUriByte>=1 ); // if( rc==SQLITE_OK && nPathname+8>pVfs->mxPathname ){
// if( rc==SQLITE_OK && nPathname+8>pVfs->mxPathname ){ // /* This branch is taken when the journal path required by
// /* This branch is taken when the journal path required by // ** the database being opened will be more than pVfs->mxPathname
// ** the database being opened will be more than pVfs->mxPathname // ** bytes in length. This means the database cannot be opened,
// ** bytes in length. This means the database cannot be opened, // ** as it will not be possible to open the journal file or even
// ** as it will not be possible to open the journal file or even // ** check for a hot-journal before reading.
// ** check for a hot-journal before reading. // */
// */ // rc = SQLITE_CANTOPEN_BKPT;
// rc = SQLITE_CANTOPEN_BKPT; // }
// } // if( rc!=SQLITE_OK ){
// if( rc!=SQLITE_OK ){ // sqlite3DbFree(0, zPathname);
// sqlite3DbFree(0, zPathname); // return rc;
// return rc; // }
// } // }
// }
// /* Allocate memory for the Pager structure, PCache object, the
// /* Allocate memory for the Pager structure, PCache object, the // ** three file descriptors, the database file name and the journal
// ** three file descriptors, the database file name and the journal // ** file name. The layout in memory is as follows:
// ** file name. The layout in memory is as follows: // **
// ** // ** Pager object (sizeof(Pager) bytes)
// ** Pager object (sizeof(Pager) bytes) // ** PCache object (sqlite3PcacheSize() bytes)
// ** PCache object (sqlite3PcacheSize() bytes) // ** Database file handle (pVfs->szOsFile bytes)
// ** Database file handle (pVfs->szOsFile bytes) // ** Sub-journal file handle (journalFileSize bytes)
// ** Sub-journal file handle (journalFileSize bytes) // ** Main journal file handle (journalFileSize bytes)
// ** Main journal file handle (journalFileSize bytes) // ** Ptr back to the Pager (sizeof(Pager*) bytes)
// ** Ptr back to the Pager (sizeof(Pager*) bytes) // ** \0\0\0\0 database prefix (4 bytes)
// ** \0\0\0\0 database prefix (4 bytes) // ** Database file name (nPathname+1 bytes)
// ** Database file name (nPathname+1 bytes) // ** URI query parameters (nUriByte bytes)
// ** URI query parameters (nUriByte bytes) // ** Journal filename (nPathname+8+1 bytes)
// ** Journal filename (nPathname+8+1 bytes) // ** WAL filename (nPathname+4+1 bytes)
// ** WAL filename (nPathname+4+1 bytes) // ** \0\0\0 terminator (3 bytes)
// ** \0\0\0 terminator (3 bytes) // **
// ** // ** Some 3rd-party software, over which we have no control, depends on
// ** Some 3rd-party software, over which we have no control, depends on // ** the specific order of the filenames and the \0 separators between them
// ** 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
// ** so that it can (for example) find the database filename given the WAL // ** filename without using the sqlite3_filename_database() API. This is a
// ** 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
// ** 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
// ** software is in widespread use, so we try to avoid changing the filename // ** order and formatting if possible. In particular, the details of the
// ** order and formatting if possible. In particular, the details of the // ** filename format expected by 3rd-party software should be as follows:
// ** filename format expected by 3rd-party software should be as follows: // **
// ** // ** - Main Database Path
// ** - Main Database Path // ** - \0
// ** - \0 // ** - Multiple URI components consisting of:
// ** - Multiple URI components consisting of: // ** - Key
// ** - Key // ** - \0
// ** - \0 // ** - Value
// ** - Value // ** - \0
// ** - \0 // ** - \0
// ** - \0 // ** - Journal Path
// ** - Journal Path // ** - \0
// ** - \0 // ** - WAL Path (zWALName)
// ** - WAL Path (zWALName) // ** - \0
// ** - \0 // **
// ** // ** The sqlite3_create_filename() interface and the databaseFilename() utility
// ** The sqlite3_create_filename() interface and the databaseFilename() utility // ** that is used by sqlite3_filename_database() and kin also depend on the
// ** 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
// ** specific formatting and order of the various filenames, so if the format // ** changes here, be sure to change it there as well.
// ** changes here, be sure to change it there as well. // */
// */ // pPtr = (u8 *)sqlite3MallocZero(
// pPtr = (u8 *)sqlite3MallocZero( // ROUND8(sizeof(*pPager)) + /* Pager structure */
// ROUND8(sizeof(*pPager)) + /* Pager structure */ // ROUND8(pcacheSize) + /* PCache object */
// ROUND8(pcacheSize) + /* PCache object */ // ROUND8(pVfs->szOsFile) + /* The main db file */
// ROUND8(pVfs->szOsFile) + /* The main db file */ // journalFileSize * 2 + /* The two journal files */
// journalFileSize * 2 + /* The two journal files */ // sizeof(pPager) + /* Space to hold a pointer */
// sizeof(pPager) + /* Space to hold a pointer */ // 4 + /* Database prefix */
// 4 + /* Database prefix */ // nPathname + 1 + /* database filename */
// nPathname + 1 + /* database filename */ // nUriByte + /* query parameters */
// nUriByte + /* query parameters */ // nPathname + 8 + 1 + /* Journal filename */
// nPathname + 8 + 1 + /* Journal filename */ // #ifndef SQLITE_OMIT_WAL
// #ifndef SQLITE_OMIT_WAL // nPathname + 4 + 1 + /* WAL filename */
// nPathname + 4 + 1 + /* WAL filename */ // #endif
// #endif // 3 /* Terminator */
// 3 /* Terminator */ // );
// ); // assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) );
// assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) ); // if( !pPtr ){
// if( !pPtr ){ // sqlite3DbFree(0, zPathname);
// sqlite3DbFree(0, zPathname); // return SQLITE_NOMEM;
// return SQLITE_NOMEM; // }
// } // pPager = (Pager*)pPtr; pPtr += ROUND8(sizeof(*pPager));
// pPager = (Pager*)pPtr; pPtr += ROUND8(sizeof(*pPager)); // pPager->pPCache = (PCache*)pPtr; pPtr += ROUND8(pcacheSize);
// pPager->pPCache = (PCache*)pPtr; pPtr += ROUND8(pcacheSize); // pPager->fd = (sqlite3_file*)pPtr; pPtr += ROUND8(pVfs->szOsFile);
// pPager->fd = (sqlite3_file*)pPtr; pPtr += ROUND8(pVfs->szOsFile); // pPager->sjfd = (sqlite3_file*)pPtr; pPtr += journalFileSize;
// pPager->sjfd = (sqlite3_file*)pPtr; pPtr += journalFileSize; // pPager->jfd = (sqlite3_file*)pPtr; pPtr += journalFileSize;
// pPager->jfd = (sqlite3_file*)pPtr; pPtr += journalFileSize; // assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) );
// assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) ); // memcpy(pPtr, &pPager, sizeof(pPager)); pPtr += sizeof(pPager);
// memcpy(pPtr, &pPager, sizeof(pPager)); pPtr += sizeof(pPager);
// /* Fill in the Pager.zFilename and pPager.zQueryParam fields */
// /* Fill in the Pager.zFilename and pPager.zQueryParam fields */ // pPtr += 4; /* Skip zero prefix */
// pPtr += 4; /* Skip zero prefix */ // pPager->zFilename = (char*)pPtr;
// pPager->zFilename = (char*)pPtr; // if( nPathname>0 ){
// if( nPathname>0 ){ // memcpy(pPtr, zPathname, nPathname); pPtr += nPathname + 1;
// memcpy(pPtr, zPathname, nPathname); pPtr += nPathname + 1; // if( zUri ){
// if( zUri ){ // memcpy(pPtr, zUri, nUriByte); pPtr += nUriByte;
// memcpy(pPtr, zUri, nUriByte); pPtr += nUriByte; // }else{
// }else{ // pPtr++;
// pPtr++; // }
// } // }
// }
// /* Fill in Pager.zJournal */
// if( nPathname>0 ){
// /* Fill in Pager.zJournal */ // pPager->zJournal = (char*)pPtr;
// if( nPathname>0 ){ // memcpy(pPtr, zPathname, nPathname); pPtr += nPathname;
// pPager->zJournal = (char*)pPtr; // memcpy(pPtr, "-journal",8); pPtr += 8 + 1;
// memcpy(pPtr, zPathname, nPathname); pPtr += nPathname; // #ifdef SQLITE_ENABLE_8_3_NAMES
// memcpy(pPtr, "-journal",8); pPtr += 8 + 1; // sqlite3FileSuffix3(zFilename,pPager->zJournal);
// #ifdef SQLITE_ENABLE_8_3_NAMES // pPtr = (u8*)(pPager->zJournal + sqlite3Strlen30(pPager->zJournal)+1);
// sqlite3FileSuffix3(zFilename,pPager->zJournal); // #endif
// pPtr = (u8*)(pPager->zJournal + sqlite3Strlen30(pPager->zJournal)+1); // }else{
// #endif // pPager->zJournal = 0;
// }else{ // }
// pPager->zJournal = 0;
// } // #ifndef SQLITE_OMIT_WAL
// /* Fill in Pager.zWal */
// #ifndef SQLITE_OMIT_WAL // if( nPathname>0 ){
// /* Fill in Pager.zWal */ // pPager->zWal = (char*)pPtr;
// if( nPathname>0 ){ // memcpy(pPtr, zPathname, nPathname); pPtr += nPathname;
// pPager->zWal = (char*)pPtr; // memcpy(pPtr, "-wal", 4); pPtr += 4 + 1;
// memcpy(pPtr, zPathname, nPathname); pPtr += nPathname; // #ifdef SQLITE_ENABLE_8_3_NAMES
// memcpy(pPtr, "-wal", 4); pPtr += 4 + 1; // sqlite3FileSuffix3(zFilename, pPager->zWal);
// #ifdef SQLITE_ENABLE_8_3_NAMES // pPtr = (u8*)(pPager->zWal + sqlite3Strlen30(pPager->zWal)+1);
// sqlite3FileSuffix3(zFilename, pPager->zWal); // #endif
// pPtr = (u8*)(pPager->zWal + sqlite3Strlen30(pPager->zWal)+1); // }else{
// #endif // pPager->zWal = 0;
// }else{ // }
// pPager->zWal = 0; // #endif
// } // (void)pPtr; /* Suppress warning about unused pPtr value */
// #endif
// (void)pPtr; /* Suppress warning about unused pPtr value */ // if( nPathname ) sqlite3DbFree(0, zPathname);
// pPager->pVfs = pVfs;
// if( nPathname ) sqlite3DbFree(0, zPathname); // pPager->vfsFlags = vfsFlags;
// pPager->pVfs = pVfs;
// pPager->vfsFlags = vfsFlags; // /* Open the pager file.
// */
// /* Open the pager file. // if( zFilename && zFilename[0] ){
// */ // int fout = 0; /* VFS flags returned by xOpen() */
// if( zFilename && zFilename[0] ){ // rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout);
// int fout = 0; /* VFS flags returned by xOpen() */ // assert( !memDb );
// rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout); // #ifndef SQLITE_OMIT_DESERIALIZE
// assert( !memDb ); // pPager->memVfs = memJM = (fout&SQLITE_OPEN_MEMORY)!=0;
// #ifndef SQLITE_OMIT_DESERIALIZE // #endif
// pPager->memVfs = memJM = (fout&SQLITE_OPEN_MEMORY)!=0; // readOnly = (fout&SQLITE_OPEN_READONLY)!=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
// /* If the file was successfully opened for read/write access, // ** database file. The default page size is the maximum of:
// ** 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()
// ** + SQLITE_DEFAULT_PAGE_SIZE, // ** + The largest page size that can be written atomically.
// ** + The value returned by sqlite3OsSectorSize() // */
// ** + The largest page size that can be written atomically. // if( rc==SQLITE_OK ){
// */ // int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
// if( rc==SQLITE_OK ){ // if( !readOnly ){
// int iDc = sqlite3OsDeviceCharacteristics(pPager->fd); // setSectorSize(pPager);
// if( !readOnly ){ // assert(SQLITE_DEFAULT_PAGE_SIZE<=SQLITE_MAX_DEFAULT_PAGE_SIZE);
// setSectorSize(pPager); // if( szPageDflt<pPager->sectorSize ){
// assert(SQLITE_DEFAULT_PAGE_SIZE<=SQLITE_MAX_DEFAULT_PAGE_SIZE); // if( pPager->sectorSize>SQLITE_MAX_DEFAULT_PAGE_SIZE ){
// if( szPageDflt<pPager->sectorSize ){ // szPageDflt = SQLITE_MAX_DEFAULT_PAGE_SIZE;
// if( pPager->sectorSize>SQLITE_MAX_DEFAULT_PAGE_SIZE ){ // }else{
// szPageDflt = SQLITE_MAX_DEFAULT_PAGE_SIZE; // szPageDflt = (u32)pPager->sectorSize;
// }else{ // }
// szPageDflt = (u32)pPager->sectorSize; // }
// } // #ifdef SQLITE_ENABLE_ATOMIC_WRITE
// } // {
// #ifdef SQLITE_ENABLE_ATOMIC_WRITE // int ii;
// { // assert(SQLITE_IOCAP_ATOMIC512==(512>>8));
// int ii; // assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8));
// assert(SQLITE_IOCAP_ATOMIC512==(512>>8)); // assert(SQLITE_MAX_DEFAULT_PAGE_SIZE<=65536);
// assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8)); // for(ii=szPageDflt; ii<=SQLITE_MAX_DEFAULT_PAGE_SIZE; ii=ii*2){
// assert(SQLITE_MAX_DEFAULT_PAGE_SIZE<=65536); // if( iDc&(SQLITE_IOCAP_ATOMIC|(ii>>8)) ){
// for(ii=szPageDflt; ii<=SQLITE_MAX_DEFAULT_PAGE_SIZE; ii=ii*2){ // szPageDflt = ii;
// if( iDc&(SQLITE_IOCAP_ATOMIC|(ii>>8)) ){ // }
// szPageDflt = ii; // }
// } // }
// } // #endif
// } // }
// #endif // pPager->noLock = sqlite3_uri_boolean(pPager->zFilename, "nolock", 0);
// } // if( (iDc & SQLITE_IOCAP_IMMUTABLE)!=0
// pPager->noLock = sqlite3_uri_boolean(pPager->zFilename, "nolock", 0); // || sqlite3_uri_boolean(pPager->zFilename, "immutable", 0) ){
// if( (iDc & SQLITE_IOCAP_IMMUTABLE)!=0 // vfsFlags |= SQLITE_OPEN_READONLY;
// || sqlite3_uri_boolean(pPager->zFilename, "immutable", 0) ){ // goto act_like_temp_file;
// vfsFlags |= SQLITE_OPEN_READONLY; // }
// goto act_like_temp_file; // }
// } // }else{
// } // /* If a temporary file is requested, it is not opened immediately.
// }else{ // ** In this case we accept the default page size and delay actually
// /* If a temporary file is requested, it is not opened immediately. // ** opening the file until the first call to OsWrite().
// ** 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
// ** This branch is also run for an in-memory database. An in-memory // ** disk and uses an in-memory rollback journal.
// ** 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.
// ** // */
// ** This branch also runs for files marked as immutable. // act_like_temp_file:
// */ // tempFile = 1;
// act_like_temp_file: // pPager->eState = PAGER_READER; /* Pretend we already have a lock */
// tempFile = 1; // pPager->eLock = EXCLUSIVE_LOCK; /* Pretend we are in EXCLUSIVE mode */
// pPager->eState = PAGER_READER; /* Pretend we already have a lock */ // pPager->noLock = 1; /* Do no locking */
// pPager->eLock = EXCLUSIVE_LOCK; /* Pretend we are in EXCLUSIVE mode */ // readOnly = (vfsFlags&SQLITE_OPEN_READONLY);
// 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.
// /* 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 );
// if( rc==SQLITE_OK ){ // rc = sqlite3PagerSetPagesize(pPager, &szPageDflt, -1);
// assert( pPager->memDb==0 ); // testcase( rc!=SQLITE_OK );
// rc = sqlite3PagerSetPagesize(pPager, &szPageDflt, -1); // }
// testcase( rc!=SQLITE_OK );
// } // /* Initialize the PCache object. */
// if( rc==SQLITE_OK ){
// /* Initialize the PCache object. */ // nExtra = ROUND8(nExtra);
// if( rc==SQLITE_OK ){ // assert( nExtra>=8 && nExtra<1000 );
// nExtra = ROUND8(nExtra); // rc = sqlite3PcacheOpen(szPageDflt, nExtra, !memDb,
// assert( nExtra>=8 && nExtra<1000 ); // !memDb?pagerStress:0, (void *)pPager, pPager->pPCache);
// 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 an error occurred above, free the Pager structure and close the file. // if( rc!=SQLITE_OK ){
// */ // sqlite3OsClose(pPager->fd);
// if( rc!=SQLITE_OK ){ // sqlite3PageFree(pPager->pTmpSpace);
// sqlite3OsClose(pPager->fd); // sqlite3_free(pPager);
// sqlite3PageFree(pPager->pTmpSpace); // return rc;
// 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->useJournal = (u8)useJournal; // /* pPager->stmtInUse = 0; */
// /* pPager->stmtOpen = 0; */ // /* pPager->nRef = 0; */
// /* pPager->stmtInUse = 0; */ // /* pPager->stmtSize = 0; */
// /* pPager->nRef = 0; */ // /* pPager->stmtJSize = 0; */
// /* pPager->stmtSize = 0; */ // /* pPager->nPage = 0; */
// /* pPager->stmtJSize = 0; */ // pPager->mxPgno = SQLITE_MAX_PAGE_COUNT;
// /* pPager->nPage = 0; */ // /* pPager->state = PAGER_UNLOCK; */
// pPager->mxPgno = SQLITE_MAX_PAGE_COUNT; // /* pPager->errMask = 0; */
// /* pPager->state = PAGER_UNLOCK; */ // pPager->tempFile = (u8)tempFile;
// /* pPager->errMask = 0; */ // assert( tempFile==PAGER_LOCKINGMODE_NORMAL
// pPager->tempFile = (u8)tempFile; // || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE );
// assert( tempFile==PAGER_LOCKINGMODE_NORMAL // assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 );
// || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE ); // pPager->exclusiveMode = (u8)tempFile;
// assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 ); // pPager->changeCountDone = pPager->tempFile;
// pPager->exclusiveMode = (u8)tempFile; // pPager->memDb = (u8)memDb;
// pPager->changeCountDone = pPager->tempFile; // pPager->readOnly = (u8)readOnly;
// pPager->memDb = (u8)memDb; // assert( useJournal || pPager->tempFile );
// pPager->readOnly = (u8)readOnly; // pPager->noSync = pPager->tempFile;
// assert( useJournal || pPager->tempFile ); // if( pPager->noSync ){
// pPager->noSync = pPager->tempFile; // assert( pPager->fullSync==0 );
// if( pPager->noSync ){ // assert( pPager->extraSync==0 );
// assert( pPager->fullSync==0 ); // assert( pPager->syncFlags==0 );
// assert( pPager->extraSync==0 ); // assert( pPager->walSyncFlags==0 );
// assert( pPager->syncFlags==0 ); // }else{
// assert( pPager->walSyncFlags==0 ); // pPager->fullSync = 1;
// }else{ // pPager->extraSync = 0;
// pPager->fullSync = 1; // pPager->syncFlags = SQLITE_SYNC_NORMAL;
// pPager->extraSync = 0; // pPager->walSyncFlags = SQLITE_SYNC_NORMAL | (SQLITE_SYNC_NORMAL<<2);
// pPager->syncFlags = SQLITE_SYNC_NORMAL; // }
// pPager->walSyncFlags = SQLITE_SYNC_NORMAL | (SQLITE_SYNC_NORMAL<<2); // /* pPager->pFirst = 0; */
// } // /* pPager->pFirstSynced = 0; */
// /* pPager->pFirst = 0; */ // /* pPager->pLast = 0; */
// /* pPager->pFirstSynced = 0; */ // pPager->nExtra = (u16)nExtra;
// /* pPager->pLast = 0; */ // pPager->journalSizeLimit = SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT;
// pPager->nExtra = (u16)nExtra; // assert( isOpen(pPager->fd) || tempFile );
// pPager->journalSizeLimit = SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT; // setSectorSize(pPager);
// assert( isOpen(pPager->fd) || tempFile ); // if( !useJournal ){
// setSectorSize(pPager); // pPager->journalMode = PAGER_JOURNALMODE_OFF;
// if( !useJournal ){ // }else if( memDb || memJM ){
// pPager->journalMode = PAGER_JOURNALMODE_OFF; // pPager->journalMode = PAGER_JOURNALMODE_MEMORY;
// }else if( memDb || memJM ){ // }
// pPager->journalMode = PAGER_JOURNALMODE_MEMORY; // /* pPager->xBusyHandler = 0; */
// } // /* pPager->pBusyHandlerArg = 0; */
// /* pPager->xBusyHandler = 0; */ // pPager->xReiniter = xReinit;
// /* pPager->pBusyHandlerArg = 0; */ // setGetterMethod(pPager);
// pPager->xReiniter = xReinit; // /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
// setGetterMethod(pPager); // /* pPager->szMmap = SQLITE_DEFAULT_MMAP_SIZE // will be set by btree.c */
// /* 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 // ** Return the sqlite3_file for the main database given the name
...@@ -5033,7 +5020,6 @@ ...@@ -5033,7 +5020,6 @@
// return pPager->fd; // return pPager->fd;
// } // }
// /* // /*
// ** This function is called after transitioning from PAGER_UNLOCK to // ** This function is called after transitioning from PAGER_UNLOCK to
// ** PAGER_SHARED state. It tests if there is a hot journal present in // ** PAGER_SHARED state. It tests if there is a hot journal present in
...@@ -5650,7 +5636,6 @@ ...@@ -5650,7 +5636,6 @@
// return pPager->errCode; // return pPager->errCode;
// } // }
// /* Dispatch all page fetch requests to the appropriate getter method. // /* Dispatch all page fetch requests to the appropriate getter method.
// */ // */
// int sqlite3PagerGet( // int sqlite3PagerGet(
...@@ -5790,7 +5775,6 @@ ...@@ -5790,7 +5775,6 @@
// assert( rc!=SQLITE_OK || isOpen(pPager->jfd) ); // 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. // ** the sub-journal if necessary.
// */ // */
...@@ -6589,7 +6573,6 @@ ...@@ -6589,7 +6573,6 @@
// return rc; // return rc;
// } // }
// /* // /*
// ** When this function is called, the database file has been completely // ** When this function is called, the database file has been completely
// ** updated to reflect the changes made by the current transaction and // ** updated to reflect the changes made by the current transaction and
...@@ -6879,7 +6862,6 @@ ...@@ -6879,7 +6862,6 @@
// } // }
// } // }
// /* // /*
// ** This function is called to rollback or release (commit) a savepoint. // ** 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
...@@ -7401,7 +7383,6 @@ ...@@ -7401,7 +7383,6 @@
// } // }
// #endif // #endif
// #ifndef SQLITE_OMIT_WAL // #ifndef SQLITE_OMIT_WAL
// /* // /*
// ** This function is called when the user invokes "PRAGMA wal_checkpoint", // ** This function is called when the user invokes "PRAGMA wal_checkpoint",
...@@ -7496,7 +7477,6 @@ ...@@ -7496,7 +7477,6 @@
// return rc; // return rc;
// } // }
// /* // /*
// ** The caller must be holding a SHARED lock on the database file to call // ** The caller must be holding a SHARED lock on the database file to call
// ** this function. // ** this function.
......
...@@ -46,6 +46,8 @@ typedef struct sqlite3_pcache_page { ...@@ -46,6 +46,8 @@ typedef struct sqlite3_pcache_page {
typedef struct sqlite3_vfs sqlite3_vfs; typedef struct sqlite3_vfs sqlite3_vfs;
typedef struct sqlite3 sqlite3; typedef struct sqlite3 sqlite3;
#define SQLITE_DEFAULT_PAGE_SIZE 4096
#include "pager.h" #include "pager.h"
#include "pcache.h" #include "pcache.h"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册