Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2d008724 authored by Jeff Brown's avatar Jeff Brown Committed by Android (Google) Code Review
Browse files

Merge "Throw if WAL enabled/disabled when connections are in use."

parents 3004cc50 e67ca420
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -7312,6 +7312,7 @@ package android.database.sqlite {
    method public static android.database.sqlite.SQLiteDatabase create(android.database.sqlite.SQLiteDatabase.CursorFactory);
    method public int delete(java.lang.String, java.lang.String, java.lang.String[]);
    method public static boolean deleteDatabase(java.io.File);
    method public void disableWriteAheadLogging();
    method public boolean enableWriteAheadLogging();
    method public void endTransaction();
    method public void execSQL(java.lang.String) throws android.database.SQLException;
+37 −5
Original line number Diff line number Diff line
@@ -257,7 +257,34 @@ public final class SQLiteConnectionPool implements Closeable {
        synchronized (mLock) {
            throwIfClosedLocked();

            boolean restrictToOneConnection = false;
            if (mConfiguration.journalMode.equalsIgnoreCase("WAL")
                    != configuration.journalMode.equalsIgnoreCase("WAL")) {
                // WAL mode can only be changed if there are no acquired connections
                // because we need to close all but the primary connection first.
                if (!mAcquiredConnections.isEmpty()) {
                    throw new IllegalStateException("Write Ahead Logging (WAL) mode cannot "
                            + "be enabled or disabled while there are transactions in "
                            + "progress.  Finish all transactions and release all active "
                            + "database connections first.");
                }

                // Close all non-primary connections.  This should happen immediately
                // because none of them are in use.
                closeAvailableNonPrimaryConnectionsAndLogExceptionsLocked();
                assert mAvailableNonPrimaryConnections.isEmpty();

                restrictToOneConnection = true;
            }

            if (mConfiguration.openFlags != configuration.openFlags) {
                // If we are changing open flags and WAL mode at the same time, then
                // we have no choice but to close the primary connection beforehand
                // because there can only be one connection open when we change WAL mode.
                if (restrictToOneConnection) {
                    closeAvailableConnectionsAndLogExceptionsLocked();
                }

                // Try to reopen the primary connection using the new open flags then
                // close and discard all existing connections.
                // This might throw if the database is corrupt or cannot be opened in
@@ -453,11 +480,7 @@ public final class SQLiteConnectionPool implements Closeable {

    // Can't throw.
    private void closeAvailableConnectionsAndLogExceptionsLocked() {
        final int count = mAvailableNonPrimaryConnections.size();
        for (int i = 0; i < count; i++) {
            closeConnectionAndLogExceptionsLocked(mAvailableNonPrimaryConnections.get(i));
        }
        mAvailableNonPrimaryConnections.clear();
        closeAvailableNonPrimaryConnectionsAndLogExceptionsLocked();

        if (mAvailablePrimaryConnection != null) {
            closeConnectionAndLogExceptionsLocked(mAvailablePrimaryConnection);
@@ -465,6 +488,15 @@ public final class SQLiteConnectionPool implements Closeable {
        }
    }

    // Can't throw.
    private void closeAvailableNonPrimaryConnectionsAndLogExceptionsLocked() {
        final int count = mAvailableNonPrimaryConnections.size();
        for (int i = 0; i < count; i++) {
            closeConnectionAndLogExceptionsLocked(mAvailableNonPrimaryConnections.get(i));
        }
        mAvailableNonPrimaryConnections.clear();
    }

    // Can't throw.
    private void closeExcessConnectionsAndLogExceptionsLocked() {
        int availableCount = mAvailableNonPrimaryConnections.size();
+57 −8
Original line number Diff line number Diff line
@@ -834,8 +834,14 @@ public final class SQLiteDatabase extends SQLiteClosable {

        synchronized (mLock) {
            throwIfNotOpenLocked();

            mConfigurationLocked.customFunctions.add(wrapper);
            try {
                mConnectionPoolLocked.reconfigure(mConfigurationLocked);
            } catch (RuntimeException ex) {
                mConfigurationLocked.customFunctions.remove(wrapper);
                throw ex;
            }
        }
    }

@@ -1733,8 +1739,15 @@ public final class SQLiteDatabase extends SQLiteClosable {

        synchronized (mLock) {
            throwIfNotOpenLocked();

            final Locale oldLocale = mConfigurationLocked.locale;
            mConfigurationLocked.locale = locale;
            try {
                mConnectionPoolLocked.reconfigure(mConfigurationLocked);
            } catch (RuntimeException ex) {
                mConfigurationLocked.locale = oldLocale;
                throw ex;
            }
        }
    }

@@ -1759,8 +1772,15 @@ public final class SQLiteDatabase extends SQLiteClosable {

        synchronized (mLock) {
            throwIfNotOpenLocked();

            final int oldMaxSqlCacheSize = mConfigurationLocked.maxSqlCacheSize;
            mConfigurationLocked.maxSqlCacheSize = cacheSize;
            try {
                mConnectionPoolLocked.reconfigure(mConfigurationLocked);
            } catch (RuntimeException ex) {
                mConfigurationLocked.maxSqlCacheSize = oldMaxSqlCacheSize;
                throw ex;
            }
        }
    }

@@ -1805,6 +1825,10 @@ public final class SQLiteDatabase extends SQLiteClosable {
     * </p>
     *
     * @return true if write-ahead-logging is set. false otherwise
     *
     * @throw IllegalStateException if there are transactions in progress at the
     * time this method is called.  WAL mode can only be changed when there are no
     * transactions in progress.
     */
    public boolean enableWriteAheadLogging() {
        synchronized (mLock) {
@@ -1835,18 +1859,32 @@ public final class SQLiteDatabase extends SQLiteClosable {
                return false;
            }

            mIsWALEnabledLocked = true;
            final int oldMaxConnectionPoolSize = mConfigurationLocked.maxConnectionPoolSize;
            final String oldSyncMode = mConfigurationLocked.syncMode;
            final String oldJournalMode = mConfigurationLocked.journalMode;
            mConfigurationLocked.maxConnectionPoolSize = SQLiteGlobal.getWALConnectionPoolSize();
            mConfigurationLocked.syncMode = SQLiteGlobal.getWALSyncMode();
            mConfigurationLocked.journalMode = "WAL";
            try {
                mConnectionPoolLocked.reconfigure(mConfigurationLocked);
            } catch (RuntimeException ex) {
                mConfigurationLocked.maxConnectionPoolSize = oldMaxConnectionPoolSize;
                mConfigurationLocked.syncMode = oldSyncMode;
                mConfigurationLocked.journalMode = oldJournalMode;
                throw ex;
            }

            mIsWALEnabledLocked = true;
        }
        return true;
    }

    /**
     * This method disables the features enabled by {@link #enableWriteAheadLogging()}.
     * @hide
     *
     * @throw IllegalStateException if there are transactions in progress at the
     * time this method is called.  WAL mode can only be changed when there are no
     * transactions in progress.
     */
    public void disableWriteAheadLogging() {
        synchronized (mLock) {
@@ -1856,11 +1894,22 @@ public final class SQLiteDatabase extends SQLiteClosable {
                return;
            }

            mIsWALEnabledLocked = false;
            final int oldMaxConnectionPoolSize = mConfigurationLocked.maxConnectionPoolSize;
            final String oldSyncMode = mConfigurationLocked.syncMode;
            final String oldJournalMode = mConfigurationLocked.journalMode;
            mConfigurationLocked.maxConnectionPoolSize = 1;
            mConfigurationLocked.syncMode = SQLiteGlobal.getDefaultSyncMode();
            mConfigurationLocked.journalMode = SQLiteGlobal.getDefaultJournalMode();
            try {
                mConnectionPoolLocked.reconfigure(mConfigurationLocked);
            } catch (RuntimeException ex) {
                mConfigurationLocked.maxConnectionPoolSize = oldMaxConnectionPoolSize;
                mConfigurationLocked.syncMode = oldSyncMode;
                mConfigurationLocked.journalMode = oldJournalMode;
                throw ex;
            }

            mIsWALEnabledLocked = false;
        }
    }