org.tmatesoft.sqljet.core.internal.pager
Class SqlJetPager

java.lang.Object
  extended by org.tmatesoft.sqljet.core.internal.pager.SqlJetPager
All Implemented Interfaces:
ISqlJetLimits, ISqlJetPageCallback, ISqlJetPager

public class SqlJetPager
extends java.lang.Object
implements ISqlJetPager, ISqlJetLimits, ISqlJetPageCallback

A open page cache is an instance of the following structure. Pager.errCode may be set to SQLITE_IOERR, SQLITE_CORRUPT, or or SQLITE_FULL. Once one of the first three errors occurs, it persists and is returned as the result of every major pager API call. The SQLITE_FULL return code is slightly different. It persists only until the next successful rollback is performed on the pager cache. Also, SQLITE_FULL does not affect the sqlite3PagerGet() and sqlite3PagerLookup() APIs, they may still be used successfully. Managing the size of the database file in pages is a little complicated. The variable Pager.dbSize contains the number of pages that the database image currently contains. As the database image grows or shrinks this variable is updated. The variable Pager.dbFileSize contains the number of pages in the database file. This may be different from Pager.dbSize if some pages have been appended to the database image but not yet written out from the cache to the actual file on disk. Or if the image has been truncated by an incremental-vacuum operation. The Pager.dbOrigSize variable contains the number of pages in the database image when the current transaction was opened. The contents of all three of these variables is only guaranteed to be correct if the boolean Pager.dbSizeValid is true.


Field Summary
 
Fields inherited from interface org.tmatesoft.sqljet.core.internal.ISqlJetPager
aJournalMagic, JOURNAL, MEMORY_DB, PAGER_MAX_PGNO, SQLJET_DEFAULT_JOURNAL_SIZE_LIMIT, SQLJET_MIN_SECTOR_SIZE
 
Fields inherited from interface org.tmatesoft.sqljet.core.internal.ISqlJetLimits
SQLJET_DEFAULT_CACHE_SIZE, SQLJET_DEFAULT_PAGE_SIZE, SQLJET_DEFAULT_TEMP_CACHE_SIZE, SQLJET_MAX_ATTACHED, SQLJET_MAX_COLUMN, SQLJET_MAX_COMPOUND_SELECT, SQLJET_MAX_DEFAULT_PAGE_SIZE, SQLJET_MAX_EXPR_DEPTH, SQLJET_MAX_FILE_FORMAT, SQLJET_MAX_FUNCTION_ARG, SQLJET_MAX_LENGTH, SQLJET_MAX_LIKE_PATTERN_LENGTH, SQLJET_MAX_PAGE_COUNT, SQLJET_MAX_PAGE_SIZE, SQLJET_MAX_SQL_LENGTH, SQLJET_MAX_VARIABLE_NUMBER, SQLJET_MAX_VDBE_OP, SQLJET_MIN_FILE_FORMAT, SQLJET_MIN_PAGE_SIZE
 
Constructor Summary
SqlJetPager()
           
 
Method Summary
 ISqlJetPage acquirePage(int pageNumber, boolean read)
          Acquire a page.
 void begin(boolean exclusive)
          Acquire a write-lock on the database.
 void close()
          Shutdown the page cache.
 void commitPhaseOne(java.lang.String master, boolean noSync)
          Sync the database file for the pager pPager.
 void commitPhaseTwo()
          Commit all changes to the database and release the write lock.
 int getCacheSize()
           
 java.io.File getDirectoryName()
          Return the directory of the database file.
 ISqlJetFile getFile()
          Return the file handle for the database file associated with the pager.
 java.io.File getFileName()
          Return the path of the database file.
 ISqlJetFileSystem getFileSystem()
          Return the file system for the pager.
 SqlJetPagerJournalMode getJournalMode()
          Get the journal-mode for this pager.
 java.io.File getJournalName()
          Return the path of the journal file.
 long getJournalSizeLimit()
          Get the size-limit used for persistent journal files.
 SqlJetPagerLockingMode getLockingMode()
          Get the locking-mode for this pager.
 int getMaxPageCount()
          Return the current maximum page count.
 ISqlJetPage getPage(int pageNumber)
          Just call acquire( pageNumber, true);
 int getPageCount()
          Return the total number of pages in the disk file associated with pager.
 int getPageSize()
          Get the page size.
 int getRefCount()
          Return the number of references to the pager.
 SqlJetSafetyLevel getSafetyLevel()
          Get safety level
 ISqlJetMemoryPointer getTempSpace()
          Return a pointer to the "temporary page" buffer held internally by the pager.
 int imageSize()
          Return the current size of the database file image in pages.
 boolean isNoSync()
          Return true if fsync() calls are disabled for this pager.
 boolean isReadOnly()
          Return TRUE if the database file is opened read-only.
 ISqlJetPage lookupPage(int pageNumber)
          Acquire a page if it is already in the in-memory cache.
 void open(ISqlJetFileSystem fileSystem, java.io.File fileName, java.util.Set<SqlJetPagerFlags> flags, SqlJetFileType type, java.util.Set<SqlJetFileOpenPermission> permissions)
          Open a new page cache.
 void openSavepoint(int nSavepoint)
          Ensure that there are at least nSavepoint savepoints open.
 void pageCallback(ISqlJetPage page)
           
 void readFileHeader(int count, ISqlJetMemoryPointer buffer)
          Read the first N bytes from the beginning of the file into memory that buffer points to.
 void rollback()
          Rollback all changes.
 void savepoint(SqlJetSavepointOperation op, int iSavepoint)
          Parameter op is always either SAVEPOINT_ROLLBACK or SAVEPOINT_RELEASE.
 void setBusyhandler(ISqlJetBusyHandler busyHandler)
          Set the busy handler function.
 void setCacheSize(int cacheSize)
          Change the maximum number of in-memory pages that are allowed.
 void setJournalMode(SqlJetPagerJournalMode journalMode)
          Set the journal-mode for this pager.
 void setJournalSizeLimit(long limit)
          Set the size-limit used for persistent journal files.
 void setLockingMode(SqlJetPagerLockingMode lockingMode)
          Set the locking-mode for this pager.
 void setMaxPageCount(int maxPageCount)
          Attempt to set the maximum database page count if mxPage is positive.
 int setPageSize(int pageSize)
          Set the page size to pageSize.
 void setReiniter(ISqlJetPageCallback reinitier)
          Set the reinitializer for this pager.
 void setSafetyLevel(SqlJetSafetyLevel safetyLevel)
          Set safety level
 void sync()
          Sync the pager file to disk.
 void truncateImage(int pagesNumber)
          Truncate the in-memory database file image to nPage pages.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

SqlJetPager

public SqlJetPager()
Method Detail

open

public void open(ISqlJetFileSystem fileSystem,
                 java.io.File fileName,
                 java.util.Set<SqlJetPagerFlags> flags,
                 SqlJetFileType type,
                 java.util.Set<SqlJetFileOpenPermission> permissions)
          throws SqlJetException
Description copied from interface: ISqlJetPager
Open a new page cache. The file to be cached need not exist. The file is not locked until the first call to ISqlJetPager.getPage(int) and is only held open until the last page is released using #unref(ISqlJetPage). If fileName is null then a randomly-named temporary file is created and used as the file to be cached. The file will be deleted automatically when it is closed. If fileName is ISqlJetPager.MEMORY_DB then all information is held in cache. It is never written to disk. This can be used to implement an in-memory database.

Specified by:
open in interface ISqlJetPager
Parameters:
fileSystem - The file system to use
fileName - Name of the database file to open
flags - flags controlling this file
type - file type passed through to ISqlJetFileSystem.open(java.io.File, SqlJetFileType, Set)
permissions - permissions passed through to ISqlJetFileSystem.open(java.io.File, SqlJetFileType, Set)
Throws:
SqlJetException

getDirectoryName

public java.io.File getDirectoryName()
Description copied from interface: ISqlJetPager
Return the directory of the database file.

Specified by:
getDirectoryName in interface ISqlJetPager
Returns:

getFileName

public java.io.File getFileName()
Description copied from interface: ISqlJetPager
Return the path of the database file.

Specified by:
getFileName in interface ISqlJetPager
Returns:

getFileSystem

public ISqlJetFileSystem getFileSystem()
Description copied from interface: ISqlJetPager
Return the file system for the pager.

Specified by:
getFileSystem in interface ISqlJetPager
Returns:

getFile

public ISqlJetFile getFile()
Description copied from interface: ISqlJetPager
Return the file handle for the database file associated with the pager. This might return NULL if the file has not yet been opened.

Specified by:
getFile in interface ISqlJetPager
Returns:

getJournalName

public java.io.File getJournalName()
Description copied from interface: ISqlJetPager
Return the path of the journal file.

Specified by:
getJournalName in interface ISqlJetPager
Returns:

isNoSync

public boolean isNoSync()
Description copied from interface: ISqlJetPager
Return true if fsync() calls are disabled for this pager. Return FALSE if fsync()s are executed normally.

Specified by:
isNoSync in interface ISqlJetPager
Returns:

isReadOnly

public boolean isReadOnly()
Description copied from interface: ISqlJetPager
Return TRUE if the database file is opened read-only. Return FALSE if the database is (in theory) writable.

Specified by:
isReadOnly in interface ISqlJetPager
Returns:

getLockingMode

public SqlJetPagerLockingMode getLockingMode()
Description copied from interface: ISqlJetPager
Get the locking-mode for this pager.

Specified by:
getLockingMode in interface ISqlJetPager
Returns:

setLockingMode

public void setLockingMode(SqlJetPagerLockingMode lockingMode)
Description copied from interface: ISqlJetPager
Set the locking-mode for this pager.

Specified by:
setLockingMode in interface ISqlJetPager

getJournalMode

public SqlJetPagerJournalMode getJournalMode()
Description copied from interface: ISqlJetPager
Get the journal-mode for this pager.

Specified by:
getJournalMode in interface ISqlJetPager
Returns:

setJournalMode

public void setJournalMode(SqlJetPagerJournalMode journalMode)
Description copied from interface: ISqlJetPager
Set the journal-mode for this pager.

Specified by:
setJournalMode in interface ISqlJetPager

getJournalSizeLimit

public long getJournalSizeLimit()
Description copied from interface: ISqlJetPager
Get the size-limit used for persistent journal files.

Specified by:
getJournalSizeLimit in interface ISqlJetPager
Returns:

setJournalSizeLimit

public void setJournalSizeLimit(long limit)
Description copied from interface: ISqlJetPager
Set the size-limit used for persistent journal files.

Specified by:
setJournalSizeLimit in interface ISqlJetPager

getSafetyLevel

public SqlJetSafetyLevel getSafetyLevel()
Description copied from interface: ISqlJetPager
Get safety level

Specified by:
getSafetyLevel in interface ISqlJetPager
Returns:

setSafetyLevel

public void setSafetyLevel(SqlJetSafetyLevel safetyLevel)
Description copied from interface: ISqlJetPager
Set safety level

Specified by:
setSafetyLevel in interface ISqlJetPager

getTempSpace

public ISqlJetMemoryPointer getTempSpace()
Description copied from interface: ISqlJetPager
Return a pointer to the "temporary page" buffer held internally by the pager. This is a buffer that is big enough to hold the entire content of a database page. This buffer is used internally during rollback and will be overwritten whenever a rollback occurs. But other modules are free to use it too, as long as no rollbacks are happening.

Specified by:
getTempSpace in interface ISqlJetPager
Returns:

setBusyhandler

public void setBusyhandler(ISqlJetBusyHandler busyHandler)
Description copied from interface: ISqlJetPager
Set the busy handler function.

Specified by:
setBusyhandler in interface ISqlJetPager

setReiniter

public void setReiniter(ISqlJetPageCallback reinitier)
Description copied from interface: ISqlJetPager
Set the reinitializer for this pager. If not NULL, the reinitializer is called when the content of a page in cache is restored to its original value as a result of a rollback. The callback gives higher-level code an opportunity to restore the EXTRA section to agree with the restored page data.

Specified by:
setReiniter in interface ISqlJetPager

setPageSize

public int setPageSize(int pageSize)
                throws SqlJetException
Description copied from interface: ISqlJetPager
Set the page size to pageSize. If the suggest new page size is inappropriate, then an alternative page size is set to that value before returning.

Specified by:
setPageSize in interface ISqlJetPager
Returns:
Throws:
SqlJetException

getPageSize

public int getPageSize()
Description copied from interface: ISqlJetPager
Get the page size.

Specified by:
getPageSize in interface ISqlJetPager
Returns:

setMaxPageCount

public void setMaxPageCount(int maxPageCount)
                     throws SqlJetException
Description copied from interface: ISqlJetPager
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.

Specified by:
setMaxPageCount in interface ISqlJetPager
Throws:
SqlJetException

getMaxPageCount

public int getMaxPageCount()
Description copied from interface: ISqlJetPager
Return the current maximum page count.

Specified by:
getMaxPageCount in interface ISqlJetPager
Returns:

setCacheSize

public void setCacheSize(int cacheSize)
Description copied from interface: ISqlJetPager
Change the maximum number of in-memory pages that are allowed.

Specified by:
setCacheSize in interface ISqlJetPager

getCacheSize

public int getCacheSize()
Specified by:
getCacheSize in interface ISqlJetPager
Returns:

readFileHeader

public void readFileHeader(int count,
                           ISqlJetMemoryPointer buffer)
                    throws SqlJetIOException
Description copied from interface: ISqlJetPager
Read the first N bytes from the beginning of the file into memory that buffer points to. No error checking is done. The rational for this is that this function may be called even if the file does not exist or contain a header. In these cases sqlite3OsRead() will return an error, to which the correct response is to zero the memory at pDest and continue. A real IO error will presumably recur and be picked up later (Todo: Think about this).

Specified by:
readFileHeader in interface ISqlJetPager
Throws:
SqlJetIOException

getPageCount

public int getPageCount()
                 throws SqlJetException
Description copied from interface: ISqlJetPager
Return the total number of pages in the disk file associated with pager. If the PENDING_BYTE lies on the page directly after the end of the file, then consider this page part of the file too. For example, if PENDING_BYTE is byte 4096 (the first byte of page 5) and the size of the file is 4096 bytes, 5 is returned instead of 4.

Specified by:
getPageCount in interface ISqlJetPager
Returns:
pages count
Throws:
SqlJetException - if pager is in error state.

close

public void close()
           throws SqlJetException
Description copied from interface: ISqlJetPager
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.

Specified by:
close in interface ISqlJetPager
Throws:
SqlJetException

acquirePage

public ISqlJetPage acquirePage(int pageNumber,
                               boolean read)
                        throws SqlJetException
Description copied from interface: ISqlJetPager
Acquire a page. A read lock on the disk file is obtained when the first page is acquired. This read lock is dropped when the last page is released. This routine works for any page number greater than 0. If the database file is smaller than the requested page, then no actual disk read occurs and the memory image of the page is initialized to all zeros. The extra data appended to a page is always initialized to zeros the first time a page is loaded into memory. The acquisition might fail for several reasons. In all cases, an appropriate error code is returned and *ppPage is set to NULL. See also ISqlJetPager.lookupPage(int). Both this routine and ISqlJetPager.lookupPage(int) attempt to find a page in the in-memory cache first. If the page is not already in memory, this routine goes to disk to read it in whereas ISqlJetPager.lookupPage(int) just returns 0. This routine acquires a read-lock the first time it has to go to disk, and could also playback an old journal if necessary. Since ISqlJetPager.lookupPage(int) never goes to disk, it never has to deal with locks or journal files. If noContent is false, the page contents are actually read from disk. If noContent is true, it means that we do not care about the contents of the page at this time, so do not do a disk read. Just fill in the page content with zeros. But mark the fact that we have not read the content by setting the PgHdr.needRead flag. Later on, if sqlite3PagerWrite() is called on this page or if this routine is called again with noContent==0, that means that the content is needed and the disk read should occur at that point.

Specified by:
acquirePage in interface ISqlJetPager
Parameters:
pageNumber - Page number to fetch
read - Do not bother reading content from disk if false
Returns:
Throws:
SqlJetException

getPage

public ISqlJetPage getPage(int pageNumber)
                    throws SqlJetException
Description copied from interface: ISqlJetPager
Just call acquire( pageNumber, true);

Specified by:
getPage in interface ISqlJetPager
Parameters:
pageNumber - Page number to fetch
Returns:
Throws:
SqlJetException

lookupPage

public ISqlJetPage lookupPage(int pageNumber)
                       throws SqlJetException
Description copied from interface: ISqlJetPager
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 null if the page is not in cache. See also ISqlJetPager.getPage(int). The difference between this routine and ISqlJetPager.getPage(int) is that ISqlJetPager.getPage(int) 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 has ever happened.

Specified by:
lookupPage in interface ISqlJetPager
Parameters:
pageNumber - Page number to lookup
Returns:
Throws:
SqlJetException

truncateImage

public void truncateImage(int pagesNumber)
Description copied from interface: ISqlJetPager
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.

Specified by:
truncateImage in interface ISqlJetPager

imageSize

public int imageSize()
Description copied from interface: ISqlJetPager
Return the current size of the database file image in pages. This function differs from sqlite3PagerPagecount() in two ways: a) It may only be called when at least one reference to a database page is held. This guarantees that the database size is already known and a call to sqlite3OsFileSize() is not required. b) The return value is not adjusted for the locking page.

Specified by:
imageSize in interface ISqlJetPager

begin

public void begin(boolean exclusive)
           throws SqlJetException
Description copied from interface: ISqlJetPager
Acquire a write-lock on the database. The lock is removed when the any of the following happen: The parameter indicates how much space in bytes to reserve for a master journal file-name at the start of the journal when it is created. A journal file is opened if this is not a temporary file. For temporary files, the opening of the journal file is deferred until there is an actual need to write to the journal. If the database is already reserved for writing, this routine is a no-op. If exclusive is true, go ahead and get an EXCLUSIVE lock on the file immediately instead of waiting until we try to flush the cache. The exclusive is ignored if a transaction is already active.

Specified by:
begin in interface ISqlJetPager
Throws:
SqlJetException

commitPhaseOne

public void commitPhaseOne(java.lang.String master,
                           boolean noSync)
                    throws SqlJetException
Description copied from interface: ISqlJetPager
Sync the database file for the pager pPager. zMaster points to the name of a master journal file that should be written into the individual journal file. zMaster may be NULL, which is interpreted as no master journal (a single database transaction). This routine ensures that the journal is synced, all dirty pages written to the database file and the database file synced. The only thing that remains to commit the transaction is to delete the journal file (or master journal file if specified). Note that if zMaster==NULL, this does not overwrite a previous value passed to an sqlite3PagerCommitPhaseOne() call. If the final parameter - noSync - is true, then the database file itself is not synced. The caller must call sqlite3PagerSync() directly to sync the database file before calling CommitPhaseTwo() to delete the journal file in this case.

Specified by:
commitPhaseOne in interface ISqlJetPager
Throws:
SqlJetException

commitPhaseTwo

public void commitPhaseTwo()
                    throws SqlJetException
Description copied from interface: ISqlJetPager
Commit all changes to the database and release the write lock. If the commit fails for any reason, a rollback attempt is made and an error code is returned. If the commit worked, SQLITE_OK is returned.

Specified by:
commitPhaseTwo in interface ISqlJetPager
Throws:
SqlJetException

rollback

public void rollback()
              throws SqlJetException
Description copied from interface: ISqlJetPager
Rollback all changes. The database falls back to PAGER_SHARED mode. All in-memory cache pages revert to their original data contents. The journal is deleted. This routine cannot fail unless some other process is not following the correct locking protocol or unless some other process is writing trash into the journal file (SQLITE_CORRUPT) or unless a prior malloc() failed (SQLITE_NOMEM). Appropriate error codes are returned for all these occasions. Otherwise, SQLITE_OK is returned.

Specified by:
rollback in interface ISqlJetPager
Throws:
SqlJetException

sync

public void sync()
          throws SqlJetIOException
Description copied from interface: ISqlJetPager
Sync the pager file to disk.

Specified by:
sync in interface ISqlJetPager
Throws:
SqlJetIOException

getRefCount

public int getRefCount()
Description copied from interface: ISqlJetPager
Return the number of references to the pager.

Specified by:
getRefCount in interface ISqlJetPager
Returns:

pageCallback

public void pageCallback(ISqlJetPage page)
Specified by:
pageCallback in interface ISqlJetPageCallback

openSavepoint

public void openSavepoint(int nSavepoint)
                   throws SqlJetException
Ensure that there are at least nSavepoint savepoints open.

Specified by:
openSavepoint in interface ISqlJetPager
Throws:
SqlJetException

savepoint

public void savepoint(SqlJetSavepointOperation op,
                      int iSavepoint)
               throws SqlJetException
Parameter op is always either SAVEPOINT_ROLLBACK or SAVEPOINT_RELEASE. If it is SAVEPOINT_RELEASE, then release and destroy the savepoint with index iSavepoint. If it is SAVEPOINT_ROLLBACK, then rollback all changes that have occured since savepoint iSavepoint was created. In either case, all savepoints with an index greater than iSavepoint are destroyed. If there are less than (iSavepoint+1) active savepoints when this function is called it is a no-op.

Specified by:
savepoint in interface ISqlJetPager
Throws:
SqlJetException