summaryrefslogtreecommitdiffstats
path: root/core/java/android/database
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/database')
-rw-r--r--core/java/android/database/sqlite/SQLiteConnection.java90
-rw-r--r--core/java/android/database/sqlite/SQLiteConnectionPool.java3
-rw-r--r--core/java/android/database/sqlite/SQLiteDatabase.java28
-rw-r--r--core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java18
4 files changed, 72 insertions, 67 deletions
diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java
index e2c222b..bf10bcb 100644
--- a/core/java/android/database/sqlite/SQLiteConnection.java
+++ b/core/java/android/database/sqlite/SQLiteConnection.java
@@ -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();
@@ -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;
- String value = executeForString("PRAGMA synchronous", null, null);
- if (!value.equalsIgnoreCase(newValue)) {
- execute("PRAGMA synchronous=" + newValue, null, null);
+ if (mConfiguration.walEnabled) {
+ setJournalMode("WAL");
+ setSyncMode(SQLiteGlobal.getWALSyncMode());
+ } else {
+ setJournalMode(SQLiteGlobal.getDefaultJournalMode());
+ setSyncMode(SQLiteGlobal.getDefaultSyncMode());
}
}
}
- private void setJournalModeFromConfiguration() {
- if (!mConfiguration.isInMemoryDb() && !mIsReadOnlyConnection) {
- final String newValue = mConfiguration.journalMode;
- 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);
+ private void setSyncMode(String newValue) {
+ String value = executeForString("PRAGMA synchronous", null, null);
+ 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 setJournalMode(String newValue) {
+ String value = executeForString("PRAGMA journal_mode", null, null);
+ if (!value.equalsIgnoreCase(newValue)) {
+ 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.");
}
}
@@ -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.
@@ -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.
diff --git a/core/java/android/database/sqlite/SQLiteConnectionPool.java b/core/java/android/database/sqlite/SQLiteConnectionPool.java
index 00d3309..27c9ee5 100644
--- a/core/java/android/database/sqlite/SQLiteConnectionPool.java
+++ b/core/java/android/database/sqlite/SQLiteConnectionPool.java
@@ -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()) {
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 24a7800..0ecce4d 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -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
@@ -1834,7 +1830,7 @@ public final class SQLiteDatabase extends SQLiteClosable {
synchronized (mLock) {
throwIfNotOpenLocked();
- if (mIsWALEnabledLocked) {
+ if (mConfigurationLocked.walEnabled) {
return true;
}
@@ -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;
}
@@ -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;
}
}
diff --git a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
index efbcaca..e06a5ee 100644
--- a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
+++ b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
@@ -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.
@@ -124,8 +117,6 @@ public final class SQLiteDatabaseConfiguration {
maxConnectionPoolSize = 1;
maxSqlCacheSize = 25;
locale = Locale.getDefault();
- syncMode = SQLiteGlobal.getDefaultSyncMode();
- journalMode = SQLiteGlobal.getDefaultJournalMode();
}
/**
@@ -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);
}