Skip to content

Commit

Permalink
Refractor: StringSearchModifier.kt
Browse files Browse the repository at this point in the history
Improve tests
Improve Formatting
  • Loading branch information
epicadk committed May 14, 2021
1 parent f0e1cf8 commit 1f8c390
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 113 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import com.google.android.fhir.logicalId
import com.google.android.fhir.resource.TestingUtils
import com.google.android.fhir.search.Order
import com.google.android.fhir.search.Search
import com.google.android.fhir.search.StringFilterModifier
import com.google.android.fhir.search.getQuery
import com.google.android.fhir.search.params.StringSearchModifier
import com.google.android.fhir.sync.FhirDataSource
import com.google.common.truth.Truth.assertThat
import java.math.BigDecimal
Expand Down Expand Up @@ -373,107 +373,138 @@ class DatabaseImplTest {
}

@Test
fun search_String_Exact() {
val patient1 =
fun search_String_default() {
val patient =
Patient().apply {
id = "test_1"
addName(HumanName().addGiven("Eve"))
addName(HumanName().addGiven("Evelyn"))
}
val patient2 =
val res = runBlocking {
database.insert(patient)
database.search<Patient>(
Search(ResourceType.Patient).apply { filter(Patient.GIVEN) { value = "eve" } }.getQuery()
)
}
assertThat(res).hasSize(1)
assertThat(
res.all { patient -> patient.nameFirstRep.given.any { it.toString().startsWith("Eve") } }
)
.isTrue()
}

@Test
fun search_String_default_no_match() {
val patient =
Patient().apply {
id = "test_2"
addName(HumanName().addGiven("EVE"))
id = "test_1"
addName(HumanName().addGiven("Severine"))
}
val patient3 =
val res = runBlocking {
database.insert(patient)
database.search<Patient>(
Search(ResourceType.Patient).apply { filter(Patient.GIVEN) { value = "eve" } }.getQuery()
)
}
assertThat(res).hasSize(0)
}

@Test
fun search_String_exact() {
val patient =
Patient().apply {
id = "test_3"
addName(HumanName().addGiven("eve"))
id = "test_1"
addName(HumanName().addGiven("Eve"))
}
val res = runBlocking {
database.insert(patient1, patient2, patient3)
database.insert(patient)
database.search<Patient>(
Search(ResourceType.Patient)
.apply {
filter(Patient.GIVEN) {
value = "Eve"
modifier = StringSearchModifier.EXACT
modifier = StringFilterModifier.MATCHES_EXACTLY
}
}
.getQuery()
)
}
assertThat(res).hasSize(1)
assertThat(res[0].id).isEqualTo("Patient/${patient1.id}")
assertThat(res[0].nameFirstRep.given.any { it.toString() == "Eve" }).isTrue()
}

@Test
fun search_String_Contains() {
val patient1 =
fun search_String_exact_no_match() {
val patient =
Patient().apply {
id = "test_1"
addName(HumanName().addGiven("Severine"))
}
val patient2 =
Patient().apply {
id = "test_2"
addName(HumanName().addGiven("Evelyn"))
addName(HumanName().addGiven("EVE"))
}
val patient3 =
val res = runBlocking {
database.insert(patient)
database.search<Patient>(
Search(ResourceType.Patient)
.apply {
filter(Patient.GIVEN) {
value = "Eve"
modifier = StringFilterModifier.MATCHES_EXACTLY
}
}
.getQuery()
)
}
assertThat(res).hasSize(0)
}

@Test
fun search_String_contains() {
val patient =
Patient().apply {
id = "test_3"
addName(HumanName().addGiven("Eve"))
id = "test_1"
addName(HumanName().addGiven("Severine"))
}

val res = runBlocking {
database.insert(patient1, patient2, patient3)
database.insert(patient)
database.search<Patient>(
Search(ResourceType.Patient)
.apply {
filter(Patient.GIVEN) {
value = "eve"
modifier = StringSearchModifier.CONTAINS
value = "Eve"
modifier = StringFilterModifier.CONTAINS
}
}
.getQuery()
)
}
assertThat(res).hasSize(3)
assertThat(res).hasSize(1)
assertThat(
res.all { patient ->
patient.nameFirstRep.given.any { it.toString().toLowerCase().contains("eve") }
res.all { result ->
result.nameFirstRep.given.any { it.toString().toLowerCase().contains("eve") }
}
)
.isTrue()
}

@Test
fun search_String_Default() {
val patient1 =
fun search_String_contains_no_match() {
val patient =
Patient().apply {
id = "test_1"
addName(HumanName().addGiven("Doe").addGiven("Eve"))
}
val patient2 =
Patient().apply {
id = "test_2"
addName(HumanName().addGiven("Evelyn"))
}
val patient3 =
Patient().apply {
id = "test_3"
addName(HumanName().addGiven("Severine"))
addName(HumanName().addGiven("John"))
}
val res = runBlocking {
database.insert(patient1, patient2, patient3)
database.insert(patient)
database.search<Patient>(
Search(ResourceType.Patient).apply { filter(Patient.GIVEN) { value = "eve" } }.getQuery()
Search(ResourceType.Patient)
.apply {
filter(Patient.GIVEN) {
value = "eve"
modifier = StringFilterModifier.CONTAINS
}
}
.getQuery()
)
}
assertThat(res).hasSize(2)
assertThat(
res.all { patient -> patient.nameFirstRep.given.any { it.toString().startsWith("Eve") } }
)
.isTrue()
assertThat(res).hasSize(0)
}

private companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package com.google.android.fhir.search
import ca.uhn.fhir.rest.gclient.NumberClientParam
import ca.uhn.fhir.rest.gclient.StringClientParam
import com.google.android.fhir.db.Database
import com.google.android.fhir.search.params.StringSearchModifier
import org.hl7.fhir.r4.model.Resource
import org.hl7.fhir.r4.model.ResourceType

Expand Down Expand Up @@ -94,9 +93,9 @@ fun StringFilter.query(type: ResourceType): SearchQuery {

val condition =
when (modifier) {
StringSearchModifier.CONTAINS -> "LIKE '%' || ? || '%' COLLATE NOCASE"
StringSearchModifier.EXACT -> "= ?"
else -> "LIKE ? || '%' COLLATE NOCASE"
StringFilterModifier.STARTS_WITH -> "LIKE ? || '%' COLLATE NOCASE"
StringFilterModifier.MATCHES_EXACTLY -> "= ?"
StringFilterModifier.CONTAINS -> "LIKE '%' || ? || '%' COLLATE NOCASE"
}
return SearchQuery(
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import ca.uhn.fhir.rest.gclient.IParam
import ca.uhn.fhir.rest.gclient.NumberClientParam
import ca.uhn.fhir.rest.gclient.ReferenceClientParam
import ca.uhn.fhir.rest.gclient.StringClientParam
import com.google.android.fhir.search.params.StringSearchModifier
import org.hl7.fhir.r4.model.ResourceType

@SearchDslMarker
Expand Down Expand Up @@ -56,7 +55,7 @@ data class Search(val type: ResourceType, var count: Int? = null, var from: Int?
@SearchDslMarker
data class StringFilter(
val parameter: StringClientParam,
var modifier: StringSearchModifier? = null,
var modifier: StringFilterModifier = StringFilterModifier.STARTS_WITH,
var value: String? = null
)

Expand All @@ -67,3 +66,9 @@ enum class Order {
ASCENDING,
DESCENDING
}

enum class StringFilterModifier {
STARTS_WITH,
MATCHES_EXACTLY,
CONTAINS
}

This file was deleted.

64 changes: 32 additions & 32 deletions engine/src/test/java/com/google/android/fhir/search/SearchTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package com.google.android.fhir.search

import android.os.Build
import com.google.android.fhir.search.params.StringSearchModifier
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.runBlocking
import org.hl7.fhir.r4.model.Patient
Expand Down Expand Up @@ -46,28 +45,24 @@ class SearchTest {
)
assertThat(query.args).isEqualTo(listOf(ResourceType.Patient.name))
}

@Test
fun search_string_contains() {
fun search_string_default() {
val query =
Search(ResourceType.Patient)
.apply {
filter(Patient.ADDRESS) {
modifier = StringSearchModifier.CONTAINS
value = "someValue"
}
}
.apply { filter(Patient.ADDRESS) { value = "someValue" } }
.getQuery()

assertThat(query.query)
.isEqualTo(
"""
SELECT a.serializedResource
FROM ResourceEntity a
WHERE a.resourceType = ?
AND a.resourceId IN (
SELECT resourceId FROM StringIndexEntity
WHERE resourceType = ? AND index_name = ? AND index_value LIKE '%' || ? || '%' COLLATE NOCASE
)
SELECT a.serializedResource
FROM ResourceEntity a
WHERE a.resourceType = ?
AND a.resourceId IN (
SELECT resourceId FROM StringIndexEntity
WHERE resourceType = ? AND index_name = ? AND index_value LIKE ? || '%' COLLATE NOCASE
)
""".trimIndent()
)
assertThat(query.args)
Expand All @@ -85,7 +80,7 @@ class SearchTest {
Search(ResourceType.Patient)
.apply {
filter(Patient.ADDRESS) {
modifier = StringSearchModifier.EXACT
modifier = StringFilterModifier.MATCHES_EXACTLY
value = "someValue"
}
}
Expand All @@ -94,13 +89,13 @@ class SearchTest {
assertThat(query.query)
.isEqualTo(
"""
SELECT a.serializedResource
FROM ResourceEntity a
WHERE a.resourceType = ?
AND a.resourceId IN (
SELECT resourceId FROM StringIndexEntity
WHERE resourceType = ? AND index_name = ? AND index_value = ?
)
SELECT a.serializedResource
FROM ResourceEntity a
WHERE a.resourceType = ?
AND a.resourceId IN (
SELECT resourceId FROM StringIndexEntity
WHERE resourceType = ? AND index_name = ? AND index_value = ?
)
""".trimIndent()
)
assertThat(query.args)
Expand All @@ -113,22 +108,27 @@ class SearchTest {
}

@Test
fun search_string_default() {
fun search_string_contains() {
val query =
Search(ResourceType.Patient)
.apply { filter(Patient.ADDRESS) { value = "someValue" } }
.apply {
filter(Patient.ADDRESS) {
modifier = StringFilterModifier.CONTAINS
value = "someValue"
}
}
.getQuery()

assertThat(query.query)
.isEqualTo(
"""
SELECT a.serializedResource
FROM ResourceEntity a
WHERE a.resourceType = ?
AND a.resourceId IN (
SELECT resourceId FROM StringIndexEntity
WHERE resourceType = ? AND index_name = ? AND index_value LIKE ? || '%' COLLATE NOCASE
)
SELECT a.serializedResource
FROM ResourceEntity a
WHERE a.resourceType = ?
AND a.resourceId IN (
SELECT resourceId FROM StringIndexEntity
WHERE resourceType = ? AND index_name = ? AND index_value LIKE '%' || ? || '%' COLLATE NOCASE
)
""".trimIndent()
)
assertThat(query.args)
Expand Down
Loading

0 comments on commit 1f8c390

Please sign in to comment.