From be39c559f6822bb256c995b3fba1e337660acb85 Mon Sep 17 00:00:00 2001 From: Scott Olsen Date: Mon, 6 Nov 2023 13:02:52 -0500 Subject: [PATCH] Fix TileSourceEntity id generation. (#2045) * Fix TileSourceEntity id generation. Room treats non-null values assigned to boxed types (e.g. Int?, Integer) as explicit values and will not auto-generate IDs when these values are provided. This was causing UNIQUNESS constraint failures when inserting/updating tilesource entites, as we were using `0` as a default. Converting to a non-boxed primitive type `Int` results in the correct behavior (Room treats `0` as an indicator that a value should be generated). --- .../main/java/com/google/android/ground/Config.kt | 2 +- .../local/room/entity/TileSourceEntity.kt | 2 +- .../persistence/local/LocalDataStoreTests.kt | 15 +++++++++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/ground/src/main/java/com/google/android/ground/Config.kt b/ground/src/main/java/com/google/android/ground/Config.kt index 6af2383c43..238d04befc 100644 --- a/ground/src/main/java/com/google/android/ground/Config.kt +++ b/ground/src/main/java/com/google/android/ground/Config.kt @@ -26,7 +26,7 @@ object Config { // Local db settings. // TODO(#128): Reset version to 1 before releasing. - const val DB_VERSION = 108 + const val DB_VERSION = 109 const val DB_NAME = "ground.db" // Firebase Cloud Firestore settings. diff --git a/ground/src/main/java/com/google/android/ground/persistence/local/room/entity/TileSourceEntity.kt b/ground/src/main/java/com/google/android/ground/persistence/local/room/entity/TileSourceEntity.kt index 2ca45558a6..5d3ef6d04a 100644 --- a/ground/src/main/java/com/google/android/ground/persistence/local/room/entity/TileSourceEntity.kt +++ b/ground/src/main/java/com/google/android/ground/persistence/local/room/entity/TileSourceEntity.kt @@ -35,7 +35,7 @@ import androidx.room.PrimaryKey indices = [Index("survey_id")] ) data class TileSourceEntity( - @ColumnInfo(name = "id") @PrimaryKey(autoGenerate = true) val id: Int? = 0, + @ColumnInfo(name = "id") @PrimaryKey(autoGenerate = true) val id: Int = 0, @ColumnInfo(name = "survey_id") val surveyId: String, @ColumnInfo(name = "url") val url: String, @ColumnInfo(name = "type") val type: TileSourceEntityType diff --git a/ground/src/test/java/com/google/android/ground/persistence/local/LocalDataStoreTests.kt b/ground/src/test/java/com/google/android/ground/persistence/local/LocalDataStoreTests.kt index fc0ab1804e..864ad67aaa 100644 --- a/ground/src/test/java/com/google/android/ground/persistence/local/LocalDataStoreTests.kt +++ b/ground/src/test/java/com/google/android/ground/persistence/local/LocalDataStoreTests.kt @@ -24,6 +24,7 @@ import com.google.android.ground.model.geometry.LinearRing import com.google.android.ground.model.geometry.Point import com.google.android.ground.model.geometry.Polygon import com.google.android.ground.model.imagery.OfflineArea +import com.google.android.ground.model.imagery.TileSource import com.google.android.ground.model.job.Job import com.google.android.ground.model.job.Style import com.google.android.ground.model.mutation.LocationOfInterestMutation @@ -375,6 +376,12 @@ class LocalDataStoreTests : BaseHiltTest() { assertThat(localValueStore.isTermsOfServiceAccepted).isFalse() } + @Test + fun testInsertOrUpdateSurvey_usesUniqueKeyForTileSources() = runWithTestDispatcher { + // Should not throw. + localSurveyStore.insertOrUpdateSurvey(TEST_SURVEY_WITH_TILE_SOURCES) + } + companion object { private val TEST_USER = User("user id", "user@gmail.com", "user 1") private val TEST_TASK = Task("task id", 1, Task.Type.TEXT, "task label", false) @@ -383,6 +390,14 @@ class LocalDataStoreTests : BaseHiltTest() { Job("job id", TEST_STYLE, "heading title", mapOf(Pair(TEST_TASK.id, TEST_TASK))) private val TEST_SURVEY = Survey("survey id", "survey 1", "foo description", mapOf(Pair(TEST_JOB.id, TEST_JOB))) + private val TEST_SURVEY_WITH_TILE_SOURCES = + TEST_SURVEY.copy( + tileSources = + listOf( + TileSource(url = "dummy URL", type = TileSource.Type.TILED_WEB_MAP), + TileSource(url = "other dummy URL", type = TileSource.Type.TILED_WEB_MAP) + ) + ) private val TEST_POINT = Point(Coordinates(110.0, -23.1)) private val TEST_POINT_2 = Point(Coordinates(51.0, 44.0)) private val TEST_POLYGON_1 =