Merge "Add package-private DelegatingOpenHelper and have SqliteCopyOpenHelper and QueryInterceptorOpenHelper implement it so that they can be configured in the RoomDataBase.init block." into androidx-main
diff --git a/room/runtime/src/androidTest/java/androidx/room/AutoClosingRoomOpenHelperTest.kt b/room/runtime/src/androidTest/java/androidx/room/AutoClosingRoomOpenHelperTest.kt
index e19a845..c601d2e 100644
--- a/room/runtime/src/androidTest/java/androidx/room/AutoClosingRoomOpenHelperTest.kt
+++ b/room/runtime/src/androidTest/java/androidx/room/AutoClosingRoomOpenHelperTest.kt
@@ -237,4 +237,25 @@
assertThat(it.isNull(4)).isTrue()
}
}
+
+ @Test
+ public fun testGetDelegate() {
+ val delegateOpenHelper = FrameworkSQLiteOpenHelperFactory()
+ .create(
+ SupportSQLiteOpenHelper.Configuration
+ .builder(ApplicationProvider.getApplicationContext())
+ .callback(Callback())
+ .name("name")
+ .build()
+ )
+
+ val autoCloseExecutor = Executors.newSingleThreadExecutor()
+
+ val autoClosing = AutoClosingRoomOpenHelper(
+ delegateOpenHelper,
+ AutoCloser(0, TimeUnit.MILLISECONDS, autoCloseExecutor)
+ )
+
+ assertThat(autoClosing.getDelegate()).isSameInstanceAs(delegateOpenHelper)
+ }
}
\ No newline at end of file
diff --git a/room/runtime/src/main/java/androidx/room/AutoClosingRoomOpenHelper.java b/room/runtime/src/main/java/androidx/room/AutoClosingRoomOpenHelper.java
index 87d364f..9aabf95 100644
--- a/room/runtime/src/main/java/androidx/room/AutoClosingRoomOpenHelper.java
+++ b/room/runtime/src/main/java/androidx/room/AutoClosingRoomOpenHelper.java
@@ -48,7 +48,7 @@
/**
* A SupportSQLiteOpenHelper that has autoclose enabled for database connections.
*/
-final class AutoClosingRoomOpenHelper implements SupportSQLiteOpenHelper {
+final class AutoClosingRoomOpenHelper implements SupportSQLiteOpenHelper, DelegatingOpenHelper {
@NonNull
private final SupportSQLiteOpenHelper mDelegateOpenHelper;
@@ -116,6 +116,12 @@
return this.mAutoClosingDb;
}
+ @Override
+ @NonNull
+ public SupportSQLiteOpenHelper getDelegate() {
+ return mDelegateOpenHelper;
+ }
+
/**
* SupportSQLiteDatabase that also keeps refcounts and autocloses the database
*/
diff --git a/room/runtime/src/main/java/androidx/room/DelegatingOpenHelper.java b/room/runtime/src/main/java/androidx/room/DelegatingOpenHelper.java
new file mode 100644
index 0000000..7c84fc5
--- /dev/null
+++ b/room/runtime/src/main/java/androidx/room/DelegatingOpenHelper.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package androidx.room;
+
+import androidx.annotation.NonNull;
+import androidx.sqlite.db.SupportSQLiteOpenHelper;
+
+/**
+ * Package private interface for OpenHelpers which delegate to other open helpers.
+ *
+ * TODO(b/175612939): delete this interface once implementations are merged.
+ */
+interface DelegatingOpenHelper {
+
+ /**
+ * Returns the delegate open helper (which may itself be a DelegatingOpenHelper) so
+ * configurations on specific instances can be applied.
+ *
+ * @return the delegate
+ */
+ @NonNull
+ SupportSQLiteOpenHelper getDelegate();
+}
diff --git a/room/runtime/src/main/java/androidx/room/QueryInterceptorOpenHelper.java b/room/runtime/src/main/java/androidx/room/QueryInterceptorOpenHelper.java
index c2ca486..9916294 100644
--- a/room/runtime/src/main/java/androidx/room/QueryInterceptorOpenHelper.java
+++ b/room/runtime/src/main/java/androidx/room/QueryInterceptorOpenHelper.java
@@ -26,7 +26,7 @@
import java.util.concurrent.Executor;
-final class QueryInterceptorOpenHelper implements SupportSQLiteOpenHelper {
+final class QueryInterceptorOpenHelper implements SupportSQLiteOpenHelper, DelegatingOpenHelper {
private final SupportSQLiteOpenHelper mDelegate;
private final RoomDatabase.QueryCallback mQueryCallback;
@@ -68,4 +68,11 @@
public void close() {
mDelegate.close();
}
+
+ @Override
+ @NonNull
+ public SupportSQLiteOpenHelper getDelegate() {
+ return mDelegate;
+ }
+
}
diff --git a/room/runtime/src/main/java/androidx/room/RoomDatabase.java b/room/runtime/src/main/java/androidx/room/RoomDatabase.java
index 4561876..0fa15d8 100644
--- a/room/runtime/src/main/java/androidx/room/RoomDatabase.java
+++ b/room/runtime/src/main/java/androidx/room/RoomDatabase.java
@@ -179,10 +179,14 @@
@CallSuper
public void init(@NonNull DatabaseConfiguration configuration) {
mOpenHelper = createOpenHelper(configuration);
- if (mOpenHelper instanceof SQLiteCopyOpenHelper) {
- SQLiteCopyOpenHelper copyOpenHelper = (SQLiteCopyOpenHelper) mOpenHelper;
+
+ // Configure SqliteCopyOpenHelper if it is available:
+ SQLiteCopyOpenHelper copyOpenHelper = unwrapOpenHelper(SQLiteCopyOpenHelper.class,
+ mOpenHelper);
+ if (copyOpenHelper != null) {
copyOpenHelper.setDatabaseConfiguration(configuration);
}
+
boolean wal = false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
wal = configuration.journalMode == JournalMode.WRITE_AHEAD_LOGGING;
@@ -239,6 +243,26 @@
}
/**
+ * Unwraps (delegating) open helpers until it finds clazz, otherwise returns null.
+ *
+ * @param clazz the open helper type to search for
+ * @param openHelper the open helper to search through
+ * @param <T> the type of clazz
+ * @return the instance of clazz, otherwise null
+ */
+ @Nullable
+ @SuppressWarnings("unchecked")
+ private <T> T unwrapOpenHelper(Class<T> clazz, SupportSQLiteOpenHelper openHelper) {
+ if (clazz.isInstance(openHelper)) {
+ return (T) openHelper;
+ }
+ if (openHelper instanceof DelegatingOpenHelper) {
+ return unwrapOpenHelper(clazz, ((DelegatingOpenHelper) openHelper).getDelegate());
+ }
+ return null;
+ }
+
+ /**
* Returns the SQLite open helper used by this database.
*
* @return The SQLite open helper used by this database.
diff --git a/room/runtime/src/main/java/androidx/room/SQLiteCopyOpenHelper.java b/room/runtime/src/main/java/androidx/room/SQLiteCopyOpenHelper.java
index dc45973..b7d244e 100644
--- a/room/runtime/src/main/java/androidx/room/SQLiteCopyOpenHelper.java
+++ b/room/runtime/src/main/java/androidx/room/SQLiteCopyOpenHelper.java
@@ -44,7 +44,7 @@
* An open helper that will copy & open a pre-populated database if it doesn't exists in internal
* storage.
*/
-class SQLiteCopyOpenHelper implements SupportSQLiteOpenHelper {
+class SQLiteCopyOpenHelper implements SupportSQLiteOpenHelper, DelegatingOpenHelper {
@NonNull
private final Context mContext;
@@ -112,6 +112,12 @@
mVerified = false;
}
+ @Override
+ @NonNull
+ public SupportSQLiteOpenHelper getDelegate() {
+ return mDelegate;
+ }
+
// Can't be constructor param because the factory is needed by the database builder which in
// turn is the one that actually builds the configuration.
void setDatabaseConfiguration(@Nullable DatabaseConfiguration databaseConfiguration) {
@@ -253,7 +259,7 @@
FrameworkSQLiteOpenHelperFactory factory = new FrameworkSQLiteOpenHelperFactory();
Configuration configuration = Configuration.builder(mContext)
.name(databaseName)
- .callback(new Callback(version){
+ .callback(new Callback(version) {
@Override
public void onCreate(@NonNull SupportSQLiteDatabase db) {
}
diff --git a/room/runtime/src/test/java/androidx/room/SQLiteCopyOpenHelperTest.kt b/room/runtime/src/test/java/androidx/room/SQLiteCopyOpenHelperTest.kt
index 7f4cb20..78e64d0 100644
--- a/room/runtime/src/test/java/androidx/room/SQLiteCopyOpenHelperTest.kt
+++ b/room/runtime/src/test/java/androidx/room/SQLiteCopyOpenHelperTest.kt
@@ -20,6 +20,7 @@
import android.content.res.AssetManager
import androidx.sqlite.db.SupportSQLiteOpenHelper
import org.junit.Assert.assertEquals
+import org.junit.Assert.assertSame
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
@@ -184,6 +185,13 @@
assertEquals(1, exceptions.size)
}
+ @Test
+ fun testGetDelegate() {
+ val openHelper = createOpenHelper(tempDirectory.newFile("toCopy.db"))
+
+ assertSame(delegate, openHelper.getDelegate())
+ }
+
internal fun setupMocks(tmpDir: File, copyFromFile: File, onAssetOpen: () -> Unit = {}) {
`when`(delegate.databaseName).thenReturn(DB_NAME)
`when`(context.getDatabasePath(DB_NAME)).thenReturn(File(tmpDir, DB_NAME))