Package org.tmatesoft.sqljet.core.internal

Examples of org.tmatesoft.sqljet.core.internal.ISqlJetMemoryPointer


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

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

        if (journalOff > 0) {

            long iLimit = journalSizeLimit;

            if (doTruncate || iLimit == 0) {
                try {
                    jfd.truncate(0);
                } catch (SqlJetException e) {
                    rc = e;
                }
            } else {
                try {
                    jfd.write(zeroHdr, zeroHdr.remaining(), 0);
                } catch (SqlJetException e) {
                    rc = e;
                }
            }
            if (rc == null && !noSync) {
View Full Code Here


            throws SqlJetException {

        ISqlJetPage pPg; /* An existing page in the cache */
        int pgno; /* The page number of a page in journal */
        long cksum; /* Checksum used for sanity checking */
        ISqlJetMemoryPointer aData; /* Temporary storage for the page */
        ISqlJetFile jfd; /* The file descriptor for the journal file */

        assert (isMainJrnl || pDone != null); /*
                                               * pDone always used on
                                               * sub-journals
                                               */
        assert (isSavepnt || pDone == null); /*
                                              * pDone never used on
                                              * non-savepoint
                                              */

        aData = tmpSpace;
        assert (aData != null); /* Temp storage must have already been allocated */

        jfd = (isMainJrnl ? this.jfd : this.sjfd);

        pgno = read32bits(jfd, pOffset);
        jfd.read(aData, pageSize, pOffset + 4);
        pOffset += pageSize + 4 + (isMainJrnl ? 4 : 0);

        /*
         * Sanity checking on the page. This is more important that I originally
         * thought. If a power failure occurs while the journal is being
         * 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);
        }

        assert (state == SqlJetPagerState.RESERVED || state.compareTo(SqlJetPagerState.EXCLUSIVE) >= 0);

        /*
         * If the pager is in RESERVED state, then there must be a copy of this
         * page in the pager cache. In this case just update the pager cache,
         * not the database file. The page is left marked dirty in this case.
         *
         * An exception to the above rule: If the database is in no-sync mode
         * and a page is moved during an incremental vacuum then the page may
         * not be in the pager cache. Later: if a malloc() or IO error occurs
         * during a Movepage() call, then the page may not be in the cache
         * either. So the condition described in the above paragraph is not
         * assert()able.
         *
         * If in EXCLUSIVE state, then we update the pager cache if it exists
         * and the main file. The page is then marked not dirty.
         *
         * Ticket #1171: The statement journal might contain page content that
         * is different from the page content at the start of the transaction.
         * This occurs when a page is changed prior to the start of a statement
         * then changed again within the statement. When rolling back such a
         * statement we must not write to the original database unless we know
         * for certain that original page contents are synced into the main
         * rollback journal. Otherwise, a power loss might leave modified data
         * in the database file without an entry in the rollback journal that
         * can restore the database to its original form. Two conditions must be
         * met before writing to the database files. (1) the database must be
         * locked. (2) we know that the original page content is fully synced in
         * the main journal either because the page is not in cache or else the
         * page is marked as needSync==0.
         *
         * 2008-04-14: When attempting to vacuum a corrupt database file, it is
         * possible to fail a statement on a database that does not yet exist.
         * Do not attempt to write if database file has never been opened.
         */
        pPg = lookup(pgno);
        PAGERTRACE("PLAYBACK %s page %d hash(%08x) %s\n", PAGERID(), pgno, dataHash(pageSize, aData),
                (isMainJrnl ? "main-journal" : "sub-journal"));
        if (state.compareTo(SqlJetPagerState.EXCLUSIVE) >= 0
                && (pPg == null || !pPg.getFlags().contains(SqlJetPageFlags.NEED_SYNC)) && null != fd) {
            long ofst = (pgno - 1) * pageSize;
            fd.write(aData, pageSize, ofst);
            if (pgno > dbFileSize) {
                dbFileSize = pgno;
            }
        } else if (!isMainJrnl && pPg == null) {
            /*
             * If this is a rollback of a savepoint and data was not written to
             * the database and the page is not in-memory, there is a potential
             * problem. When the page is next fetched by the b-tree layer, it
             * will be read from the database file, which may or may not be
             * current.
             *
             * There are a couple of different ways this can happen. All are
             * quite obscure. When running in synchronous mode, this can only
             * happen if the page is on the free-list at the start of the
             * transaction, then populated, then moved using
             * sqlite3PagerMovepage().
             *
             * The solution is to add an in-memory page to the cache containing
             * the data just read from the sub-journal. Mark the page as dirty
             * and if the pager requires a journal-sync, then mark the page as
             * requiring a journal-sync before it is written.
             */
            assert (isSavepnt);
            pPg = acquirePage(pgno, true);
            pPg.getFlags().remove(SqlJetPageFlags.NEED_READ);
            pageCache.makeDirty(pPg);
        }
        if (null != pPg) {
            /*
             * No page should ever be explicitly rolled back that is in use,
             * except for page 1 which is held in use in order to keep the lock
             * on the database active. However such a page may be rolled back as
             * a result of an internal error resulting in an automatic call to
             * sqlite3PagerRollback().
             */
            final ISqlJetMemoryPointer pData = pPg.getData();
            SqlJetUtility.memcpy(pData, aData, pageSize);

            if (null != reiniter) {
                reiniter.pageCallback(pPg);
            }
View Full Code Here

        long szJ;
        long cksum;
        /* Unsigned loop counter */
        int u;
        /* A buffer to hold the magic header */
        ISqlJetMemoryPointer aMagic = SqlJetUtility.allocatePtr(8);

        szJ = journal.fileSize();
        if (szJ < 16)
            return null;

        len = read32bits(journal, szJ - 16);
        cksum = read32bitsUnsigned(journal, szJ - 12);

        journal.read(aMagic, aMagic.remaining(), szJ - 8);
        if (0 != SqlJetUtility.memcmp(aMagic, aJournalMagic, aMagic.remaining()))
            return null;

        ISqlJetMemoryPointer zMaster = SqlJetUtility.allocatePtr(len);
        journal.read(zMaster, len, szJ - 16 - len);

        /* See if the checksum matches the master journal name */
        for (u = 0; u < len; u++) {
            cksum -= SqlJetUtility.getUnsignedByte(zMaster, u);
View Full Code Here

     * @param offset
     * @return
     * @throws SqlJetIOException
     */
    private int read32bits(final ISqlJetFile fd, final long offset) throws SqlJetIOException {
        ISqlJetMemoryPointer ac = SqlJetUtility.allocatePtr(4);
        fd.read(ac, ac.remaining(), offset);
        return SqlJetUtility.get4byte(ac);
    }
View Full Code Here

     * @param offset
     * @return
     * @throws SqlJetIOException
     */
    private long read32bitsUnsigned(final ISqlJetFile fd, final long offset) throws SqlJetIOException {
        ISqlJetMemoryPointer ac = SqlJetUtility.allocatePtr(4);
        fd.read(ac, ac.remaining(), offset);
        return SqlJetUtility.get4byteUnsigned(ac);
    }
View Full Code Here

    private int[] readJournalHdr(long journalSize) throws SqlJetException {

        int[] result = new int[2];

        /* A buffer to hold the magic header */
        ISqlJetMemoryPointer aMagic = SqlJetUtility.allocatePtr(8);
        long jrnlOff;
        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);
View Full Code Here

            newSize = pageSize * pageNumber;
            if (currentSize != newSize) {
                if (currentSize > newSize) {
                    fd.truncate(newSize);
                } else {
                    final ISqlJetMemoryPointer b = SqlJetUtility.allocatePtr(1);
                    fd.write(b, 1, newSize - 1);
                }
                dbFileSize = nPage;
            }
        }
View Full Code Here

                final Set<SqlJetDeviceCharacteristics> dc = fd.deviceCharacteristics();

                if (!dc.contains(SqlJetDeviceCharacteristics.IOCAP_SAFE_APPEND)) {
                    long jrnlOff = journalHdrOffset();
                    ISqlJetMemoryPointer zMagic = SqlJetUtility.allocatePtr(8);

                    /*
                     * This block deals with an obscure problem. If the last
                     * connection that wrote to this database was operating in
                     * persistent-journal mode, then the journal file may at
                     * this point actually be larger than Pager.journalOff
                     * bytes. If the next thing in the journal file happens to
                     * be a journal-header (written as part of the previous
                     * connections transaction), and a crash or power-failure
                     * occurs after nRec is updated but before this connection
                     * writes anything else to the journal file (or
                     * commits/rolls back its transaction), then SQLite may
                     * become confused when doing the hot-journal rollback
                     * following recovery. It may roll back all of this
                     * connections data, then proceed to rolling back the old,
                     * out-of-date data that follows it. Database corruption.
                     *
                     * To work around this, if the journal file does appear to
                     * contain a valid header following Pager.journalOff, then
                     * write a 0x00 byte to the start of it to prevent it from
                     * being recognized.
                     */
                    try {
                        jfd.read(zMagic, 8, jrnlOff);
                        if (0 == SqlJetUtility.memcmp(zMagic, aJournalMagic, 8)) {
                            ISqlJetMemoryPointer zerobyte = SqlJetUtility.allocatePtr(1);
                            jfd.write(zerobyte, 1, jrnlOff);
                        }
                    } catch (SqlJetIOException e) {
                        if (e.getIoErrorCode() != SqlJetIOErrorCode.IOERR_SHORT_READ)
                            throw e;
View Full Code Here

     *
     * @throws SqlJetIOException
     *
     */
    void subjournalPage(SqlJetPage pPg) throws SqlJetIOException {
        ISqlJetMemoryPointer pData = pPg.getData();
        long offset = stmtNRec * (4 + pageSize);

        PAGERTRACE("STMT-JOURNAL %s page %d\n", PAGERID(), pPg.pgno);

        assert (pageInJournal(pPg) || pPg.pgno > dbOrigSize);
View Full Code Here

     * on success or an error code is something goes wrong.
     *
     * @throws SqlJetIOException
     */
    static void write32bits(ISqlJetFile fd, long offset, int val) throws SqlJetIOException {
        final ISqlJetMemoryPointer b = SqlJetUtility.put4byte(val);
        fd.write(b, b.remaining(), offset);
    }
View Full Code Here

TOP

Related Classes of org.tmatesoft.sqljet.core.internal.ISqlJetMemoryPointer

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.