Skip to content

Commit

Permalink
Initial expansion of external function documentation (#2455)
Browse files Browse the repository at this point in the history
* Revise kdocs for some important FHIR Engine interfaces; largely generated.

* spotless

* Address review comments
  • Loading branch information
williamito committed Mar 8, 2024
1 parent 7862d25 commit ee810d6
Show file tree
Hide file tree
Showing 5 changed files with 295 additions and 98 deletions.
175 changes: 129 additions & 46 deletions engine/src/main/java/com/google/android/fhir/FhirEngine.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,114 +27,193 @@ import kotlinx.coroutines.flow.Flow
import org.hl7.fhir.r4.model.Resource
import org.hl7.fhir.r4.model.ResourceType

/** The FHIR Engine interface that handles the local storage of FHIR resources. */
/**
* Provides an interface for managing FHIR resources in local storage.
*
* The FHIR Engine allows you to create, read, update, and delete (CRUD) FHIR resources, as well as
* perform searches and synchronize data with a remote FHIR server. The FHIR resources are
* represented using HAPI FHIR Structures [Resource] and [ResourceType].
*
* To use a FHIR Engine instance, first call [FhirEngineProvider.init] with a
* [FhirEngineConfiguration]. This must be done only once; we recommend doing this in the
* `onCreate()` function of your `Application` class.
*
* ```
* class MyApplication : Application() {
* override fun onCreate() {
* super.onCreate()
*
* FhirEngineProvider.init(
* FhirEngineConfiguration(
* enableEncryptionIfSupported = true,
* RECREATE_AT_OPEN
* )
* )
* }
* }
* ```
*
* To get a `FhirEngine` to interact with, use [FhirEngineProvider.getInstance]:
* ```
* val fhirEngine = FhirEngineProvider.getInstance(this)
* ```
*/
interface FhirEngine {
/**
* Creates one or more FHIR [resource]s in the local storage.
* Creates one or more FHIR [Resource]s in the local storage. FHIR Engine requires all stored
* resources to have a logical [Resource.id]. If the `id` is specified in the resource passed to
* [create], the resource created in `FhirEngine` will have the same `id`. If no `id` is
* specified, `FhirEngine` will generate a UUID as that resource's `id` and include it in the
* returned list of IDs.
*
* @return the logical IDs of the newly created resources.
* @param resource The FHIR resources to create.
* @return A list of logical IDs of the newly created resources.
*/
suspend fun create(vararg resource: Resource): List<String>

/** Loads a FHIR resource given the class and the logical ID. */
/**
* Loads a FHIR resource given its [ResourceType] and logical ID.
*
* @param type The type of the resource to load.
* @param id The logical ID of the resource.
* @return The requested FHIR resource.
* @throws ResourceNotFoundException if the resource is not found.
*/
@Throws(ResourceNotFoundException::class)
suspend fun get(type: ResourceType, id: String): Resource

/** Updates a FHIR [resource] in the local storage. */
/**
* Updates one or more FHIR [Resource]s in the local storage.
*
* @param resource The FHIR resources to update.
*/
suspend fun update(vararg resource: Resource)

/** Removes a FHIR resource given the class and the logical ID. */
/**
* Removes a FHIR resource given its [ResourceType] and logical ID.
*
* @param type The type of the resource to delete.
* @param id The logical ID of the resource.
*/
suspend fun delete(type: ResourceType, id: String)

/**
* Searches the database and returns a list resources according to the [search] specifications.
* Searches the database and returns a list of resources matching the [Search] specifications.
*
* Example:
* ```
* fhirEngine.search<Patient> {
* filter(Patient.GIVEN, {
* value = "Kiran"
* modifier = StringFilterModifier.MATCHES_EXACTLY
* })
* }
* ```
*
* @param search The search criteria to apply.
* @return A list of [SearchResult] objects containing the matching resources and any included
* references.
*/
suspend fun <R : Resource> search(search: Search): List<SearchResult<R>>

/**
* Synchronizes the upload results in the database.
* Synchronizes upload results with the database.
*
* The [upload] function may initiate multiple server calls. Each call's result can then be used
* to emit [UploadSyncResult]. The caller should collect these results using [Flow.collect].
* This function initiates multiple server calls to upload local changes. The results of each call
* are emitted as [UploadRequestResult] objects, which can be collected using a [Flow].
*
* @param localChangesFetchMode Specifies the mode to fetch local changes.
* @param upload A suspend function that takes a list of [LocalChange] and returns an
* [UploadSyncResult].
* @return A [Flow] that emits the progress of the synchronization process.
* @param localChangesFetchMode Specifies how to fetch local changes for upload.
* @param upload A suspending function that takes a list of [LocalChange] objects and returns a
* [Flow] of [UploadRequestResult] objects.
* @return A [Flow] that emits the progress of the synchronization process as [SyncUploadProgress]
* objects.
*/
@Deprecated("To be deprecated.")
suspend fun syncUpload(
localChangesFetchMode: LocalChangesFetchMode,
upload: (suspend (List<LocalChange>) -> Flow<UploadRequestResult>),
): Flow<SyncUploadProgress>

/**
* Synchronizes the [download] result in the database. The database will be updated to reflect the
* result of the [download] operation.
* Synchronizes the download results with the database.
*
* This function updates the local database to reflect the results of the download operation,
* resolving any conflicts using the provided [ConflictResolver].
*
* @param conflictResolver The [ConflictResolver] to use for resolving conflicts between local and
* remote data.
* @param download A suspending function that returns a [Flow] of lists of [Resource] objects
* representing the downloaded data.
*/
@Deprecated("To be deprecated.")
suspend fun syncDownload(
conflictResolver: ConflictResolver,
download: suspend () -> Flow<List<Resource>>,
)

/**
* Returns the total count of entities available for given search.
* Returns the total count of entities available for the given [Search].
*
* @param search
* @param search The search criteria to apply.
* @return The total number of matching resources.
*/
suspend fun count(search: Search): Long

/** Returns the timestamp when data was last synchronized. */
/**
* Returns the timestamp when data was last synchronized, or `null` if no synchronization has
* occurred yet.
*/
suspend fun getLastSyncTimeStamp(): OffsetDateTime?

/**
* Clears all database tables without resetting the auto-increment value generated by
* PrimaryKey.autoGenerate.
*
* WARNING: This will clear the database and it's not recoverable.
* WARNING: This will permanently delete all data in the database.
*/
suspend fun clearDatabase()

/**
* Retrieves a list of [LocalChange]s for [Resource] with given type and id, which can be used to
* purge resource from database. If there is no local change for given [resourceType] and
* [Resource.id], return an empty list.
* Retrieves a list of [LocalChange]s for the [Resource] with the given type and ID. This can be
* used to select resources to purge from the database.
*
* @param type The [ResourceType]
* @param id The resource id [Resource.id]
* @return [List]<[LocalChange]> A list of local changes for given [resourceType] and
* [Resource.id] . If there is no local change for given [resourceType] and [Resource.id],
* return an empty list.
* @param type The [ResourceType] of the resource.
* @param id The resource ID.
* @return A list of [LocalChange] objects representing the local changes made to the resource, or
* an empty list if no changes.
*/
suspend fun getLocalChanges(type: ResourceType, id: String): List<LocalChange>

/**
* Purges a resource from the database based on resource type and id without any deletion of data
* from the server.
* Purges a resource from the database without deleting data from the server.
*
* @param type The [ResourceType]
* @param id The resource id [Resource.id]
* @param isLocalPurge default value is false here resource will not be deleted from
* LocalChangeEntity table but it will throw IllegalStateException("Resource has local changes
* either sync with server or FORCE_PURGE required") if local change exists. If true this API
* will delete resource entry from LocalChangeEntity table.
* @param type The [ResourceType] of the resource.
* @param id The resource ID.
* @param forcePurge If `true`, the resource will be purged even if it has local changes.
* Otherwise, an [IllegalStateException] will be thrown if local changes exist. Defaults to
* `false`.
*/
suspend fun purge(type: ResourceType, id: String, forcePurge: Boolean = false)
}

/**
* Returns a FHIR resource of type [R] with [id] from the local storage.
* Retrieves a FHIR resource of type [R] with the given [id] from the local storage.
*
* @param <R> The resource type which should be a subtype of [Resource].
* @throws ResourceNotFoundException if the resource is not found
* @param R The type of the FHIR resource to retrieve.
* @param id The logical ID of the resource to retrieve.
* @return The requested FHIR resource.
* @throws ResourceNotFoundException if the resource is not found.
*/
@Throws(ResourceNotFoundException::class)
suspend inline fun <reified R : Resource> FhirEngine.get(id: String): R {
return get(getResourceType(R::class.java), id) as R
}

/**
* Deletes a FHIR resource of type [R] with [id] from the local storage.
* Deletes a FHIR resource of type [R] with the given [id] from the local storage.
*
* @param <R> The resource type which should be a subtype of [Resource].
* @param R The type of the FHIR resource to delete.
* @param id The logical ID of the resource to delete.
*/
suspend inline fun <reified R : Resource> FhirEngine.delete(id: String) {
delete(getResourceType(R::class.java), id)
Expand All @@ -143,14 +222,18 @@ suspend inline fun <reified R : Resource> FhirEngine.delete(id: String) {
typealias SearchParamName = String

/**
* Contains a FHIR resource that satisfies the search criteria in the query together with any
* referenced resources as specified in the query.
* Represents the result of a FHIR search query, containing a matching resource and any referenced
* resources as specified in the query.
*
* @param R The type of the main FHIR resource in the search result.
* @property resource The FHIR resource that matches the search criteria.
* @property included A map of included resources, keyed by the search parameter name used for
* inclusion, as per the [Search.forwardIncludes] criteria in the query.
* @property revIncluded A map of reverse included resources, keyed by the resource type and search
* parameter name used for inclusion, as per the [Search.revIncludes] criteria in the query.
*/
data class SearchResult<R : Resource>(
/** Matching resource as per the query. */
val resource: R,
/** Matching referenced resources as per the [Search.include] criteria in the query. */
val included: Map<SearchParamName, List<Resource>>?,
/** Matching referenced resources as per the [Search.revInclude] criteria in the query. */
val revIncluded: Map<Pair<ResourceType, SearchParamName>, List<Resource>>?,
)
Loading

0 comments on commit ee810d6

Please sign in to comment.