Skip to content

Commit a21e824

Browse files
authored
Include index_name column in index for tables used in sorting (#2753)
* Include index_name column in index for tables used in sorting * Add index migration tests * Add index_value/index_from to make sorting index covering * Update Licence year to fix spotless
1 parent 87fa2ae commit a21e824

File tree

8 files changed

+1140
-12
lines changed

8 files changed

+1140
-12
lines changed

engine/schemas/com.google.android.fhir.db.impl.ResourceDatabase/10.json

Lines changed: 1032 additions & 0 deletions
Large diffs are not rendered by default.

engine/src/androidTest/java/com/google/android/fhir/db/impl/ResourceDatabaseMigrationTest.kt

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023-2024 Google LLC
2+
* Copyright 2023-2025 Google LLC
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -418,6 +418,72 @@ class ResourceDatabaseMigrationTest {
418418
assertThat(retrievedTask).isEqualTo(bedNetTask)
419419
}
420420

421+
@Test
422+
fun migrate9To10_should_execute_with_no_exception(): Unit = runBlocking {
423+
val patient1Id = "patient-001"
424+
val patient1ResourceUuid = "e2c79e28-ed4d-4029-a12c-108d1eb5bedb"
425+
val patient1: String =
426+
Patient()
427+
.apply {
428+
id = patient1Id
429+
addName(HumanName().apply { addGiven("Brad") })
430+
}
431+
.let { iParser.encodeResourceToString(it) }
432+
433+
val patient2Id = "patient-002"
434+
val patient2ResourceUuid = "541782b3-48f5-4c36-bd20-cae265e974e7"
435+
val patient2: String =
436+
Patient()
437+
.apply {
438+
id = patient2Id
439+
addName(HumanName().apply { addGiven("Alex") })
440+
}
441+
.let { iParser.encodeResourceToString(it) }
442+
443+
helper.createDatabase(DB_NAME, 9).apply {
444+
execSQL(
445+
"INSERT INTO ResourceEntity (resourceUuid, resourceType, resourceId, serializedResource) VALUES ('$patient1ResourceUuid', 'Patient', '$patient1', '$patient1');",
446+
)
447+
execSQL(
448+
"INSERT INTO ResourceEntity (resourceUuid, resourceType, resourceId, serializedResource) VALUES ('$patient2ResourceUuid', 'Patient', '$patient2', '$patient2');",
449+
)
450+
451+
close()
452+
}
453+
454+
val migratedDatabase = helper.runMigrationsAndValidate(DB_NAME, 10, true, Migration_9_10)
455+
456+
val patientResult1: String?
457+
val patientResult2: String?
458+
459+
migratedDatabase.let { database ->
460+
database
461+
.query(
462+
"""
463+
SELECT a.serializedResource
464+
FROM ResourceEntity a
465+
LEFT JOIN StringIndexEntity b
466+
ON a.resourceUuid = b.resourceUuid AND b.index_name = 'name'
467+
WHERE a.resourceType = 'Patient'
468+
GROUP BY a.resourceUuid
469+
HAVING MAX(IFNULL(b.index_value,0)) >= -9223372036854775808
470+
ORDER BY IFNULL(b.index_value, -9223372036854775808) ASC
471+
"""
472+
.trimIndent(),
473+
)
474+
.let {
475+
it.moveToFirst()
476+
patientResult1 = it.getString(0)
477+
it.moveToNext()
478+
patientResult2 = it.getString(0)
479+
}
480+
}
481+
migratedDatabase.close()
482+
483+
assertThat(patientResult1).isEqualTo(patient2)
484+
assertThat(patientResult2).isEqualTo(patient1)
485+
}
486+
421487
companion object {
422488
const val DB_NAME = "migration_tests.db"
423489
}

engine/src/main/java/com/google/android/fhir/db/impl/DatabaseImpl.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023-2024 Google LLC
2+
* Copyright 2023-2025 Google LLC
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -115,6 +115,7 @@ internal class DatabaseImpl(
115115
MIGRATION_6_7,
116116
MIGRATION_7_8,
117117
Migration_8_9,
118+
Migration_9_10,
118119
)
119120
}
120121
.build()

engine/src/main/java/com/google/android/fhir/db/impl/ResourceDatabase.kt

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023-2024 Google LLC
2+
* Copyright 2023-2025 Google LLC
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -54,7 +54,7 @@ import org.json.JSONObject
5454
PositionIndexEntity::class,
5555
LocalChangeResourceReferenceEntity::class,
5656
],
57-
version = 9,
57+
version = 10,
5858
exportSchema = true,
5959
)
6060
@TypeConverters(DbTypeConverters::class)
@@ -226,3 +226,32 @@ internal val Migration_8_9 =
226226
}
227227
}
228228
}
229+
230+
internal val Migration_9_10 =
231+
object : Migration(9, 10) {
232+
override fun migrate(database: SupportSQLiteDatabase) {
233+
database.beginTransaction()
234+
try {
235+
database.execSQL("DROP INDEX IF EXISTS `index_DateIndexEntity_resourceUuid`;")
236+
database.execSQL("DROP INDEX IF EXISTS `index_DateTimeIndexEntity_resourceUuid`;")
237+
database.execSQL("DROP INDEX IF EXISTS `index_NumberIndexEntity_resourceUuid`;")
238+
database.execSQL("DROP INDEX IF EXISTS `index_StringIndexEntity_resourceUuid`;")
239+
240+
database.execSQL(
241+
"CREATE INDEX IF NOT EXISTS `index_DateIndexEntity_resourceUuid_index_name_index_from` ON `DateIndexEntity` (`resourceUuid`, `index_name`, `index_from`);",
242+
)
243+
database.execSQL(
244+
"CREATE INDEX IF NOT EXISTS `index_DateTimeIndexEntity_resourceUuid_index_name_index_from` ON `DateTimeIndexEntity` (`resourceUuid`, `index_name`, `index_from`);",
245+
)
246+
database.execSQL(
247+
"CREATE INDEX IF NOT EXISTS `index_NumberIndexEntity_resourceUuid_index_name_index_value` ON `NumberIndexEntity` (`resourceUuid`, `index_name`, `index_value`);",
248+
)
249+
database.execSQL(
250+
"CREATE INDEX IF NOT EXISTS `index_StringIndexEntity_resourceUuid_index_name_index_value` ON `StringIndexEntity` (`resourceUuid`, `index_name`, `index_value`);",
251+
)
252+
database.setTransactionSuccessful()
253+
} finally {
254+
database.endTransaction()
255+
}
256+
}
257+
}

engine/src/main/java/com/google/android/fhir/db/impl/entities/DateIndexEntity.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023 Google LLC
2+
* Copyright 2023-2025 Google LLC
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -34,7 +34,7 @@ import org.hl7.fhir.r4.model.ResourceType
3434
// https://github.com/google/android-fhir/issues/2040
3535
Index(value = ["resourceType", "index_name", "resourceUuid", "index_from", "index_to"]),
3636
// Keep this index for faster foreign lookup
37-
Index(value = ["resourceUuid"]),
37+
Index(value = ["resourceUuid", "index_name", "index_from"]),
3838
],
3939
foreignKeys =
4040
[

engine/src/main/java/com/google/android/fhir/db/impl/entities/DateTimeIndexEntity.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023 Google LLC
2+
* Copyright 2023-2025 Google LLC
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -34,7 +34,7 @@ import org.hl7.fhir.r4.model.ResourceType
3434
// https://github.com/google/android-fhir/issues/2040
3535
Index(value = ["resourceType", "index_name", "resourceUuid", "index_from", "index_to"]),
3636
// Keep this index for faster foreign lookup
37-
Index(value = ["resourceUuid"]),
37+
Index(value = ["resourceUuid", "index_name", "index_from"]),
3838
],
3939
foreignKeys =
4040
[

engine/src/main/java/com/google/android/fhir/db/impl/entities/NumberIndexEntity.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2021-2023 Google LLC
2+
* Copyright 2021-2025 Google LLC
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -30,7 +30,7 @@ import org.hl7.fhir.r4.model.ResourceType
3030
[
3131
Index(value = ["resourceType", "index_name", "index_value"]),
3232
// keep this index for faster foreign lookup
33-
Index(value = ["resourceUuid"]),
33+
Index(value = ["resourceUuid", "index_name", "index_value"]),
3434
],
3535
foreignKeys =
3636
[

engine/src/main/java/com/google/android/fhir/db/impl/entities/StringIndexEntity.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2021-2023 Google LLC
2+
* Copyright 2021-2025 Google LLC
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -30,7 +30,7 @@ import org.hl7.fhir.r4.model.ResourceType
3030
[
3131
Index(value = ["resourceType", "index_name", "index_value"]),
3232
// keep this index for faster foreign lookup
33-
Index(value = ["resourceUuid"]),
33+
Index(value = ["resourceUuid", "index_name", "index_value"]),
3434
],
3535
foreignKeys =
3636
[

0 commit comments

Comments
 (0)