Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cc001fda authored by Jeff Brown's avatar Jeff Brown Committed by Android (Google) Code Review
Browse files

Merge "Provide an API for enabling foreign key constraints."

parents 69f819b3 96496adb
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -7364,6 +7364,7 @@ package android.database.sqlite {
    method public static int releaseMemory();
    method public long replace(java.lang.String, java.lang.String, android.content.ContentValues);
    method public long replaceOrThrow(java.lang.String, java.lang.String, android.content.ContentValues) throws android.database.SQLException;
    method public void setForeignKeyConstraintsEnabled(boolean);
    method public void setLocale(java.util.Locale);
    method public deprecated void setLockingEnabled(boolean);
    method public void setMaxSqlCacheSize(int);
@@ -7443,6 +7444,7 @@ package android.database.sqlite {
    method public java.lang.String getDatabaseName();
    method public android.database.sqlite.SQLiteDatabase getReadableDatabase();
    method public android.database.sqlite.SQLiteDatabase getWritableDatabase();
    method public void onConfigure(android.database.sqlite.SQLiteDatabase);
    method public abstract void onCreate(android.database.sqlite.SQLiteDatabase);
    method public void onDowngrade(android.database.sqlite.SQLiteDatabase, int, int);
    method public void onOpen(android.database.sqlite.SQLiteDatabase);
+18 −0
Original line number Diff line number Diff line
@@ -211,6 +211,7 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen
                SQLiteDebug.DEBUG_SQL_STATEMENTS, SQLiteDebug.DEBUG_SQL_TIME);

        setPageSize();
        setForeignKeyModeFromConfiguration();
        setWalModeFromConfiguration();
        setJournalSizeLimit();
        setAutoCheckpointInterval();
@@ -267,6 +268,16 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen
        }
    }

    private void setForeignKeyModeFromConfiguration() {
        if (!mIsReadOnlyConnection) {
            final long newValue = mConfiguration.foreignKeyConstraintsEnabled ? 1 : 0;
            long value = executeForLong("PRAGMA foreign_keys", null, null);
            if (value != newValue) {
                execute("PRAGMA foreign_keys=" + newValue, null, null);
            }
        }
    }

    private void setWalModeFromConfiguration() {
        if (!mConfiguration.isInMemoryDb() && !mIsReadOnlyConnection) {
            if ((mConfiguration.openFlags & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0) {
@@ -389,6 +400,8 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen
        }

        // Remember what changed.
        boolean foreignKeyModeChanged = configuration.foreignKeyConstraintsEnabled
                != mConfiguration.foreignKeyConstraintsEnabled;
        boolean walModeChanged = ((configuration.openFlags ^ mConfiguration.openFlags)
                & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0;
        boolean localeChanged = !configuration.locale.equals(mConfiguration.locale);
@@ -399,6 +412,11 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen
        // Update prepared statement cache size.
        mPreparedStatementCache.resize(configuration.maxSqlCacheSize);

        // Update foreign key mode.
        if (foreignKeyModeChanged) {
            setForeignKeyModeFromConfiguration();
        }

        // Update WAL.
        if (walModeChanged) {
            setWalModeFromConfiguration();
+14 −0
Original line number Diff line number Diff line
@@ -277,6 +277,20 @@ public final class SQLiteConnectionPool implements Closeable {
                assert mAvailableNonPrimaryConnections.isEmpty();
            }

            boolean foreignKeyModeChanged = configuration.foreignKeyConstraintsEnabled
                    != mConfiguration.foreignKeyConstraintsEnabled;
            if (foreignKeyModeChanged) {
                // Foreign key constraints can only be changed if there are no transactions
                // in progress.  To make this clear, we throw an exception if there are
                // any acquired connections.
                if (!mAcquiredConnections.isEmpty()) {
                    throw new IllegalStateException("Foreign Key Constraints cannot "
                            + "be enabled or disabled while there are transactions in "
                            + "progress.  Finish all transactions and release all active "
                            + "database connections first.");
                }
            }

            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
+47 −0
Original line number Diff line number Diff line
@@ -1792,6 +1792,53 @@ public final class SQLiteDatabase extends SQLiteClosable {
        }
    }

    /**
     * Sets whether foreign key constraints are enabled for the database.
     * <p>
     * By default, foreign key constraints are not enforced by the database.
     * This method allows an application to enable foreign key constraints.
     * It must be called each time the database is opened to ensure that foreign
     * key constraints are enabled for the session.
     * </p><p>
     * A good time to call this method is right after calling {@link #openOrCreateDatabase}
     * or in the {@link SQLiteOpenHelper#onConfigure} callback.
     * </p><p>
     * When foreign key constraints are disabled, the database does not check whether
     * changes to the database will violate foreign key constraints.  Likewise, when
     * foreign key constraints are disabled, the database will not execute cascade
     * delete or update triggers.  As a result, it is possible for the database
     * state to become inconsistent.  To perform a database integrity check,
     * call {@link #isDatabaseIntegrityOk}.
     * </p><p>
     * This method must not be called while a transaction is in progress.
     * </p><p>
     * See also <a href="http://sqlite.org/foreignkeys.html">SQLite Foreign Key Constraints</a>
     * for more details about foreign key constraint support.
     * </p>
     *
     * @param enable True to enable foreign key constraints, false to disable them.
     *
     * @throws IllegalStateException if the are transactions is in progress
     * when this method is called.
     */
    public void setForeignKeyConstraintsEnabled(boolean enable) {
        synchronized (mLock) {
            throwIfNotOpenLocked();

            if (mConfigurationLocked.foreignKeyConstraintsEnabled == enable) {
                return;
            }

            mConfigurationLocked.foreignKeyConstraintsEnabled = enable;
            try {
                mConnectionPoolLocked.reconfigure(mConfigurationLocked);
            } catch (RuntimeException ex) {
                mConfigurationLocked.foreignKeyConstraintsEnabled = !enable;
                throw ex;
            }
        }
    }

    /**
     * This method enables parallel execution of queries from multiple threads on the
     * same database.  It does this by opening multiple connections to the database
+8 −0
Original line number Diff line number Diff line
@@ -76,6 +76,13 @@ public final class SQLiteDatabaseConfiguration {
     */
    public Locale locale;

    /**
     * True if foreign key constraints are enabled.
     *
     * Default is false.
     */
    public boolean foreignKeyConstraintsEnabled;

    /**
     * The custom functions to register.
     */
@@ -136,6 +143,7 @@ public final class SQLiteDatabaseConfiguration {
        openFlags = other.openFlags;
        maxSqlCacheSize = other.maxSqlCacheSize;
        locale = other.locale;
        foreignKeyConstraintsEnabled = other.foreignKeyConstraintsEnabled;
        customFunctions.clear();
        customFunctions.addAll(other.customFunctions);
    }
Loading