Last active
February 15, 2024 21:27
-
-
Save datikaa/3b98aea99a8870f2b5bdf5b9a611bd1b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import io.realm.* | |
import io.realm.kotlin.toFlow | |
import kotlinx.coroutines.Dispatchers | |
import kotlinx.coroutines.flow.* | |
/** | |
* Returns a [Flow] with all of the results of the [RealmQuery], while drops every offer that is not | |
* loaded already. This makes it easy to be used with [kotlinx.coroutines.flow.first]. Be aware that | |
* the [Realm] object must be on a thread with a looper. | |
* | |
* | |
* Example: | |
* ``` | |
* realmInstance.where<Foo>() | |
* .flowAll() | |
* .map { results -> doExpensiveWork(results) } | |
* .flowOn(Dispatchers.IO) | |
* .onEach { flowResults -> | |
* // ... | |
* }.launchIn(Dispatchers.Main) | |
* ``` | |
* | |
* | |
* @param[detach] If true, [Realm.copyFromRealm] will be called on every element. Defaults to true. | |
*/ | |
fun <T : RealmModel> RealmQuery<T>.flowAll(detach: Boolean = true): Flow<List<T>> = findAllAsync() | |
.toFlow() | |
.flowOn(Dispatchers.Main) | |
.dropWhile { !it.isLoaded } | |
.map { if (detach) it.copyFromRealm() else it } | |
/** | |
* Same as [flowAll] but limited to only one object, which is nullable. | |
* | |
* Example: | |
* ``` | |
* val foo: List<Foo> = realmInstance.where<Foo>() | |
* .flowAll() | |
* .first() | |
* ``` | |
* | |
* @param[detach] If true, [Realm.copyFromRealm] will be called on every element. Defaults to true. | |
*/ | |
fun <T : RealmModel> RealmQuery<T>.flowFirst(detach: Boolean = true): Flow<T?> = limit(1) | |
.flowAll(detach) | |
.map { it.firstOrNull() } | |
/** | |
* Creates a detached copy from this [RealmResults]. | |
*/ | |
fun <T : RealmModel> RealmResults<T>.copyFromRealm() : List<T> { | |
return Realm.getInstance(realm.configuration).use { | |
it.copyFromRealm(this) | |
} | |
} | |
/** | |
* Creates a detached copy from this [RealmModel] | |
*/ | |
fun <T : RealmModel> T.copyFromRealm(): T = Realm.getDefaultInstance().use { | |
it.copyFromRealm(this) | |
} | |
/** | |
* Get's a default [Realm] instance on [Dispatchers.Main], and passes it inside the lambda where | |
* you need to return with a [Flow]. | |
* | |
* Example: | |
* ``` | |
* val foo: Flow<List<Foo>> = autoCloseRealmFlow { realm -> | |
* realm.where<Foo>().flowAll() | |
* } | |
* ``` | |
* @param[context] The [CoroutineContext] where the [Realm] instance will be initialized | |
*/ | |
fun <T> autoCloseRealmFlow(context: CoroutineContext = Dispatchers.Main, query: (Realm) -> Flow<T>): Flow<T> = flow { | |
emitAll(Realm.getDefaultInstance().use(query)) | |
}.flowOn(context) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment