Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow users to request referenced resources along with the searched via inline params. #1978

Merged
merged 46 commits into from
Aug 21, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
f33cc64
Inital changes to support inline resources via revInclude
aditya-07 Apr 13, 2023
54e4cbc
Merge branch 'master' into ak/revinclude
aditya-07 Apr 18, 2023
b0cd819
Merge branch 'master' into ak/revinclude
aditya-07 Apr 24, 2023
df863ac
Updated test and added doc
aditya-07 Apr 24, 2023
4239de9
Merge branch 'master' into ak/revinclude
aditya-07 Apr 27, 2023
e0f3c0f
RevInclude to return mapped response
aditya-07 Apr 28, 2023
1ccf108
Test code for forward include
aditya-07 May 4, 2023
d14e52a
Merge branch 'master' into ak/revinclude
aditya-07 May 5, 2023
543478c
Fixed include query
aditya-07 May 5, 2023
1818b80
Merge branch 'master' into ak/revinclude
aditya-07 Jun 6, 2023
724fb9d
Merge branch 'master' into ak/revinclude
aditya-07 Jun 28, 2023
379ed16
Unify search api to include include and revInclude functionality
aditya-07 Jun 29, 2023
c6f3682
Merge branch 'master' into ak/revinclude
aditya-07 Jun 29, 2023
75fac23
Workflow library: Incorporated changes related to FhirEngine.search
aditya-07 Jun 29, 2023
8ceb736
Merge branch 'ak/revinclude' of github.com:aditya-07/android-fhir int…
aditya-07 Jun 29, 2023
8756138
Merge branch 'master' into ak/revinclude
aditya-07 Jun 30, 2023
30d48a6
Merge branch 'master' into ak/revinclude
aditya-07 Jul 4, 2023
7acc7bb
Merge branch 'master' into ak/revinclude
aditya-07 Jul 5, 2023
4e50b9e
Merge branch 'master' into ak/revinclude
aditya-07 Jul 11, 2023
ced4b08
Merge branch 'master' into ak/revinclude
aditya-07 Jul 19, 2023
fe10fa0
Review comments: Changed the search result type to include the search…
aditya-07 Jul 20, 2023
5dcb352
Merge branch 'master' into ak/revinclude
aditya-07 Jul 20, 2023
7b55c7e
Updated docs
aditya-07 Jul 20, 2023
3db1d92
Added spotless toggle to skip indentation for specific code portions
aditya-07 Jul 20, 2023
e28c098
Merge branch 'master' into ak/revinclude
aditya-07 Jul 21, 2023
f74707e
Merge branch 'master' into ak/revinclude
aditya-07 Jul 24, 2023
35bf026
Added individual tests for include and revInclude
aditya-07 Jul 25, 2023
48df351
Merge branch 'master' into ak/revinclude
aditya-07 Jul 25, 2023
41d090c
Merge branch 'master' into ak/revinclude
aditya-07 Jul 26, 2023
b79bb28
Merge branch 'master' into ak/revinclude
aditya-07 Jul 26, 2023
a5ef271
Merge branch 'master' into ak/revinclude
aditya-07 Jul 27, 2023
286b58a
Merge branch 'master' into ak/revinclude
aditya-07 Jul 27, 2023
8efbdc2
Review Comments: Updated kdocs and refactored function name
aditya-07 Jul 27, 2023
af7768e
Merge branch 'master' into ak/revinclude
aditya-07 Jul 31, 2023
cfe459f
Review comments: refactored type of revInclude
aditya-07 Aug 1, 2023
31834c6
Fixed failing workflow compilation as workflow doesn't depends on eng…
aditya-07 Aug 1, 2023
9f169f3
Resolved compilation errors
aditya-07 Aug 1, 2023
fd22291
Merge branch 'master' into ak/revinclude
aditya-07 Aug 3, 2023
d5d0fe0
Merge branch 'master' into ak/revinclude
aditya-07 Aug 3, 2023
ed8a645
Merge branch 'master' into ak/revinclude
aditya-07 Aug 4, 2023
1228211
Merge branch 'master' into ak/revinclude
aditya-07 Aug 10, 2023
14ffa49
Merge branch 'master' into ak/revinclude
aditya-07 Aug 11, 2023
1dbe6be
Reverted the engine changes
aditya-07 Aug 11, 2023
530a5e1
Merge branch 'master' into ak/revinclude
aditya-07 Aug 11, 2023
8740ff4
Merge branch 'master' into ak/revinclude
omarismail94 Aug 21, 2023
00b1956
Merge branch 'master' into ak/revinclude
omarismail94 Aug 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Review comments: Changed the search result type to include the search…
… param as well.
  • Loading branch information
aditya-07 committed Jul 20, 2023
commit fe10fa0d79a692eddf4f530f3929fe821ebcacb8
Original file line number Diff line number Diff line change
Expand Up @@ -3244,7 +3244,7 @@ class DatabaseImplTest {
revInclude<Condition>(Condition.SUBJECT) {
filter(Condition.CODE, { value = of(diabetesCodeableConcept) })
filter(Condition.CODE, { value = of(migraineCodeableConcept) })
operations(Operation.OR)
operation = Operation.OR
}

revInclude<Encounter>(Encounter.SUBJECT) {
Expand All @@ -3266,7 +3266,7 @@ class DatabaseImplTest {
modifier = StringFilterModifier.STARTS_WITH
}
)
operations(Operation.AND)
operation = Operation.AND
}

include<Organization>(Patient.ORGANIZATION) {
Expand All @@ -3278,37 +3278,84 @@ class DatabaseImplTest {
}
)
filter(Practitioner.ACTIVE, { value = of(true) })
operations(Operation.AND)
operation = Operation.AND
}
}
.execute<Patient>(database)

assertThat(result[0].resource.logicalId).isEqualTo("pa-01")
assertThat(result[0].included!![ResourceType.Practitioner]!!.map { it.logicalId })
assertThat(
result[0]
.included!![ResourceType.Practitioner]!![Patient.GENERAL_PRACTITIONER.paramName]!!.map {
it.logicalId
}
)
.containsExactly("gp-01", "gp-02")
assertThat(result[0].included!![ResourceType.Organization]!!.map { it.logicalId })
assertThat(
result[0].included!![ResourceType.Organization]!![Patient.ORGANIZATION.paramName]!!.map {
it.logicalId
}
)
.containsExactly("org-01")
assertThat(result[0].revIncluded!![ResourceType.Condition]!!.map { it.logicalId })
assertThat(
result[0].revIncluded!![ResourceType.Condition]!![Condition.SUBJECT.paramName]!!.map {
it.logicalId
}
)
.containsExactly("con-01-pa-01", "con-03-pa-01")
assertThat(result[0].revIncluded!![ResourceType.Encounter]!!.map { it.logicalId })
assertThat(
result[0].revIncluded!![ResourceType.Encounter]!![Encounter.SUBJECT.paramName]!!.map {
it.logicalId
}
)
.containsExactly("en-01-pa-01", "en-02-pa-01")

assertThat(result[1].resource.logicalId).isEqualTo("pa-02")
assertThat(result[1].included!![ResourceType.Practitioner]!!.map { it.logicalId })
assertThat(
result[1]
.included!![ResourceType.Practitioner]!![Patient.GENERAL_PRACTITIONER.paramName]!!.map {
it.logicalId
}
)
.containsExactly("gp-01", "gp-02")
assertThat(result[1].included!![ResourceType.Organization]!!.map { it.logicalId })
assertThat(
result[1].included!![ResourceType.Organization]!![Patient.ORGANIZATION.paramName]!!.map {
it.logicalId
}
)
.containsExactly("org-02")
assertThat(result[1].revIncluded!![ResourceType.Condition]!!.map { it.logicalId })
assertThat(
result[1].revIncluded!![ResourceType.Condition]!![Condition.SUBJECT.paramName]!!.map {
it.logicalId
}
)
.containsExactly("con-01-pa-02", "con-03-pa-02")
assertThat(result[1].revIncluded!![ResourceType.Encounter]!!.map { it.logicalId })
assertThat(
result[1].revIncluded!![ResourceType.Encounter]!![Encounter.SUBJECT.paramName]!!.map {
it.logicalId
}
)
.containsExactly("en-01-pa-02", "en-02-pa-02")

assertThat(result[2].resource.logicalId).isEqualTo("pa-03")
assertThat(result[2].included!![ResourceType.Practitioner]!!.map { it.logicalId })
assertThat(
result[2]
.included!![ResourceType.Practitioner]!![Patient.GENERAL_PRACTITIONER.paramName]!!.map {
it.logicalId
}
)
.containsExactly("gp-01", "gp-02")
assertThat(result[2].revIncluded!![ResourceType.Condition]!!.map { it.logicalId })
assertThat(
result[2].revIncluded!![ResourceType.Condition]!![Condition.SUBJECT.paramName]!!.map {
it.logicalId
}
)
.containsExactly("con-01-pa-03", "con-03-pa-03")
assertThat(result[2].revIncluded!![ResourceType.Encounter]!!.map { it.logicalId })
assertThat(
result[2].revIncluded!![ResourceType.Encounter]!![Encounter.SUBJECT.paramName]!!.map {
it.logicalId
}
)
.containsExactly("en-01-pa-03", "en-02-pa-03")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,9 @@ suspend inline fun <reified R : Resource> FhirEngine.delete(id: String) {
delete(getResourceType(R::class.java), id)
}

typealias ReferencedResources = Map<ResourceType, List<Resource>>
typealias SearchParamName = String

typealias ReferencedResources = Map<ResourceType, Map<SearchParamName, List<Resource>>>

/** It contains the searched resource and referenced resources as per the search query. */
aditya-07 marked this conversation as resolved.
Show resolved Hide resolved
data class SearchResult<R : Resource>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,12 +189,15 @@ internal class DatabaseImpl(

override suspend fun searchReferencedResources(query: SearchQuery): List<IndexedIdAndResource> {
return db.withTransaction {
resourceDao.getResourcesRev(SimpleSQLiteQuery(query.query, query.args.toTypedArray())).map {
IndexedIdAndResource(
it.idOfBaseResourceOnWhichThisMatchedInc ?: it.idOfBaseResourceOnWhichThisMatchedRev!!,
iParser.parseResource(it.serializedResource) as Resource
)
}
resourceDao
.getReferencedResources(SimpleSQLiteQuery(query.query, query.args.toTypedArray()))
.map {
IndexedIdAndResource(
it.matchingIndex,
it.idOfBaseResourceOnWhichThisMatchedInc ?: it.idOfBaseResourceOnWhichThisMatchedRev!!,
iParser.parseResource(it.serializedResource) as Resource
)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ internal abstract class ResourceDao {
@RawQuery abstract suspend fun getResources(query: SupportSQLiteQuery): List<String>

@RawQuery
abstract suspend fun getResourcesRev(
abstract suspend fun getReferencedResources(
query: SupportSQLiteQuery
): List<IndexedIdAndSerializedResource>

Expand Down Expand Up @@ -286,13 +286,23 @@ internal abstract class ResourceDao {
}
}

/**
* Data class representing the value returned by [getReferencedResources]. The optional fields may
* or may-not contain values based on the search query.
*/
internal data class IndexedIdAndSerializedResource(
aditya-07 marked this conversation as resolved.
Show resolved Hide resolved
@ColumnInfo(name = "index_name") val matchingIndex: String,
@ColumnInfo(name = "index_value") val idOfBaseResourceOnWhichThisMatchedRev: String?,
@ColumnInfo(name = "resourceId") val idOfBaseResourceOnWhichThisMatchedInc: String?,
val serializedResource: String
)

/**
* Data class representing an included or revIncluded [Resource], index on which the match was done
* and the id of the base [Resource] for which this [Resource] has been included.
*/
internal data class IndexedIdAndResource(
aditya-07 marked this conversation as resolved.
Show resolved Hide resolved
val matchingIndex: String,
val idOfBaseResourceOnWhichThisMatched: String,
val resource: Resource
)
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,22 @@ import com.google.android.fhir.search.filter.StringParamFilterCriterion
import com.google.android.fhir.search.filter.TokenParamFilterCriterion
import com.google.android.fhir.search.filter.UriParamFilterCriterion

@DslMarker @Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE) annotation class ISearchDsl
@DslMarker @Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE) annotation class BaseSearchDsl

@ISearchDsl
interface ISearch {
/**
* Defines the basic functionality provided by the search including [filter], [sort] and logical
* [operation] on filters.
*/
@BaseSearchDsl
interface BaseSearch {
/** Logical operator between the filters. */
var operation: Operation

/** Count of the maximum expected search results. */
var count: Int?

/** Index from which the matching search results should be returned. */
var from: Int?

fun filter(
stringParameter: StringClientParam,
Expand Down Expand Up @@ -83,6 +95,4 @@ interface ISearch {
fun sort(parameter: NumberClientParam, order: Order)

fun sort(parameter: DateClientParam, order: Order)

fun operations(operation: Operation)
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import com.google.android.fhir.SearchResult
import com.google.android.fhir.UcumValue
import com.google.android.fhir.UnitConverter
import com.google.android.fhir.db.Database
import com.google.android.fhir.db.impl.dao.IndexedIdAndResource
import com.google.android.fhir.epochDay
import com.google.android.fhir.logicalId
import com.google.android.fhir.ucumUrl
Expand Down Expand Up @@ -68,16 +69,14 @@ internal suspend fun <R : Resource> Search.execute(database: Database): List<Sea
included =
includedResources
?.filter { it.idOfBaseResourceOnWhichThisMatched == baseResource.logicalId }
?.map { it.resource }
?.groupBy { it.resourceType },
?.toReferencedResources(),
revIncluded =
revIncludedResources
?.filter {
it.idOfBaseResourceOnWhichThisMatched ==
"${baseResource.fhirType()}/${baseResource.logicalId}"
}
?.map { it.resource }
?.groupBy { it.resourceType }
?.toReferencedResources()
)
}
}
Expand Down Expand Up @@ -133,7 +132,7 @@ private fun Search.getRevIncludeQuery(includeIds: List<String>): SearchQuery {
return SearchQuery(
query =
"""
SELECT a.index_value, b.serializedResource
SELECT a.index_name, a.index_value, b.serializedResource
FROM ReferenceIndexEntity a
JOIN ResourceEntity b
ON a.resourceUuid = b.resourceUuid
Expand All @@ -144,6 +143,10 @@ private fun Search.getRevIncludeQuery(includeIds: List<String>): SearchQuery {
)
}

private fun List<IndexedIdAndResource>.toReferencedResources() =
groupBy { it.resource.resourceType }
.mapValues { it.value.groupBy { it.matchingIndex }.mapValues { it.value.map { it.resource } } }

private fun Search.getIncludeQuery(includeIds: List<String>): SearchQuery {
var matchQuery = ""
val args = mutableListOf<Any>(type.name)
Expand Down Expand Up @@ -187,7 +190,7 @@ private fun Search.getIncludeQuery(includeIds: List<String>): SearchQuery {
return SearchQuery(
query =
"""
SELECT a.resourceId, c.serializedResource from ResourceEntity a
SELECT b.index_name, a.resourceId, c.serializedResource from ResourceEntity a
JOIN ReferenceIndexEntity b
On a.resourceUuid = b.resourceUuid
AND a.resourceType = ?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ internal data class NestedContext(val parentType: ResourceType, val param: IPara
*/
inline fun <reified R : Resource> Search.has(
referenceParam: ReferenceClientParam,
init: @ISearchDsl ISearch.() -> Unit
init: @BaseSearchDsl BaseSearch.() -> Unit
) {
nestedSearches.add(
NestedSearch(referenceParam, Search(type = R::class.java.newInstance().resourceType)).apply {
Expand Down Expand Up @@ -71,7 +71,7 @@ inline fun <reified R : Resource> Search.has(
*/
inline fun <reified R : Resource> Search.include(
referenceParam: ReferenceClientParam,
init: @ISearchDsl ISearch.() -> Unit
init: @BaseSearchDsl BaseSearch.() -> Unit = {}
) {
forwardIncludes.add(
NestedSearch(referenceParam, Search(type = R::class.java.newInstance().resourceType)).apply {
Expand Down Expand Up @@ -103,7 +103,7 @@ inline fun <reified R : Resource> Search.include(
fun Search.include(
resourceType: ResourceType,
referenceParam: ReferenceClientParam,
init: @ISearchDsl ISearch.() -> Unit = {}
init: @BaseSearchDsl BaseSearch.() -> Unit = {}
) {
forwardIncludes.add(
NestedSearch(referenceParam, Search(type = resourceType)).apply { search.init() }
Expand Down Expand Up @@ -133,7 +133,7 @@ fun Search.include(
*/
inline fun <reified R : Resource> Search.revInclude(
referenceParam: ReferenceClientParam,
init: @ISearchDsl ISearch.() -> Unit = {}
init: @BaseSearchDsl BaseSearch.() -> Unit = {}
) {

revIncludes.add(
Expand Down Expand Up @@ -167,7 +167,7 @@ inline fun <reified R : Resource> Search.revInclude(
fun Search.revInclude(
resourceType: ResourceType,
referenceParam: ReferenceClientParam,
init: @ISearchDsl ISearch.() -> Unit = {}
init: @BaseSearchDsl BaseSearch.() -> Unit = {}
) {
revIncludes.add(NestedSearch(referenceParam, Search(type = resourceType)).apply { search.init() })
}
Expand All @@ -189,7 +189,7 @@ fun Search.revInclude(
fun Search.has(
resourceType: ResourceType,
referenceParam: ReferenceClientParam,
init: @ISearchDsl ISearch.() -> Unit
init: @BaseSearchDsl BaseSearch.() -> Unit
) {
nestedSearches.add(
NestedSearch(referenceParam, Search(type = resourceType)).apply { search.init() }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@ import com.google.android.fhir.search.filter.UriParamFilterCriterion
import org.hl7.fhir.r4.model.ResourceType

@SearchDslMarker
class Search(val type: ResourceType, var count: Int? = null, var from: Int? = null) : ISearch {
class Search(
val type: ResourceType,
override var count: Int? = null,
override var from: Int? = null
) : BaseSearch {
internal val stringFilterCriteria = mutableListOf<StringParamFilterCriteria>()
internal val dateTimeFilterCriteria = mutableListOf<DateClientParamFilterCriteria>()
internal val numberFilterCriteria = mutableListOf<NumberParamFilterCriteria>()
Expand All @@ -55,7 +59,7 @@ class Search(val type: ResourceType, var count: Int? = null, var from: Int? = nu
@PublishedApi internal var revIncludes = mutableListOf<NestedSearch>()
@PublishedApi internal var forwardIncludes = mutableListOf<NestedSearch>()

var operation = Operation.AND
override var operation = Operation.AND

override fun filter(
stringParameter: StringClientParam,
Expand Down Expand Up @@ -143,10 +147,6 @@ class Search(val type: ResourceType, var count: Int? = null, var from: Int? = nu
sort = parameter
this.order = order
}

override fun operations(operation: Operation) {
this.operation = operation
}
}

enum class Order {
Expand Down
Loading
Loading