Merge "Support enabling WAL using a flag when DB is opened."

This commit is contained in:
Jeff Brown
2012-03-23 13:46:56 -07:00
committed by Android (Google) Code Review
10 changed files with 182 additions and 88 deletions

View File

@@ -5204,6 +5204,7 @@ package android.content {
field public static final java.lang.String LAYOUT_INFLATER_SERVICE = "layout_inflater";
field public static final java.lang.String LOCATION_SERVICE = "location";
field public static final int MODE_APPEND = 32768; // 0x8000
field public static final int MODE_ENABLE_WRITE_AHEAD_LOGGING = 8; // 0x8
field public static final int MODE_MULTI_PROCESS = 4; // 0x4
field public static final int MODE_PRIVATE = 0; // 0x0
field public static final int MODE_WORLD_READABLE = 1; // 0x1
@@ -7334,6 +7335,7 @@ package android.database.sqlite {
method public deprecated boolean isDbLockedByOtherThreads();
method public boolean isOpen();
method public boolean isReadOnly();
method public boolean isWriteAheadLoggingEnabled();
method public deprecated void markTableSyncable(java.lang.String, java.lang.String);
method public deprecated void markTableSyncable(java.lang.String, java.lang.String, java.lang.String);
method public boolean needUpgrade(int);
@@ -7375,6 +7377,7 @@ package android.database.sqlite {
field public static final int CONFLICT_REPLACE = 5; // 0x5
field public static final int CONFLICT_ROLLBACK = 1; // 0x1
field public static final int CREATE_IF_NECESSARY = 268435456; // 0x10000000
field public static final int ENABLE_WRITE_AHEAD_LOGGING = 536870912; // 0x20000000
field public static final int MAX_SQL_CACHE_SIZE = 100; // 0x64
field public static final int NO_LOCALIZED_COLLATORS = 16; // 0x10
field public static final int OPEN_READONLY = 1; // 0x1
@@ -7438,6 +7441,7 @@ package android.database.sqlite {
method public void onDowngrade(android.database.sqlite.SQLiteDatabase, int, int);
method public void onOpen(android.database.sqlite.SQLiteDatabase);
method public abstract void onUpgrade(android.database.sqlite.SQLiteDatabase, int, int);
method public void setWriteAheadLoggingEnabled(boolean);
}
public class SQLiteOutOfMemoryException extends android.database.sqlite.SQLiteException {

View File

@@ -766,17 +766,18 @@ class ContextImpl extends Context {
@Override
public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
File f = validateFilePath(name, true);
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory);
setFilePermissionsFromMode(f.getPath(), mode, 0);
return db;
return openOrCreateDatabase(name, mode, factory, null);
}
@Override
public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
DatabaseErrorHandler errorHandler) {
File f = validateFilePath(name, true);
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f.getPath(), factory, errorHandler);
int flags = SQLiteDatabase.CREATE_IF_NECESSARY;
if ((mode & MODE_ENABLE_WRITE_AHEAD_LOGGING) != 0) {
flags |= SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING;
}
SQLiteDatabase db = SQLiteDatabase.openDatabase(f.getPath(), factory, flags, errorHandler);
setFilePermissionsFromMode(f.getPath(), mode, 0);
return db;
}

View File

@@ -98,6 +98,16 @@ public abstract class Context {
*/
public static final int MODE_MULTI_PROCESS = 0x0004;
/**
* Database open flag: when set, the database is opened with write-ahead
* logging enabled by default.
*
* @see #openOrCreateDatabase(String, int, CursorFactory)
* @see #openOrCreateDatabase(String, int, CursorFactory, DatabaseErrorHandler)
* @see SQLiteDatabase#enableWriteAheadLogging
*/
public static final int MODE_ENABLE_WRITE_AHEAD_LOGGING = 0x0008;
/**
* Flag for {@link #bindService}: automatically create the service as long
* as the binding exists. Note that while this will create the service,
@@ -691,6 +701,7 @@ public abstract class Context {
* @param mode Operating mode. Use 0 or {@link #MODE_PRIVATE} for the
* default operation, {@link #MODE_WORLD_READABLE}
* and {@link #MODE_WORLD_WRITEABLE} to control permissions.
* Use {@link #MODE_ENABLE_WRITE_AHEAD_LOGGING} to enable write-ahead logging by default.
* @param factory An optional factory class that is called to instantiate a
* cursor when query is called.
*
@@ -700,6 +711,7 @@ public abstract class Context {
* @see #MODE_PRIVATE
* @see #MODE_WORLD_READABLE
* @see #MODE_WORLD_WRITEABLE
* @see #MODE_ENABLE_WRITE_AHEAD_LOGGING
* @see #deleteDatabase
*/
public abstract SQLiteDatabase openOrCreateDatabase(String name,
@@ -716,6 +728,7 @@ public abstract class Context {
* @param mode Operating mode. Use 0 or {@link #MODE_PRIVATE} for the
* default operation, {@link #MODE_WORLD_READABLE}
* and {@link #MODE_WORLD_WRITEABLE} to control permissions.
* Use {@link #MODE_ENABLE_WRITE_AHEAD_LOGGING} to enable write-ahead logging by default.
* @param factory An optional factory class that is called to instantiate a
* cursor when query is called.
* @param errorHandler the {@link DatabaseErrorHandler} to be used when sqlite reports database
@@ -726,6 +739,7 @@ public abstract class Context {
* @see #MODE_PRIVATE
* @see #MODE_WORLD_READABLE
* @see #MODE_WORLD_WRITEABLE
* @see #MODE_ENABLE_WRITE_AHEAD_LOGGING
* @see #deleteDatabase
*/
public abstract SQLiteDatabase openOrCreateDatabase(String name,

View File

@@ -269,7 +269,7 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen
private void setWalModeFromConfiguration() {
if (!mConfiguration.isInMemoryDb() && !mIsReadOnlyConnection) {
if (mConfiguration.walEnabled) {
if ((mConfiguration.openFlags & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0) {
setJournalMode("WAL");
setSyncMode(SQLiteGlobal.getWALSyncMode());
} else {
@@ -389,7 +389,8 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen
}
// Remember what changed.
boolean walModeChanged = configuration.walEnabled != mConfiguration.walEnabled;
boolean walModeChanged = ((configuration.openFlags ^ mConfiguration.openFlags)
& SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0;
boolean localeChanged = !configuration.locale.equals(mConfiguration.locale);
// Update configuration parameters.

View File

@@ -81,6 +81,7 @@ public final class SQLiteConnectionPool implements Closeable {
private final Object mLock = new Object();
private final AtomicBoolean mConnectionLeaked = new AtomicBoolean();
private final SQLiteDatabaseConfiguration mConfiguration;
private int mMaxConnectionPoolSize;
private boolean mIsOpen;
private int mNextConnectionId;
@@ -146,6 +147,7 @@ public final class SQLiteConnectionPool implements Closeable {
private SQLiteConnectionPool(SQLiteDatabaseConfiguration configuration) {
mConfiguration = new SQLiteDatabaseConfiguration(configuration);
setMaxConnectionPoolSizeLocked();
}
@Override
@@ -257,8 +259,9 @@ public final class SQLiteConnectionPool implements Closeable {
synchronized (mLock) {
throwIfClosedLocked();
boolean restrictToOneConnection = false;
if (mConfiguration.walEnabled != configuration.walEnabled) {
boolean walModeChanged = ((configuration.openFlags ^ mConfiguration.openFlags)
& SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0;
if (walModeChanged) {
// 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()) {
@@ -272,15 +275,13 @@ public final class SQLiteConnectionPool implements Closeable {
// 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) {
if (walModeChanged) {
closeAvailableConnectionsAndLogExceptionsLocked();
}
@@ -296,9 +297,11 @@ public final class SQLiteConnectionPool implements Closeable {
mAvailablePrimaryConnection = newPrimaryConnection;
mConfiguration.updateParametersFrom(configuration);
setMaxConnectionPoolSizeLocked();
} else {
// Reconfigure the database connections in place.
mConfiguration.updateParametersFrom(configuration);
setMaxConnectionPoolSizeLocked();
closeExcessConnectionsAndLogExceptionsLocked();
reconfigureAllConnectionsLocked();
@@ -360,8 +363,7 @@ public final class SQLiteConnectionPool implements Closeable {
mAvailablePrimaryConnection = connection;
}
wakeConnectionWaitersLocked();
} else if (mAvailableNonPrimaryConnections.size() >=
mConfiguration.maxConnectionPoolSize - 1) {
} else if (mAvailableNonPrimaryConnections.size() >= mMaxConnectionPoolSize - 1) {
closeConnectionAndLogExceptionsLocked(connection);
} else {
if (recycleConnectionLocked(connection, status)) {
@@ -499,7 +501,7 @@ public final class SQLiteConnectionPool implements Closeable {
// Can't throw.
private void closeExcessConnectionsAndLogExceptionsLocked() {
int availableCount = mAvailableNonPrimaryConnections.size();
while (availableCount-- > mConfiguration.maxConnectionPoolSize - 1) {
while (availableCount-- > mMaxConnectionPoolSize - 1) {
SQLiteConnection connection =
mAvailableNonPrimaryConnections.remove(availableCount);
closeConnectionAndLogExceptionsLocked(connection);
@@ -874,7 +876,7 @@ public final class SQLiteConnectionPool implements Closeable {
if (mAvailablePrimaryConnection != null) {
openConnections += 1;
}
if (openConnections >= mConfiguration.maxConnectionPoolSize) {
if (openConnections >= mMaxConnectionPoolSize) {
return null;
}
connection = openConnectionLocked(mConfiguration,
@@ -926,6 +928,18 @@ public final class SQLiteConnectionPool implements Closeable {
return (connectionFlags & CONNECTION_FLAG_INTERACTIVE) != 0 ? 1 : 0;
}
private void setMaxConnectionPoolSizeLocked() {
if ((mConfiguration.openFlags & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0) {
mMaxConnectionPoolSize = SQLiteGlobal.getWALConnectionPoolSize();
} else {
// TODO: We don't actually need to restrict the connection pool size to 1
// for non-WAL databases. There might be reasons to use connection pooling
// with other journal modes. For now, enabling connection pooling and
// using WAL are the same thing in the API.
mMaxConnectionPoolSize = 1;
}
}
private void throwIfClosedLocked() {
if (!mIsOpen) {
throw new IllegalStateException("Cannot perform this operation "
@@ -972,7 +986,7 @@ public final class SQLiteConnectionPool implements Closeable {
synchronized (mLock) {
printer.println("Connection pool for " + mConfiguration.path + ":");
printer.println(" Open: " + mIsOpen);
printer.println(" Max connections: " + mConfiguration.maxConnectionPoolSize);
printer.println(" Max connections: " + mMaxConnectionPoolSize);
printer.println(" Available primary connection:");
if (mAvailablePrimaryConnection != null) {

View File

@@ -231,6 +231,18 @@ public final class SQLiteDatabase extends SQLiteClosable {
*/
public static final int CREATE_IF_NECESSARY = 0x10000000; // update native code if changing
/**
* Open flag: Flag for {@link #openDatabase} to open the database file with
* write-ahead logging enabled by default. Using this flag is more efficient
* than calling {@link #enableWriteAheadLogging}.
*
* Write-ahead logging cannot be used with read-only databases so the value of
* this flag is ignored if the database is opened read-only.
*
* @see #enableWriteAheadLogging
*/
public static final int ENABLE_WRITE_AHEAD_LOGGING = 0x20000000;
/**
* Absolute max value that can be set by {@link #setMaxSqlCacheSize(int)}.
*
@@ -654,7 +666,7 @@ public final class SQLiteDatabase extends SQLiteClosable {
* @throws SQLiteException if the database cannot be opened
*/
public static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags) {
return openDatabase(path, factory, flags, new DefaultDatabaseErrorHandler());
return openDatabase(path, factory, flags, null);
}
/**
@@ -694,7 +706,7 @@ public final class SQLiteDatabase extends SQLiteClosable {
* Equivalent to openDatabase(path, factory, CREATE_IF_NECESSARY).
*/
public static SQLiteDatabase openOrCreateDatabase(String path, CursorFactory factory) {
return openDatabase(path, factory, CREATE_IF_NECESSARY);
return openDatabase(path, factory, CREATE_IF_NECESSARY, null);
}
/**
@@ -1781,56 +1793,84 @@ public final class SQLiteDatabase extends SQLiteClosable {
}
/**
* This method enables parallel execution of queries from multiple threads on the same database.
* It does this by opening multiple handles to the database and using a different
* database handle for each query.
* This method enables parallel execution of queries from multiple threads on the
* same database. It does this by opening multiple connections to the database
* and using a different database connection for each query. The database
* journal mode is also changed to enable writes to proceed concurrently with reads.
* <p>
* If a transaction is in progress on one connection handle and say, a table is updated in the
* transaction, then query on the same table on another connection handle will block for the
* transaction to complete. But this method enables such queries to execute by having them
* return old version of the data from the table. Most often it is the data that existed in the
* table prior to the above transaction updates on that table.
* <p>
* Maximum number of simultaneous handles used to execute queries in parallel is
* When write-ahead logging is not enabled (the default), it is not possible for
* reads and writes to occur on the database at the same time. Before modifying the
* database, the writer implicitly acquires an exclusive lock on the database which
* prevents readers from accessing the database until the write is completed.
* </p><p>
* In contrast, when write-ahead logging is enabled (by calling this method), write
* operations occur in a separate log file which allows reads to proceed concurrently.
* While a write is in progress, readers on other threads will perceive the state
* of the database as it was before the write began. When the write completes, readers
* on other threads will then perceive the new state of the database.
* </p><p>
* It is a good idea to enable write-ahead logging whenever a database will be
* concurrently accessed and modified by multiple threads at the same time.
* However, write-ahead logging uses significantly more memory than ordinary
* journaling because there are multiple connections to the same database.
* So if a database will only be used by a single thread, or if optimizing
* concurrency is not very important, then write-ahead logging should be disabled.
* </p><p>
* After calling this method, execution of queries in parallel is enabled as long as
* the database remains open. To disable execution of queries in parallel, either
* call {@link #disableWriteAheadLogging} or close the database and reopen it.
* </p><p>
* The maximum number of connections used to execute queries in parallel is
* dependent upon the device memory and possibly other properties.
* <p>
* After calling this method, execution of queries in parallel is enabled as long as this
* database handle is open. To disable execution of queries in parallel, database should
* be closed and reopened.
* <p>
* </p><p>
* If a query is part of a transaction, then it is executed on the same database handle the
* transaction was begun.
* <p>
* If the database has any attached databases, then execution of queries in paralel is NOT
* possible. In such cases, a message is printed to logcat and false is returned.
* <p>
* This feature is not available for :memory: databases. In such cases,
* a message is printed to logcat and false is returned.
* <p>
* A typical way to use this method is the following:
* <pre>
* SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", cursorFactory,
* CREATE_IF_NECESSARY, myDatabaseErrorHandler);
* db.enableWriteAheadLogging();
* </pre>
* <p>
* </p><p>
* Writers should use {@link #beginTransactionNonExclusive()} or
* {@link #beginTransactionWithListenerNonExclusive(SQLiteTransactionListener)}
* to start a trsnsaction.
* Non-exclusive mode allows database file to be in readable by threads executing queries.
* to start a transaction. Non-exclusive mode allows database file to be in readable
* by other threads executing queries.
* </p><p>
* If the database has any attached databases, then execution of queries in parallel is NOT
* possible. Likewise, write-ahead logging is not supported for read-only databases
* or memory databases. In such cases, {@link #enableWriteAheadLogging} returns false.
* </p><p>
* The best way to enable write-ahead logging is to pass the
* {@link #ENABLE_WRITE_AHEAD_LOGGING} flag to {@link #openDatabase}. This is
* more efficient than calling {@link #enableWriteAheadLogging}.
* <code><pre>
* SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", cursorFactory,
* SQLiteDatabase.CREATE_IF_NECESSARY | SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING,
* myDatabaseErrorHandler);
* db.enableWriteAheadLogging();
* </pre></code>
* </p><p>
* Another way to enable write-ahead logging is to call {@link #enableWriteAheadLogging}
* after opening the database.
* <code><pre>
* SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", cursorFactory,
* SQLiteDatabase.CREATE_IF_NECESSARY, myDatabaseErrorHandler);
* db.enableWriteAheadLogging();
* </pre></code>
* </p><p>
* See also <a href="http://sqlite.org/wal.html">SQLite Write-Ahead Logging</a> for
* more details about how write-ahead logging works.
* </p>
*
* @return true if write-ahead-logging is set. false otherwise
* @return True if write-ahead logging is enabled.
*
* @throws 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.
*
* @see #ENABLE_WRITE_AHEAD_LOGGING
* @see #disableWriteAheadLogging
*/
public boolean enableWriteAheadLogging() {
synchronized (mLock) {
throwIfNotOpenLocked();
if (mConfigurationLocked.walEnabled) {
if ((mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) != 0) {
return true;
}
@@ -1855,14 +1895,11 @@ public final class SQLiteDatabase extends SQLiteClosable {
return false;
}
final int oldMaxConnectionPoolSize = mConfigurationLocked.maxConnectionPoolSize;
mConfigurationLocked.maxConnectionPoolSize = SQLiteGlobal.getWALConnectionPoolSize();
mConfigurationLocked.walEnabled = true;
mConfigurationLocked.openFlags |= ENABLE_WRITE_AHEAD_LOGGING;
try {
mConnectionPoolLocked.reconfigure(mConfigurationLocked);
} catch (RuntimeException ex) {
mConfigurationLocked.maxConnectionPoolSize = oldMaxConnectionPoolSize;
mConfigurationLocked.walEnabled = false;
mConfigurationLocked.openFlags &= ~ENABLE_WRITE_AHEAD_LOGGING;
throw ex;
}
}
@@ -1875,28 +1912,43 @@ public final class SQLiteDatabase extends SQLiteClosable {
* @throws 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.
*
* @see #enableWriteAheadLogging
*/
public void disableWriteAheadLogging() {
synchronized (mLock) {
throwIfNotOpenLocked();
if (!mConfigurationLocked.walEnabled) {
if ((mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) == 0) {
return;
}
final int oldMaxConnectionPoolSize = mConfigurationLocked.maxConnectionPoolSize;
mConfigurationLocked.maxConnectionPoolSize = 1;
mConfigurationLocked.walEnabled = false;
mConfigurationLocked.openFlags &= ~ENABLE_WRITE_AHEAD_LOGGING;
try {
mConnectionPoolLocked.reconfigure(mConfigurationLocked);
} catch (RuntimeException ex) {
mConfigurationLocked.maxConnectionPoolSize = oldMaxConnectionPoolSize;
mConfigurationLocked.walEnabled = true;
mConfigurationLocked.openFlags |= ENABLE_WRITE_AHEAD_LOGGING;
throw ex;
}
}
}
/**
* Returns true if write-ahead logging has been enabled for this database.
*
* @return True if write-ahead logging has been enabled for this database.
*
* @see #enableWriteAheadLogging
* @see #ENABLE_WRITE_AHEAD_LOGGING
*/
public boolean isWriteAheadLoggingEnabled() {
synchronized (mLock) {
throwIfNotOpenLocked();
return (mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) != 0;
}
}
/**
* Collect statistics about all open databases in the current process.
* Used by bug report.

View File

@@ -61,14 +61,6 @@ public final class SQLiteDatabaseConfiguration {
*/
public int openFlags;
/**
* The maximum number of connections to retain in the connection pool.
* Must be at least 1.
*
* Default is 1.
*/
public int maxConnectionPoolSize;
/**
* The maximum size of the prepared statement cache for each database connection.
* Must be non-negative.
@@ -84,13 +76,6 @@ public final class SQLiteDatabaseConfiguration {
*/
public Locale locale;
/**
* True if WAL mode is enabled.
*
* Default is false.
*/
public boolean walEnabled;
/**
* The custom functions to register.
*/
@@ -114,7 +99,6 @@ public final class SQLiteDatabaseConfiguration {
this.openFlags = openFlags;
// Set default values for optional parameters.
maxConnectionPoolSize = 1;
maxSqlCacheSize = 25;
locale = Locale.getDefault();
}
@@ -150,10 +134,8 @@ public final class SQLiteDatabaseConfiguration {
}
openFlags = other.openFlags;
maxConnectionPoolSize = other.maxConnectionPoolSize;
maxSqlCacheSize = other.maxSqlCacheSize;
locale = other.locale;
walEnabled = other.walEnabled;
customFunctions.clear();
customFunctions.addAll(other.customFunctions);
}

View File

@@ -58,6 +58,7 @@ public abstract class SQLiteOpenHelper {
private SQLiteDatabase mDatabase;
private boolean mIsInitializing;
private boolean mEnableWriteAheadLogging;
private final DatabaseErrorHandler mErrorHandler;
/**
@@ -74,7 +75,7 @@ public abstract class SQLiteOpenHelper {
* newer, {@link #onDowngrade} will be used to downgrade the database
*/
public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version) {
this(context, name, factory, version, new DefaultDatabaseErrorHandler());
this(context, name, factory, version, null);
}
/**
@@ -92,14 +93,11 @@ public abstract class SQLiteOpenHelper {
* {@link #onUpgrade} will be used to upgrade the database; if the database is
* newer, {@link #onDowngrade} will be used to downgrade the database
* @param errorHandler the {@link DatabaseErrorHandler} to be used when sqlite reports database
* corruption.
* corruption, or null to use the default error handler.
*/
public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version,
DatabaseErrorHandler errorHandler) {
if (version < 1) throw new IllegalArgumentException("Version must be >= 1, was " + version);
if (errorHandler == null) {
throw new IllegalArgumentException("DatabaseErrorHandler param value can't be null.");
}
mContext = context;
mName = name;
@@ -116,6 +114,32 @@ public abstract class SQLiteOpenHelper {
return mName;
}
/**
* Enables or disables the use of write-ahead logging for the database.
*
* Write-ahead logging cannot be used with read-only databases so the value of
* this flag is ignored if the database is opened read-only.
*
* @param enabled True if write-ahead logging should be enabled, false if it
* should be disabled.
*
* @see SQLiteDatabase#enableWriteAheadLogging()
*/
public void setWriteAheadLoggingEnabled(boolean enabled) {
synchronized (this) {
if (mEnableWriteAheadLogging != enabled) {
if (mDatabase != null && mDatabase.isOpen() && !mDatabase.isReadOnly()) {
if (enabled) {
mDatabase.enableWriteAheadLogging();
} else {
mDatabase.disableWriteAheadLogging();
}
}
mEnableWriteAheadLogging = enabled;
}
}
}
/**
* Create and/or open a database that will be used for reading and writing.
* The first time this is called, the database will be opened and
@@ -197,7 +221,9 @@ public abstract class SQLiteOpenHelper {
db = SQLiteDatabase.openDatabase(path, mFactory,
SQLiteDatabase.OPEN_READONLY, mErrorHandler);
} else {
db = mContext.openOrCreateDatabase(mName, 0, mFactory, mErrorHandler);
db = mContext.openOrCreateDatabase(mName, mEnableWriteAheadLogging ?
Context.MODE_ENABLE_WRITE_AHEAD_LOGGING : 0,
mFactory, mErrorHandler);
}
} catch (SQLiteException ex) {
if (writable) {

View File

@@ -84,6 +84,7 @@ public class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
mContext = context;
setWriteAheadLoggingEnabled(true);
}
public static boolean isValidTable(String name) {

View File

@@ -260,7 +260,6 @@ public class SettingsProvider extends ContentProvider {
// Watch for external modifications to the database file,
// keeping our cache in sync.
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
db.enableWriteAheadLogging();
sObserverInstance = new SettingsFileObserver(db.getPath());
sObserverInstance.startWatching();
startAsyncCachePopulation();