All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.ru.alexey.event.threads.secure.SecureRealm.kt Maven / Gradle / Ivy

package ru.alexey.event.threads.secure

import io.realm.kotlin.Realm
import io.realm.kotlin.RealmConfiguration
import io.realm.kotlin.types.RealmObject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.*
import ru.alexey.event.threads.resources.ObservableResource
import kotlin.jvm.JvmInline
import kotlin.random.Random
import kotlin.reflect.KClass

@JvmInline
value class Seed(val seed: Long)

fun createConfig(vararg objects: KClass, seed: Seed, config: RealmConfiguration.Builder.() -> Unit) =
    RealmConfiguration.Builder(
        objects.toSet()
    ).apply(config)
        .encryptionKey(
            Random(seed.seed).nextBytes(64)
        )
        .build()


interface WrappedList {
    val list: List
}

fun  List.wrap() = object : WrappedList {
    override val list: List = this@wrap
}

class SecureRealm>(
    private val realm: Realm,
    private val clazz: KClass,
    private val source: StateFlow,
) : StateFlow by source, ObservableResource {
    override suspend fun update(block: (T) -> T) {
        realm.write {
            val old = query(clazz = clazz).find()
            val new = old.wrap().apply { block(this as T) }.list
            old.filter { it !in new }.forEach { delete(it) }
            new.filter { it !in old }.forEach { copyToRealm(it) }
        }
    }
}

inline fun > secureDatabase(
    realm: Realm,
    scope: CoroutineScope
): ObservableResource {
    val source: StateFlow = realm.query(clazz = R::class).find().asFlow().map {
        it.list.wrap() as T
    }.stateIn(
        scope = scope,
        initialValue = emptyList().wrap() as T,
        started = SharingStarted.Lazily
    )
    return SecureRealm(
        realm,
        clazz = R::class,
        source = source
    )
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy