Loading core/java/android/database/sqlite/SQLiteConnection.java +61 −29 Original line number Diff line number Diff line Loading @@ -211,8 +211,7 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen SQLiteDebug.DEBUG_SQL_STATEMENTS, SQLiteDebug.DEBUG_SQL_TIME); setPageSize(); setSyncModeFromConfiguration(); setJournalModeFromConfiguration(); setWalModeFromConfiguration(); setJournalSizeLimit(); setAutoCheckpointInterval(); setLocaleFromConfiguration(); Loading Loading @@ -268,28 +267,69 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen } } private void setSyncModeFromConfiguration() { private void setWalModeFromConfiguration() { if (!mConfiguration.isInMemoryDb() && !mIsReadOnlyConnection) { final String newValue = mConfiguration.syncMode; if (mConfiguration.walEnabled) { setJournalMode("WAL"); setSyncMode(SQLiteGlobal.getWALSyncMode()); } else { setJournalMode(SQLiteGlobal.getDefaultJournalMode()); setSyncMode(SQLiteGlobal.getDefaultSyncMode()); } } } private void setSyncMode(String newValue) { String value = executeForString("PRAGMA synchronous", null, null); if (!value.equalsIgnoreCase(newValue)) { if (!canonicalizeSyncMode(value).equalsIgnoreCase( canonicalizeSyncMode(newValue))) { execute("PRAGMA synchronous=" + newValue, null, null); } } private static String canonicalizeSyncMode(String value) { if (value.equals("0")) { return "OFF"; } else if (value.equals("1")) { return "NORMAL"; } else if (value.equals("2")) { return "FULL"; } return value; } private void setJournalModeFromConfiguration() { if (!mConfiguration.isInMemoryDb() && !mIsReadOnlyConnection) { final String newValue = mConfiguration.journalMode; private void setJournalMode(String newValue) { String value = executeForString("PRAGMA journal_mode", null, null); if (!value.equalsIgnoreCase(newValue)) { value = executeForString("PRAGMA journal_mode=" + newValue, null, null); if (!value.equalsIgnoreCase(newValue)) { Log.e(TAG, "setting journal_mode to " + newValue + " failed for db: " + mConfiguration.label + " (on pragma set journal_mode, sqlite returned:" + value); } try { String result = executeForString("PRAGMA journal_mode=" + newValue, null, null); if (result.equalsIgnoreCase(newValue)) { return; } // PRAGMA journal_mode silently fails and returns the original journal // mode in some cases if the journal mode could not be changed. } catch (SQLiteDatabaseLockedException ex) { // This error (SQLITE_BUSY) occurs if one connection has the database // open in WAL mode and another tries to change it to non-WAL. } // Because we always disable WAL mode when a database is first opened // (even if we intend to re-enable it), we can encounter problems if // there is another open connection to the database somewhere. // This can happen for a variety of reasons such as an application opening // the same database in multiple processes at the same time or if there is a // crashing content provider service that the ActivityManager has // removed from its registry but whose process hasn't quite died yet // by the time it is restarted in a new process. // // If we don't change the journal mode, nothing really bad happens. // In the worst case, an application that enables WAL might not actually // get it, although it can still use connection pooling. Log.w(TAG, "Could not change the database journal mode of '" + mConfiguration.label + "' from '" + value + "' to '" + newValue + "' because the database is locked. This usually means that " + "there are other open connections to the database which prevents " + "the database from enabling or disabling write-ahead logging mode. " + "Proceeding without changing the journal mode."); } } Loading Loading @@ -349,10 +389,7 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen } // Remember what changed. boolean syncModeChanged = !configuration.syncMode.equalsIgnoreCase( mConfiguration.syncMode); boolean journalModeChanged = !configuration.journalMode.equalsIgnoreCase( mConfiguration.journalMode); boolean walModeChanged = configuration.walEnabled != mConfiguration.walEnabled; boolean localeChanged = !configuration.locale.equals(mConfiguration.locale); // Update configuration parameters. Loading @@ -361,14 +398,9 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen // Update prepared statement cache size. mPreparedStatementCache.resize(configuration.maxSqlCacheSize); // Update sync mode. if (syncModeChanged) { setSyncModeFromConfiguration(); } // Update journal mode. if (journalModeChanged) { setJournalModeFromConfiguration(); // Update WAL. if (walModeChanged) { setWalModeFromConfiguration(); } // Update locale. Loading core/java/android/database/sqlite/SQLiteConnectionPool.java +1 −2 Original line number Diff line number Diff line Loading @@ -258,8 +258,7 @@ public final class SQLiteConnectionPool implements Closeable { throwIfClosedLocked(); boolean restrictToOneConnection = false; if (mConfiguration.journalMode.equalsIgnoreCase("WAL") != configuration.journalMode.equalsIgnoreCase("WAL")) { if (mConfiguration.walEnabled != configuration.walEnabled) { // 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()) { Loading core/java/android/database/sqlite/SQLiteDatabase.java +6 −22 Original line number Diff line number Diff line Loading @@ -127,10 +127,6 @@ public final class SQLiteDatabase extends SQLiteClosable { // INVARIANT: Guarded by mLock. private boolean mHasAttachedDbsLocked; // True if the database is in WAL mode. // INVARIANT: Guarded by mLock. private boolean mIsWALEnabledLocked; /** * When a constraint violation occurs, an immediate ROLLBACK occurs, * thus ending the current transaction, and the command aborts with a Loading Loading @@ -1834,7 +1830,7 @@ public final class SQLiteDatabase extends SQLiteClosable { synchronized (mLock) { throwIfNotOpenLocked(); if (mIsWALEnabledLocked) { if (mConfigurationLocked.walEnabled) { return true; } Loading @@ -1860,21 +1856,15 @@ public final class SQLiteDatabase extends SQLiteClosable { } 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"; mConfigurationLocked.walEnabled = true; try { mConnectionPoolLocked.reconfigure(mConfigurationLocked); } catch (RuntimeException ex) { mConfigurationLocked.maxConnectionPoolSize = oldMaxConnectionPoolSize; mConfigurationLocked.syncMode = oldSyncMode; mConfigurationLocked.journalMode = oldJournalMode; mConfigurationLocked.walEnabled = false; throw ex; } mIsWALEnabledLocked = true; } return true; } Loading @@ -1890,26 +1880,20 @@ public final class SQLiteDatabase extends SQLiteClosable { synchronized (mLock) { throwIfNotOpenLocked(); if (!mIsWALEnabledLocked) { if (!mConfigurationLocked.walEnabled) { return; } 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(); mConfigurationLocked.walEnabled = false; try { mConnectionPoolLocked.reconfigure(mConfigurationLocked); } catch (RuntimeException ex) { mConfigurationLocked.maxConnectionPoolSize = oldMaxConnectionPoolSize; mConfigurationLocked.syncMode = oldSyncMode; mConfigurationLocked.journalMode = oldJournalMode; mConfigurationLocked.walEnabled = true; throw ex; } mIsWALEnabledLocked = false; } } Loading core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java +4 −14 Original line number Diff line number Diff line Loading @@ -85,18 +85,11 @@ public final class SQLiteDatabaseConfiguration { public Locale locale; /** * The database synchronization mode. * True if WAL mode is enabled. * * Default is {@link SQLiteGlobal#getDefaultSyncMode()}. * Default is false. */ public String syncMode; /** * The database journal mode. * * Default is {@link SQLiteGlobal#getDefaultJournalMode()}. */ public String journalMode; public boolean walEnabled; /** * The custom functions to register. Loading Loading @@ -124,8 +117,6 @@ public final class SQLiteDatabaseConfiguration { maxConnectionPoolSize = 1; maxSqlCacheSize = 25; locale = Locale.getDefault(); syncMode = SQLiteGlobal.getDefaultSyncMode(); journalMode = SQLiteGlobal.getDefaultJournalMode(); } /** Loading Loading @@ -162,8 +153,7 @@ public final class SQLiteDatabaseConfiguration { maxConnectionPoolSize = other.maxConnectionPoolSize; maxSqlCacheSize = other.maxSqlCacheSize; locale = other.locale; syncMode = other.syncMode; journalMode = other.journalMode; walEnabled = other.walEnabled; customFunctions.clear(); customFunctions.addAll(other.customFunctions); } Loading Loading
core/java/android/database/sqlite/SQLiteConnection.java +61 −29 Original line number Diff line number Diff line Loading @@ -211,8 +211,7 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen SQLiteDebug.DEBUG_SQL_STATEMENTS, SQLiteDebug.DEBUG_SQL_TIME); setPageSize(); setSyncModeFromConfiguration(); setJournalModeFromConfiguration(); setWalModeFromConfiguration(); setJournalSizeLimit(); setAutoCheckpointInterval(); setLocaleFromConfiguration(); Loading Loading @@ -268,28 +267,69 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen } } private void setSyncModeFromConfiguration() { private void setWalModeFromConfiguration() { if (!mConfiguration.isInMemoryDb() && !mIsReadOnlyConnection) { final String newValue = mConfiguration.syncMode; if (mConfiguration.walEnabled) { setJournalMode("WAL"); setSyncMode(SQLiteGlobal.getWALSyncMode()); } else { setJournalMode(SQLiteGlobal.getDefaultJournalMode()); setSyncMode(SQLiteGlobal.getDefaultSyncMode()); } } } private void setSyncMode(String newValue) { String value = executeForString("PRAGMA synchronous", null, null); if (!value.equalsIgnoreCase(newValue)) { if (!canonicalizeSyncMode(value).equalsIgnoreCase( canonicalizeSyncMode(newValue))) { execute("PRAGMA synchronous=" + newValue, null, null); } } private static String canonicalizeSyncMode(String value) { if (value.equals("0")) { return "OFF"; } else if (value.equals("1")) { return "NORMAL"; } else if (value.equals("2")) { return "FULL"; } return value; } private void setJournalModeFromConfiguration() { if (!mConfiguration.isInMemoryDb() && !mIsReadOnlyConnection) { final String newValue = mConfiguration.journalMode; private void setJournalMode(String newValue) { String value = executeForString("PRAGMA journal_mode", null, null); if (!value.equalsIgnoreCase(newValue)) { value = executeForString("PRAGMA journal_mode=" + newValue, null, null); if (!value.equalsIgnoreCase(newValue)) { Log.e(TAG, "setting journal_mode to " + newValue + " failed for db: " + mConfiguration.label + " (on pragma set journal_mode, sqlite returned:" + value); } try { String result = executeForString("PRAGMA journal_mode=" + newValue, null, null); if (result.equalsIgnoreCase(newValue)) { return; } // PRAGMA journal_mode silently fails and returns the original journal // mode in some cases if the journal mode could not be changed. } catch (SQLiteDatabaseLockedException ex) { // This error (SQLITE_BUSY) occurs if one connection has the database // open in WAL mode and another tries to change it to non-WAL. } // Because we always disable WAL mode when a database is first opened // (even if we intend to re-enable it), we can encounter problems if // there is another open connection to the database somewhere. // This can happen for a variety of reasons such as an application opening // the same database in multiple processes at the same time or if there is a // crashing content provider service that the ActivityManager has // removed from its registry but whose process hasn't quite died yet // by the time it is restarted in a new process. // // If we don't change the journal mode, nothing really bad happens. // In the worst case, an application that enables WAL might not actually // get it, although it can still use connection pooling. Log.w(TAG, "Could not change the database journal mode of '" + mConfiguration.label + "' from '" + value + "' to '" + newValue + "' because the database is locked. This usually means that " + "there are other open connections to the database which prevents " + "the database from enabling or disabling write-ahead logging mode. " + "Proceeding without changing the journal mode."); } } Loading Loading @@ -349,10 +389,7 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen } // Remember what changed. boolean syncModeChanged = !configuration.syncMode.equalsIgnoreCase( mConfiguration.syncMode); boolean journalModeChanged = !configuration.journalMode.equalsIgnoreCase( mConfiguration.journalMode); boolean walModeChanged = configuration.walEnabled != mConfiguration.walEnabled; boolean localeChanged = !configuration.locale.equals(mConfiguration.locale); // Update configuration parameters. Loading @@ -361,14 +398,9 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen // Update prepared statement cache size. mPreparedStatementCache.resize(configuration.maxSqlCacheSize); // Update sync mode. if (syncModeChanged) { setSyncModeFromConfiguration(); } // Update journal mode. if (journalModeChanged) { setJournalModeFromConfiguration(); // Update WAL. if (walModeChanged) { setWalModeFromConfiguration(); } // Update locale. Loading
core/java/android/database/sqlite/SQLiteConnectionPool.java +1 −2 Original line number Diff line number Diff line Loading @@ -258,8 +258,7 @@ public final class SQLiteConnectionPool implements Closeable { throwIfClosedLocked(); boolean restrictToOneConnection = false; if (mConfiguration.journalMode.equalsIgnoreCase("WAL") != configuration.journalMode.equalsIgnoreCase("WAL")) { if (mConfiguration.walEnabled != configuration.walEnabled) { // 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()) { Loading
core/java/android/database/sqlite/SQLiteDatabase.java +6 −22 Original line number Diff line number Diff line Loading @@ -127,10 +127,6 @@ public final class SQLiteDatabase extends SQLiteClosable { // INVARIANT: Guarded by mLock. private boolean mHasAttachedDbsLocked; // True if the database is in WAL mode. // INVARIANT: Guarded by mLock. private boolean mIsWALEnabledLocked; /** * When a constraint violation occurs, an immediate ROLLBACK occurs, * thus ending the current transaction, and the command aborts with a Loading Loading @@ -1834,7 +1830,7 @@ public final class SQLiteDatabase extends SQLiteClosable { synchronized (mLock) { throwIfNotOpenLocked(); if (mIsWALEnabledLocked) { if (mConfigurationLocked.walEnabled) { return true; } Loading @@ -1860,21 +1856,15 @@ public final class SQLiteDatabase extends SQLiteClosable { } 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"; mConfigurationLocked.walEnabled = true; try { mConnectionPoolLocked.reconfigure(mConfigurationLocked); } catch (RuntimeException ex) { mConfigurationLocked.maxConnectionPoolSize = oldMaxConnectionPoolSize; mConfigurationLocked.syncMode = oldSyncMode; mConfigurationLocked.journalMode = oldJournalMode; mConfigurationLocked.walEnabled = false; throw ex; } mIsWALEnabledLocked = true; } return true; } Loading @@ -1890,26 +1880,20 @@ public final class SQLiteDatabase extends SQLiteClosable { synchronized (mLock) { throwIfNotOpenLocked(); if (!mIsWALEnabledLocked) { if (!mConfigurationLocked.walEnabled) { return; } 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(); mConfigurationLocked.walEnabled = false; try { mConnectionPoolLocked.reconfigure(mConfigurationLocked); } catch (RuntimeException ex) { mConfigurationLocked.maxConnectionPoolSize = oldMaxConnectionPoolSize; mConfigurationLocked.syncMode = oldSyncMode; mConfigurationLocked.journalMode = oldJournalMode; mConfigurationLocked.walEnabled = true; throw ex; } mIsWALEnabledLocked = false; } } Loading
core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java +4 −14 Original line number Diff line number Diff line Loading @@ -85,18 +85,11 @@ public final class SQLiteDatabaseConfiguration { public Locale locale; /** * The database synchronization mode. * True if WAL mode is enabled. * * Default is {@link SQLiteGlobal#getDefaultSyncMode()}. * Default is false. */ public String syncMode; /** * The database journal mode. * * Default is {@link SQLiteGlobal#getDefaultJournalMode()}. */ public String journalMode; public boolean walEnabled; /** * The custom functions to register. Loading Loading @@ -124,8 +117,6 @@ public final class SQLiteDatabaseConfiguration { maxConnectionPoolSize = 1; maxSqlCacheSize = 25; locale = Locale.getDefault(); syncMode = SQLiteGlobal.getDefaultSyncMode(); journalMode = SQLiteGlobal.getDefaultJournalMode(); } /** Loading Loading @@ -162,8 +153,7 @@ public final class SQLiteDatabaseConfiguration { maxConnectionPoolSize = other.maxConnectionPoolSize; maxSqlCacheSize = other.maxSqlCacheSize; locale = other.locale; syncMode = other.syncMode; journalMode = other.journalMode; walEnabled = other.walEnabled; customFunctions.clear(); customFunctions.addAll(other.customFunctions); } Loading