diff options
Diffstat (limited to 'core/java/android')
-rw-r--r-- | core/java/android/database/sqlite/SQLiteConnectionPool.java | 42 | ||||
-rw-r--r-- | core/java/android/database/sqlite/SQLiteDatabase.java | 65 |
2 files changed, 94 insertions, 13 deletions
diff --git a/core/java/android/database/sqlite/SQLiteConnectionPool.java b/core/java/android/database/sqlite/SQLiteConnectionPool.java index 3562e89..00d3309 100644 --- a/core/java/android/database/sqlite/SQLiteConnectionPool.java +++ b/core/java/android/database/sqlite/SQLiteConnectionPool.java @@ -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); @@ -466,6 +489,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(); while (availableCount-- > mConfiguration.maxConnectionPoolSize - 1) { diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java index bf32ea7..e575c26 100644 --- a/core/java/android/database/sqlite/SQLiteDatabase.java +++ b/core/java/android/database/sqlite/SQLiteDatabase.java @@ -834,8 +834,14 @@ public final class SQLiteDatabase extends SQLiteClosable { synchronized (mLock) { throwIfNotOpenLocked(); + mConfigurationLocked.customFunctions.add(wrapper); - mConnectionPoolLocked.reconfigure(mConfigurationLocked); + 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; - mConnectionPoolLocked.reconfigure(mConfigurationLocked); + 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; - mConnectionPoolLocked.reconfigure(mConfigurationLocked); + 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"; - mConnectionPoolLocked.reconfigure(mConfigurationLocked); + 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(); - mConnectionPoolLocked.reconfigure(mConfigurationLocked); + try { + mConnectionPoolLocked.reconfigure(mConfigurationLocked); + } catch (RuntimeException ex) { + mConfigurationLocked.maxConnectionPoolSize = oldMaxConnectionPoolSize; + mConfigurationLocked.syncMode = oldSyncMode; + mConfigurationLocked.journalMode = oldJournalMode; + throw ex; + } + + mIsWALEnabledLocked = false; } } |