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

commonMain.dev.inmo.micro_utils.repos.KeyValuesRepo.kt Maven / Gradle / Ivy

There is a newer version: 0.22.2
Show newest version
package dev.inmo.micro_utils.repos

import dev.inmo.micro_utils.common.diff
import dev.inmo.micro_utils.pagination.*
import dev.inmo.micro_utils.pagination.utils.doForAllWithNextPaging
import dev.inmo.micro_utils.pagination.utils.getAllWithNextPaging
import kotlinx.coroutines.flow.Flow

interface ReadKeyValuesRepo : Repo {
    suspend fun get(k: Key, pagination: Pagination, reversed: Boolean = false): PaginationResult
    suspend fun keys(pagination: Pagination, reversed: Boolean = false): PaginationResult
    suspend fun keys(v: Value, pagination: Pagination, reversed: Boolean = false): PaginationResult
    suspend fun contains(k: Key): Boolean
    suspend fun contains(k: Key, v: Value): Boolean
    suspend fun count(k: Key): Long
    suspend fun count(): Long

    suspend fun getAll(k: Key, reversed: Boolean = false): List {
        val results = getAllWithNextPaging { get(k, it) }
        return if (reversed) {
            results.reversed()
        } else {
            results
        }
    }

    /**
     * WARNING!!! THIS METHOD PROBABLY IS NOT EFFICIENT, USE WITH CAUTION
     */
    suspend fun getAll(reverseLists: Boolean = false): Map> = mutableMapOf>().also { map ->
        doWithPagination {
            keys(it).also { paginationResult ->
                paginationResult.results.forEach { k ->
                    map[k] = getAll(k, reverseLists)
                }
            }.nextPageIfNotEmpty()
        }
    }
}
typealias ReadOneToManyKeyValueRepo = ReadKeyValuesRepo

interface WriteKeyValuesRepo : Repo {
    val onNewValue: Flow>
    val onValueRemoved: Flow>
    val onDataCleared: Flow

    suspend fun add(toAdd: Map>)

    /**
     * Removes [Value]s by passed [Key]s without full clear of all data by [Key]
     */
    suspend fun remove(toRemove: Map>)

    /**
     * Removes [v] without full clear of all data by [Key]s with [v]
     */
    suspend fun removeWithValue(v: Value)

    /**
     * Fully clear all data by [k]
     */
    suspend fun clear(k: Key)
    /**
     * Clear [v] **with** full clear of all data by [Key]s with [v]
     */
    suspend fun clearWithValue(v: Value)

    suspend fun set(toSet: Map>) {
        toSet.keys.forEach { key -> clear(key) }
        add(toSet)
    }
}
typealias WriteOneToManyKeyValueRepo = WriteKeyValuesRepo

suspend inline fun > REPO.add(
    keysAndValues: List>>
) = add(keysAndValues.toMap())

suspend inline fun > REPO.add(
    vararg keysAndValues: Pair>
) = add(keysAndValues.toMap())

suspend inline fun  WriteKeyValuesRepo.add(
    k: Key, v: List
) = add(mapOf(k to v))

suspend inline fun  WriteKeyValuesRepo.add(
    k: Key, vararg v: Value
) = add(k, v.toList())

suspend inline fun > REPO.set(
    keysAndValues: List>>
) = set(keysAndValues.toMap())

suspend inline fun > REPO.set(
    vararg keysAndValues: Pair>
) = set(keysAndValues.toMap())

suspend inline fun  WriteKeyValuesRepo.set(
    k: Key, v: List
) = set(mapOf(k to v))

suspend inline fun  WriteKeyValuesRepo.set(
    k: Key, vararg v: Value
) = set(k, v.toList())

interface KeyValuesRepo : ReadKeyValuesRepo, WriteKeyValuesRepo {
    override suspend fun clearWithValue(v: Value) {
        doWithPagination {
            val keysResult = keys(v, it)

            if (keysResult.results.isNotEmpty()) {
                remove(keysResult.results.map { it to listOf(v) })
            }

            keysResult.currentPageIfNotEmpty()
        }
    }
    suspend override fun removeWithValue(v: Value) {
        val toRemove = mutableMapOf>()

        doForAllWithNextPaging {
            keys(it).also {
                it.results.forEach {
                    if (contains(it, v)) {
                        toRemove[it] = listOf(v)
                    }
                }
            }
        }

        remove(toRemove)
    }

    override suspend fun set(toSet: Map>) {
        toSet.forEach { (k, v) ->
            val diff = getAll(k).diff(v)
            remove(k, diff.removed.map { it.value })
            add(k, diff.added.map { it.value })
        }
    }
}
typealias OneToManyKeyValueRepo = KeyValuesRepo

class DelegateBasedKeyValuesRepo(
    readDelegate: ReadKeyValuesRepo,
    writeDelegate: WriteKeyValuesRepo
) : KeyValuesRepo,
    ReadKeyValuesRepo by readDelegate,
    WriteKeyValuesRepo by writeDelegate

suspend inline fun  WriteKeyValuesRepo.remove(
    keysAndValues: List>>
) = remove(keysAndValues.toMap())

suspend inline fun  WriteKeyValuesRepo.remove(
    vararg keysAndValues: Pair>
) = remove(keysAndValues.toMap())

suspend inline fun  WriteKeyValuesRepo.remove(
    k: Key,
    v: List
) = remove(mapOf(k to v))

suspend inline fun  WriteKeyValuesRepo.remove(
    k: Key,
    vararg v: Value
) = remove(k, v.toList())




© 2015 - 2024 Weber Informatics LLC | Privacy Policy