Package org.tmatesoft.sqljet.core

Examples of org.tmatesoft.sqljet.core.SqlJetException


    /**
     * @throws SqlJetExceptionRemove
     */
    private void checkErrorCode() throws SqlJetException {
        if (null != errCode)
            throw new SqlJetException(errCode);
    }
View Full Code Here


        assert (state == SqlJetPagerState.UNLOCK || pageCache.getRefCount() > 0 || pageNumber == 1);

        if (pageNumber > PAGER_MAX_PGNO || pageNumber == 0
                || pageNumber == ((ISqlJetFile.PENDING_BYTE / (pageSize)) + 1)) {
            throw new SqlJetException(SqlJetErrorCode.CORRUPT);
        }

        /*
         * If this is the first page accessed, then get a SHARED lock on the
         * database file. pagerSharedLock() is a no-op if a database lock is
         * already held.
         */
        sharedLock();
        assert (state != SqlJetPagerState.UNLOCK);

        final ISqlJetPage page = pageCache.fetch(pageNumber, true);

        if (null == page) {
            throw new SqlJetException(SqlJetErrorCode.INTERNAL, "Page cache is overflow");
        }

        if (null == page.getPager()) {
            /*
             * The pager cache has created a new page. Its content needs to be
             * initialized.
             */
            page.setPager(this);

            int nMax;
            try {
                nMax = getPageCount();
            } catch (SqlJetException e) {
                page.unref();
                throw e;
            }

            if (nMax < pageNumber || memDb || !read) {

                if (pageNumber > mxPgno) {
                    page.unref();
                    throw new SqlJetException(SqlJetErrorCode.FULL);
                }

                SqlJetUtility.memset(page.getData(), (byte) 0, pageSize);
                if (!read) {
                    if (null == page.getFlags())
View Full Code Here

         * If the pager is still in an error state, do not proceed. The error
         * state will be cleared at some point in the future when all page
         * references are dropped and the cache can be discarded.
         */
        if (null != errCode && errCode != SqlJetErrorCode.FULL) {
            throw new SqlJetException(errCode);
        }

        if (SqlJetPagerState.UNLOCK == state || isErrorReset)
            try {

                boolean isHotJournal = false;
                assert (!memDb);
                assert (pageCache.getRefCount() == 0);

                if (!noReadlock) {
                    try {
                        waitOnLock(SqlJetLockType.SHARED);
                    } catch (SqlJetException e) {
                        assert (state == SqlJetPagerState.UNLOCK);
                        error(e);
                        throw e;
                    }
                } else if (state == SqlJetPagerState.UNLOCK) {
                    state = SqlJetPagerState.SHARED;
                }
                assert (SqlJetPagerState.SHARED == state);

                /*
                 * If a journal file exists, and there is no RESERVED lock on
                 * the database file, then it either needs to be played back or
                 * deleted.
                 */
                if (!isErrorReset) {
                    isHotJournal = hasHotJournal();
                }

                if (isErrorReset || isHotJournal) {
                    /*
                     * Get an EXCLUSIVE lock on the database file. At this point
                     * it is important that a RESERVED lock is not obtained on
                     * the way to the EXCLUSIVE lock. If it were, another
                     * process might open the database file, detect the RESERVED
                     * lock, and conclude that the database is safe to read
                     * while this process is still rolling it back.
                     *
                     * Because the intermediate RESERVED lock is not requested,
                     * the second process will get to this point in the code and
                     * fail to obtain its own EXCLUSIVE lock on the database
                     * file.
                     */
                    if (SqlJetPagerState.EXCLUSIVE.compareTo(state) > 0) {
                        try {
                            fd.lock(SqlJetLockType.EXCLUSIVE);
                        } catch (SqlJetException e) {
                            error(e);
                            throw e;
                        }
                        state = SqlJetPagerState.EXCLUSIVE;
                    }

                    /*
                     * Open the journal for read/write access. This is because
                     * in exclusive-access mode the file descriptor will be kept
                     * open and possibly used for a transaction later on. On
                     * some systems, the OsTruncate() call used in
                     * exclusive-access mode also requires a read/write file
                     * handle.
                     */
                    if (null == jfd) {

                        if (fileSystem.access(journal, SqlJetFileAccesPermission.EXISTS)) {

                            assert (!tempFile);

                            jfd = fileSystem.open(journal, SqlJetFileType.MAIN_JOURNAL, SqlJetUtility
                                    .of(SqlJetFileOpenPermission.READWRITE));
                            if (null != jfd) {
                                try {
                                    final Set<SqlJetFileOpenPermission> p = jfd.getPermissions();
                                    if (p.contains(SqlJetFileOpenPermission.READONLY))
                                        throw new SqlJetException(SqlJetErrorCode.CANTOPEN);
                                } catch (SqlJetException e) {
                                    jfd.close();
                                    throw e;
                                }
                            }

                        } else {
                            /*
                             * If the journal does not exist, it usually means
                             * that some other connection managed to get in and
                             * roll it back before this connection obtained the
                             * exclusive lock above. Or, it may mean that the
                             * pager was in the error-state when this function
                             * was called and the journal file does not exist.
                             */
                            endTransaction(false);
                        }

                        journalOpen = true;
                        journalStarted = false;
                        journalOff = 0;
                        setMaster = false;
                        journalHdr = 0;

                        /*
                         * Playback and delete the journal. Drop the database
                         * write lock and reacquire the read lock. Purge the
                         * cache before playing back the hot-journal so that we
                         * don't end up with an inconsistent cache.
                         */
                        try {
                            pageCache.clear();
                        } finally {
                            if (null != jfd) {
                                try {
                                    playback(true);
                                } catch (SqlJetException e) {
                                    error(e);
                                    throw e;
                                }
                            }
                        }
                        assert (SqlJetPagerState.SHARED == state || (SqlJetPagerLockingMode.EXCLUSIVE == lockingMode && SqlJetPagerState.SHARED
                                .compareTo(state) < 0));

                    }

                }

                if (pageCache.getPageCount() > 0) {
                    /*
                     * The shared-lock has just been acquired on the database
                     * file and there are already pages in the cache (from a
                     * previous read or write transaction). Check to see if the
                     * database has been modified. If the database has changed,
                     * flush the cache.
                     *
                     * Database changes is detected by looking at 15 bytes
                     * beginning at offset 24 into the file. The first 4 of
                     * these 16 bytes are a 32-bit counter that is incremented
                     * with each change. The other bytes change randomly with
                     * each file change when a codec is in use.
                     *
                     * There is a vanishingly small chance that a change will
                     * not be detected. The chance of an undetected change is so
                     * small that it can be neglected.
                     */
                    ISqlJetMemoryPointer dbFileVers = SqlJetUtility.allocatePtr(this.dbFileVers.remaining());
                    getPageCount();

                    if (null != errCode) {
                        throw new SqlJetException(errCode);
                    }

                    assert (dbSizeValid);
                    if (dbSize > 0) {
                        PAGERTRACE("CKVERS %s %d\n", PAGERID(), dbFileVers.remaining());
View Full Code Here

     * @param isHot
     * @throws SqlJetException
     */
    private void playback(boolean isHot) throws SqlJetException {

        SqlJetException rc = null;

        long szJ; /* Size of the journal file in bytes */
        int nRec = -1; /* Number of Records in the journal */
        int u; /* Unsigned loop counter */
        int mxPg = 0; /* Size of the original file in pages */
        boolean res = true; /* Value returned by sqlite3OsAccess() */
        String zMaster = null; /* Name of master journal file if any */

        /*
         * Figure out how many records are in the journal. Abort early if the
         * journal is empty.
         */
        assert (journalOpen);

        try {
            szJ = jfd.fileSize();
            if (szJ == 0) {
                return;
            }

            /*
             * Read the master journal name from the journal, if it is present.
             * If a master journal file name is specified, but the file is not
             * present on disk, then the journal is not hot and does not need to
             * be played back.
             */
            zMaster = readMasterJournal(jfd);
            if (null != zMaster) {
                res = fileSystem.access(new File(zMaster), SqlJetFileAccesPermission.EXISTS);
            }
            if (!res) {
                return;
            }
            journalOff = 0;

            /*
             * This loop terminates either when the readJournalHdr() call
             * returns SQLITE_DONE or an IO error occurs.
             */
            while (true) {

                /*
                 * Read the next journal header from the journal file. If there
                 * are not enough bytes left in the journal file for a complete
                 * header, or it is corrupted, then a process must of failed
                 * while writing it. This indicates nothing more needs to be
                 * rolled back.
                 */
                try {
                    final int[] readJournalHdr = readJournalHdr(szJ);
                    nRec = readJournalHdr[0];
                    mxPg = readJournalHdr[1];
                } catch (SqlJetException e) {
                    if (SqlJetErrorCode.DONE == e.getErrorCode())
                        return;
                }

                /*
                 * If nRec is 0xffffffff, then this journal was created by a
                 * process working in no-sync mode. This means that the rest of
                 * the journal file consists of pages, there are no more journal
                 * headers. Compute the value of nRec based on this assumption.
                 */
                if (nRec == 0xffffffff) {
                    assert (journalOff == JOURNAL_HDR_SZ());
                    nRec = (int) ((szJ - JOURNAL_HDR_SZ()) / JOURNAL_PG_SZ());
                }

                /*
                 * If nRec is 0 and this rollback is of a transaction created by
                 * this process and if this is the final header in the journal,
                 * then it means that this part of the journal was being filled
                 * but has not yet been synced to disk. Compute the number of
                 * pages based on the remaining size of the file.
                 *
                 * The third term of the test was added to fix ticket #2565.
                 * When rolling back a hot journal, nRec==0 always means that
                 * the next chunk of the journal contains zero pages to be
                 * rolled back. But when doing a ROLLBACK and the nRec==0 chunk
                 * is the last chunk in the journal, it means that the journal
                 * might contain additional pages that need to be rolled back
                 * and that the number of pages should be computed based on the
                 * journal file size.
                 */
                if (nRec == 0 && !isHot && journalHdr + JOURNAL_HDR_SZ() == journalOff) {
                    nRec = (int) ((szJ - journalOff) / JOURNAL_PG_SZ());
                }

                /*
                 * If this is the first header read from the journal, truncate
                 * the database file back to its original size.
                 */
                if (journalOff == JOURNAL_HDR_SZ()) {
                    doTruncate(mxPg);
                    dbSize = mxPg;
                }

                if(isHot) {
                    reset();
                }

                /*
                 * Copy original pages out of the journal and back into the
                 * database file.
                 */
                for (u = 0; u < nRec; u++) {

                    try {
                        journalOff = playbackOnePage(true, journalOff, false, null);
                    } catch (SqlJetException e) {
                        if (e.getErrorCode() == SqlJetErrorCode.DONE) {
                            journalOff = szJ;
                            break;
                        } else {
                            /*
                             * If we are unable to rollback, then the database
                             * is probably going to end up being corrupt. It is
                             * corrupt to us, anyhow. Perhaps the next process
                             * to come along can fix it....
                             */
                            throw new SqlJetException(SqlJetErrorCode.CORRUPT);
                        }
                    }

                }
            }
View Full Code Here

     */
    private void playbackSavepoint(PagerSavepoint pSavepoint) throws SqlJetException {
        long szJ; /* Effective size of the main journal */
        long iHdrOff; /* End of first segment of main-journal records */
        int ii; /* Loop counter */
        SqlJetException rc = null; /* Return code */
        BitSet pDone = null; /* Bitvec to ensure pages played back only once */

        /* Allocate a bitvec to use to store the set of pages rolled back */
        if (pSavepoint != null) {
            pDone = new BitSet(pSavepoint.nOrig);
View Full Code Here

     * @param hasMaster
     * @throws SqlJetException
     */
    private void endTransaction(boolean hasMaster) throws SqlJetException {

        SqlJetException rc = null;
        SqlJetException rc2 = null;

        if (state.compareTo(SqlJetPagerState.RESERVED) < 0) {
            return;
        }
        releaseAllSavepoint();
View Full Code Here

     * @param doTruncate
     * @throws SqlJetException
     */
    private void zeroJournalHdr(boolean doTruncate) throws SqlJetException {

        SqlJetException rc = null;
        ISqlJetMemoryPointer zeroHdr = SqlJetUtility.allocatePtr(28);

        if (journalOff > 0) {

            long iLimit = journalSizeLimit;
View Full Code Here

         * written, it could cause invalid data to be written into the journal.
         * We need to detect this invalid data (with high probability) and
         * ignore it.
         */
        if (pgno == 0 || pgno == PAGER_MJ_PGNO()) {
            throw new SqlJetException(SqlJetErrorCode.DONE);
        }
        if (pgno > dbSize || SqlJetUtility.bitSetTest(pDone, pgno)) {
            return pOffset;
        }
        if (isMainJrnl) {
            cksum = read32bitsUnsigned(jfd, pOffset - 4);
            if (!isSavepnt && cksum(aData) != cksum) {
                throw new SqlJetException(SqlJetErrorCode.DONE);
            }
        }
        if (pDone != null) {
            pDone.set(pgno);
        }
View Full Code Here

        int iPageSize;
        int iSectorSize;

        seekJournalHdr();
        if (journalOff + JOURNAL_HDR_SZ() > journalSize) {
            throw new SqlJetException(SqlJetErrorCode.DONE);
        }
        jrnlOff = journalOff;

        jfd.read(aMagic, aMagic.remaining(), jrnlOff);
        jrnlOff += aMagic.remaining();

        if (0 != SqlJetUtility.memcmp(aMagic, aJournalMagic, aMagic.remaining())) {
            throw new SqlJetException(SqlJetErrorCode.DONE);
        }

        int pNRec = read32bits(jfd, jrnlOff);
        cksumInit = read32bitsUnsigned(jfd, jrnlOff + 4);
        int pDbSize = read32bits(jfd, jrnlOff + 8);

        result[0] = pNRec;
        result[1] = pDbSize;

        if (journalOff == 0) {
            iPageSize = read32bits(jfd, jrnlOff + 16);

            if (iPageSize < SQLJET_MIN_PAGE_SIZE || iPageSize > SQLJET_MAX_PAGE_SIZE
                    || ((iPageSize - 1) & iPageSize) != 0) {
                /*
                 * If the page-size in the journal-header is invalid, then the
                 * process that wrote the journal-header must have crashed
                 * before the header was synced. In this case stop reading the
                 * journal file here.
                 */
                throw new SqlJetException(SqlJetErrorCode.DONE);
            } else {
                setPageSize(iPageSize);
                assert (pageSize == iPageSize);
            }

            /*
             * Update the assumed sector-size to match the value used by the
             * process that created this journal. If this journal was created by
             * a process other than this one, then this routine is being called
             * from within pager_playback(). The local value of Pager.sectorSize
             * is restored at the end of that routine.
             */

            iSectorSize = read32bits(jfd, jrnlOff + 12);

            if ((iSectorSize & (iSectorSize - 1)) != 0 || iSectorSize < SQLJET_MIN_PAGE_SIZE
                    || iSectorSize > SQLJET_MAX_PAGE_SIZE) {
                throw new SqlJetException(SqlJetErrorCode.DONE);
            }
            sectorSize = iSectorSize;
        }

        journalOff += JOURNAL_HDR_SZ();
View Full Code Here

                }
            } while (lock != true);
            if (lock) {
                state = SqlJetPagerState.getPagerState(lockType);
            } else {
                throw new SqlJetException(SqlJetErrorCode.BUSY);
            }
        }
    }
View Full Code Here

TOP

Related Classes of org.tmatesoft.sqljet.core.SqlJetException

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.