diff options
Diffstat (limited to 'core/java/android')
4 files changed, 137 insertions, 24 deletions
diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java index b692039c28e4..2c93a7fe26cd 100644 --- a/core/java/android/database/sqlite/SQLiteConnection.java +++ b/core/java/android/database/sqlite/SQLiteConnection.java @@ -289,14 +289,19 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen private void setWalModeFromConfiguration() { if (!mConfiguration.isInMemoryDb() && !mIsReadOnlyConnection) { - boolean walEnabled = + final boolean walEnabled = (mConfiguration.openFlags & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0; - if (walEnabled || mConfiguration.useCompatibilityWal) { + // Use compatibility WAL unless an app explicitly set journal/synchronous mode + final boolean useCompatibilityWal = mConfiguration.journalMode == null + && mConfiguration.syncMode == null && mConfiguration.useCompatibilityWal; + if (walEnabled || useCompatibilityWal) { setJournalMode("WAL"); setSyncMode(SQLiteGlobal.getWALSyncMode()); } else { - setJournalMode(SQLiteGlobal.getDefaultJournalMode()); - setSyncMode(SQLiteGlobal.getDefaultSyncMode()); + setJournalMode(mConfiguration.journalMode == null + ? SQLiteGlobal.getDefaultJournalMode() : mConfiguration.journalMode); + setSyncMode(mConfiguration.syncMode == null + ? SQLiteGlobal.getDefaultSyncMode() : mConfiguration.syncMode); } } } @@ -310,12 +315,10 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen } 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"; + switch (value) { + case "0": return "OFF"; + case "1": return "NORMAL"; + case "2": return "FULL"; } return value; } diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java index 83b8dc76bfc3..863fb1986e06 100644 --- a/core/java/android/database/sqlite/SQLiteDatabase.java +++ b/core/java/android/database/sqlite/SQLiteDatabase.java @@ -262,7 +262,8 @@ public final class SQLiteDatabase extends SQLiteClosable { private SQLiteDatabase(final String path, final int openFlags, CursorFactory cursorFactory, DatabaseErrorHandler errorHandler, - int lookasideSlotSize, int lookasideSlotCount, long idleConnectionTimeoutMs) { + int lookasideSlotSize, int lookasideSlotCount, long idleConnectionTimeoutMs, + String journalMode, String syncMode) { mCursorFactory = cursorFactory; mErrorHandler = errorHandler != null ? errorHandler : new DefaultDatabaseErrorHandler(); mConfigurationLocked = new SQLiteDatabaseConfiguration(path, openFlags); @@ -285,6 +286,8 @@ public final class SQLiteDatabase extends SQLiteClosable { } } mConfigurationLocked.idleConnectionTimeoutMs = effectiveTimeoutMs; + mConfigurationLocked.journalMode = journalMode; + mConfigurationLocked.syncMode = syncMode; mConfigurationLocked.useCompatibilityWal = SQLiteGlobal.isCompatibilityWalSupported(); } @@ -721,7 +724,7 @@ public final class SQLiteDatabase extends SQLiteClosable { SQLiteDatabase db = new SQLiteDatabase(path, openParams.mOpenFlags, openParams.mCursorFactory, openParams.mErrorHandler, openParams.mLookasideSlotSize, openParams.mLookasideSlotCount, - openParams.mIdleConnectionTimeout); + openParams.mIdleConnectionTimeout, openParams.mJournalMode, openParams.mSyncMode); db.open(); return db; } @@ -747,7 +750,8 @@ public final class SQLiteDatabase extends SQLiteClosable { */ public static SQLiteDatabase openDatabase(@NonNull String path, @Nullable CursorFactory factory, @DatabaseOpenFlags int flags, @Nullable DatabaseErrorHandler errorHandler) { - SQLiteDatabase db = new SQLiteDatabase(path, flags, factory, errorHandler, -1, -1, -1); + SQLiteDatabase db = new SQLiteDatabase(path, flags, factory, errorHandler, -1, -1, -1, null, + null); db.open(); return db; } @@ -2302,17 +2306,21 @@ public final class SQLiteDatabase extends SQLiteClosable { private final DatabaseErrorHandler mErrorHandler; private final int mLookasideSlotSize; private final int mLookasideSlotCount; - private long mIdleConnectionTimeout; + private final long mIdleConnectionTimeout; + private final String mJournalMode; + private final String mSyncMode; private OpenParams(int openFlags, CursorFactory cursorFactory, DatabaseErrorHandler errorHandler, int lookasideSlotSize, int lookasideSlotCount, - long idleConnectionTimeout) { + long idleConnectionTimeout, String journalMode, String syncMode) { mOpenFlags = openFlags; mCursorFactory = cursorFactory; mErrorHandler = errorHandler; mLookasideSlotSize = lookasideSlotSize; mLookasideSlotCount = lookasideSlotCount; mIdleConnectionTimeout = idleConnectionTimeout; + mJournalMode = journalMode; + mSyncMode = syncMode; } /** @@ -2379,6 +2387,28 @@ public final class SQLiteDatabase extends SQLiteClosable { } /** + * Returns <a href="https://sqlite.org/pragma.html#pragma_journal_mode">journal mode</a>. + * This journal mode will only be used if {@link SQLiteDatabase#ENABLE_WRITE_AHEAD_LOGGING} + * flag is not set, otherwise a platform will use "WAL" journal mode. + * @see Builder#setJournalMode(String) + */ + @Nullable + public String getJournalMode() { + return mJournalMode; + } + + /** + * Returns <a href="https://sqlite.org/pragma.html#pragma_synchronous">synchronous mode</a>. + * This value will only be used when {@link SQLiteDatabase#ENABLE_WRITE_AHEAD_LOGGING} flag + * is not set, otherwise a system wide default will be used. + * @see Builder#setSynchronousMode(String) + */ + @Nullable + public String getSynchronousMode() { + return mSyncMode; + } + + /** * Creates a new instance of builder {@link Builder#Builder(OpenParams) initialized} with * {@code this} parameters. * @hide @@ -2398,6 +2428,8 @@ public final class SQLiteDatabase extends SQLiteClosable { private int mOpenFlags; private CursorFactory mCursorFactory; private DatabaseErrorHandler mErrorHandler; + private String mJournalMode; + private String mSyncMode; public Builder() { } @@ -2408,6 +2440,8 @@ public final class SQLiteDatabase extends SQLiteClosable { mOpenFlags = params.mOpenFlags; mCursorFactory = params.mCursorFactory; mErrorHandler = params.mErrorHandler; + mJournalMode = params.mJournalMode; + mSyncMode = params.mSyncMode; } /** @@ -2539,6 +2573,30 @@ public final class SQLiteDatabase extends SQLiteClosable { return this; } + + /** + * Sets <a href="https://sqlite.org/pragma.html#pragma_journal_mode">journal mode</a> + * to use when {@link SQLiteDatabase#ENABLE_WRITE_AHEAD_LOGGING} flag is not set. + */ + @NonNull + public Builder setJournalMode(@NonNull String journalMode) { + Preconditions.checkNotNull(journalMode); + mJournalMode = journalMode; + return this; + } + + /** + * Sets <a href="https://sqlite.org/pragma.html#pragma_synchronous">synchronous mode</a> + * to use when {@link SQLiteDatabase#ENABLE_WRITE_AHEAD_LOGGING} flag is not set. + * @return + */ + @NonNull + public Builder setSynchronousMode(@NonNull String syncMode) { + Preconditions.checkNotNull(syncMode); + mSyncMode = syncMode; + return this; + } + /** * Creates an instance of {@link OpenParams} with the options that were previously set * on this builder @@ -2546,7 +2604,7 @@ public final class SQLiteDatabase extends SQLiteClosable { @NonNull public OpenParams build() { return new OpenParams(mOpenFlags, mCursorFactory, mErrorHandler, mLookasideSlotSize, - mLookasideSlotCount, mIdleConnectionTimeout); + mLookasideSlotCount, mIdleConnectionTimeout, mJournalMode, mSyncMode); } } } @@ -2561,4 +2619,6 @@ public final class SQLiteDatabase extends SQLiteClosable { }) @Retention(RetentionPolicy.SOURCE) public @interface DatabaseOpenFlags {} + } + diff --git a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java index 905da7247308..a14df1ebcbc6 100644 --- a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java +++ b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java @@ -120,6 +120,18 @@ public final class SQLiteDatabaseConfiguration { public boolean useCompatibilityWal; /** + * Journal mode to use when {@link SQLiteDatabase#ENABLE_WRITE_AHEAD_LOGGING} is not set. + * <p>Default is returned by {@link SQLiteGlobal#getDefaultJournalMode()} + */ + public String journalMode; + + /** + * Synchronous mode to use when {@link SQLiteDatabase#ENABLE_WRITE_AHEAD_LOGGING} is not set. + * <p>Default is returned by {@link SQLiteGlobal#getDefaultSyncMode()} + */ + public String syncMode; + + /** * Creates a database configuration with the required parameters for opening a * database and default values for all other parameters. * @@ -180,6 +192,8 @@ public final class SQLiteDatabaseConfiguration { lookasideSlotCount = other.lookasideSlotCount; idleConnectionTimeoutMs = other.idleConnectionTimeoutMs; useCompatibilityWal = other.useCompatibilityWal; + journalMode = other.journalMode; + syncMode = other.syncMode; } /** diff --git a/core/java/android/database/sqlite/SQLiteOpenHelper.java b/core/java/android/database/sqlite/SQLiteOpenHelper.java index cc9e0f4ded84..d4699a8d71cd 100644 --- a/core/java/android/database/sqlite/SQLiteOpenHelper.java +++ b/core/java/android/database/sqlite/SQLiteOpenHelper.java @@ -17,6 +17,8 @@ package android.database.sqlite; import android.annotation.IntRange; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.content.Context; import android.database.DatabaseErrorHandler; import android.database.SQLException; @@ -24,6 +26,8 @@ import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.os.FileUtils; import android.util.Log; +import com.android.internal.util.Preconditions; + import java.io.File; /** @@ -69,7 +73,8 @@ 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 */ - public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version) { + public SQLiteOpenHelper(@NonNull Context context, @Nullable String name, + @Nullable CursorFactory factory, int version) { this(context, name, factory, version, null); } @@ -90,12 +95,33 @@ public abstract class SQLiteOpenHelper { * @param errorHandler the {@link DatabaseErrorHandler} to be used when sqlite reports database * corruption, or null to use the default error handler. */ - public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version, - DatabaseErrorHandler errorHandler) { + public SQLiteOpenHelper(@NonNull Context context, @Nullable String name, + @Nullable CursorFactory factory, int version, + @Nullable DatabaseErrorHandler errorHandler) { this(context, name, factory, version, 0, errorHandler); } /** + * Create a helper object to create, open, and/or manage a database. + * This method always returns very quickly. The database is not actually + * created or opened until one of {@link #getWritableDatabase} or + * {@link #getReadableDatabase} is called. + * + * @param context to use to open or create the database + * @param name of the database file, or null for an in-memory database + * @param version number of the database (starting at 1); if the database is older, + * {@link #onUpgrade} will be used to upgrade the database; if the database is + * newer, {@link #onDowngrade} will be used to downgrade the database + * @param openParams configuration parameters that are used for opening {@link SQLiteDatabase}. + * Please note that {@link SQLiteDatabase#CREATE_IF_NECESSARY} flag will always be + * set when the helper opens the database + */ + public SQLiteOpenHelper(@NonNull Context context, @Nullable String name, int version, + @NonNull SQLiteDatabase.OpenParams openParams) { + this(context, name, version, 0, openParams.toBuilder()); + } + + /** * Same as {@link #SQLiteOpenHelper(Context, String, CursorFactory, int, DatabaseErrorHandler)} * but also accepts an integer minimumSupportedVersion as a convenience for upgrading very old * versions of this database that are no longer supported. If a database with older version that @@ -118,17 +144,27 @@ public abstract class SQLiteOpenHelper { * @see #onUpgrade(SQLiteDatabase, int, int) * @hide */ - public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version, - int minimumSupportedVersion, DatabaseErrorHandler errorHandler) { + public SQLiteOpenHelper(@NonNull Context context, @Nullable String name, + @Nullable CursorFactory factory, int version, + int minimumSupportedVersion, @Nullable DatabaseErrorHandler errorHandler) { + this(context, name, version, minimumSupportedVersion, + new SQLiteDatabase.OpenParams.Builder()); + mOpenParamsBuilder.setCursorFactory(factory); + mOpenParamsBuilder.setErrorHandler(errorHandler); + } + + private SQLiteOpenHelper(@NonNull Context context, @Nullable String name, int version, + int minimumSupportedVersion, + @NonNull SQLiteDatabase.OpenParams.Builder openParamsBuilder) { + Preconditions.checkNotNull(context); + Preconditions.checkNotNull(openParamsBuilder); if (version < 1) throw new IllegalArgumentException("Version must be >= 1, was " + version); mContext = context; mName = name; mNewVersion = version; mMinimumSupportedVersion = Math.max(0, minimumSupportedVersion); - mOpenParamsBuilder = new SQLiteDatabase.OpenParams.Builder(); - mOpenParamsBuilder.setCursorFactory(factory); - mOpenParamsBuilder.setErrorHandler(errorHandler); + mOpenParamsBuilder = openParamsBuilder; mOpenParamsBuilder.addOpenFlags(SQLiteDatabase.CREATE_IF_NECESSARY); } |
