MicroUtils/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/KeyValuesRepo.kt

169 lines
5.5 KiB
Kotlin
Raw Normal View History

2020-09-20 02:17:11 +00:00
package dev.inmo.micro_utils.repos
2024-02-15 09:36:32 +00:00
import dev.inmo.micro_utils.common.diff
import dev.inmo.micro_utils.pagination.*
2023-04-25 13:14:38 +00:00
import dev.inmo.micro_utils.pagination.utils.doForAllWithNextPaging
2021-03-29 13:48:37 +00:00
import dev.inmo.micro_utils.pagination.utils.getAllWithNextPaging
2020-10-14 13:37:25 +00:00
import kotlinx.coroutines.flow.Flow
2020-09-20 02:17:11 +00:00
2022-06-04 09:00:23 +00:00
interface ReadKeyValuesRepo<Key, Value> : Repo {
2020-09-20 02:17:11 +00:00
suspend fun get(k: Key, pagination: Pagination, reversed: Boolean = false): PaginationResult<Value>
suspend fun keys(pagination: Pagination, reversed: Boolean = false): PaginationResult<Key>
2020-11-14 10:44:28 +00:00
suspend fun keys(v: Value, pagination: Pagination, reversed: Boolean = false): PaginationResult<Key>
2020-09-20 02:17:11 +00:00
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<Value> {
val results = getAllWithNextPaging { get(k, it) }
return if (reversed) {
results.reversed()
} else {
results
}
}
/**
* WARNING!!! THIS METHOD PROBABLY IS NOT EFFICIENT, USE WITH CAUTION
*/
2020-10-25 16:21:23 +00:00
suspend fun getAll(reverseLists: Boolean = false): Map<Key, List<Value>> = mutableMapOf<Key, List<Value>>().also { map ->
doWithPagination {
keys(it).also { paginationResult ->
paginationResult.results.forEach { k ->
2020-10-25 16:21:23 +00:00
map[k] = getAll(k, reverseLists)
}
}.nextPageIfNotEmpty()
}
}
2020-09-20 02:17:11 +00:00
}
2022-06-04 09:00:23 +00:00
typealias ReadOneToManyKeyValueRepo<Key,Value> = ReadKeyValuesRepo<Key, Value>
2020-09-20 02:17:11 +00:00
2022-06-04 09:00:23 +00:00
interface WriteKeyValuesRepo<Key, Value> : Repo {
2020-10-14 13:37:25 +00:00
val onNewValue: Flow<Pair<Key, Value>>
val onValueRemoved: Flow<Pair<Key, Value>>
val onDataCleared: Flow<Key>
2020-11-06 20:25:50 +00:00
suspend fun add(toAdd: Map<Key, List<Value>>)
2023-04-25 13:14:38 +00:00
/**
* Removes [Value]s by passed [Key]s without full clear of all data by [Key]
*/
2020-11-06 20:25:50 +00:00
suspend fun remove(toRemove: Map<Key, List<Value>>)
2023-04-25 13:14:38 +00:00
/**
* Removes [v] without full clear of all data by [Key]s with [v]
*/
suspend fun removeWithValue(v: Value)
/**
* Fully clear all data by [k]
*/
2020-09-20 02:17:11 +00:00
suspend fun clear(k: Key)
2023-04-25 13:14:38 +00:00
/**
* Clear [v] **with** full clear of all data by [Key]s with [v]
*/
2021-06-15 08:24:00 +00:00
suspend fun clearWithValue(v: Value)
2020-11-18 14:07:54 +00:00
suspend fun set(toSet: Map<Key, List<Value>>) {
toSet.keys.forEach { key -> clear(key) }
add(toSet)
}
2020-09-20 02:17:11 +00:00
}
2022-06-04 09:00:23 +00:00
typealias WriteOneToManyKeyValueRepo<Key,Value> = WriteKeyValuesRepo<Key, Value>
2020-10-25 16:21:23 +00:00
2022-06-04 09:00:23 +00:00
suspend inline fun <Key, Value, REPO : WriteKeyValuesRepo<Key, Value>> REPO.add(
2020-10-25 16:21:23 +00:00
keysAndValues: List<Pair<Key, List<Value>>>
) = add(keysAndValues.toMap())
2022-06-04 09:00:23 +00:00
suspend inline fun <Key, Value, REPO : WriteKeyValuesRepo<Key, Value>> REPO.add(
2020-10-25 16:21:23 +00:00
vararg keysAndValues: Pair<Key, List<Value>>
) = add(keysAndValues.toMap())
2022-06-04 09:00:23 +00:00
suspend inline fun <Key, Value> WriteKeyValuesRepo<Key, Value>.add(
2020-11-08 18:46:26 +00:00
k: Key, v: List<Value>
) = add(mapOf(k to v))
2020-10-25 16:21:23 +00:00
2022-06-04 09:00:23 +00:00
suspend inline fun <Key, Value> WriteKeyValuesRepo<Key, Value>.add(
2020-11-08 18:46:26 +00:00
k: Key, vararg v: Value
) = add(k, v.toList())
2022-06-04 09:00:23 +00:00
suspend inline fun <Key, Value, REPO : WriteKeyValuesRepo<Key, Value>> REPO.set(
2020-11-18 14:07:54 +00:00
keysAndValues: List<Pair<Key, List<Value>>>
) = set(keysAndValues.toMap())
2022-06-04 09:00:23 +00:00
suspend inline fun <Key, Value, REPO : WriteKeyValuesRepo<Key, Value>> REPO.set(
2020-11-18 14:07:54 +00:00
vararg keysAndValues: Pair<Key, List<Value>>
) = set(keysAndValues.toMap())
2022-06-04 09:00:23 +00:00
suspend inline fun <Key, Value> WriteKeyValuesRepo<Key, Value>.set(
2020-11-18 14:07:54 +00:00
k: Key, v: List<Value>
) = set(mapOf(k to v))
2022-06-04 09:00:23 +00:00
suspend inline fun <Key, Value> WriteKeyValuesRepo<Key, Value>.set(
2020-11-18 14:07:54 +00:00
k: Key, vararg v: Value
) = set(k, v.toList())
2022-06-04 09:00:23 +00:00
interface KeyValuesRepo<Key, Value> : ReadKeyValuesRepo<Key, Value>, WriteKeyValuesRepo<Key, Value> {
2021-06-15 08:24:00 +00:00
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()
}
}
2023-04-25 13:14:38 +00:00
suspend override fun removeWithValue(v: Value) {
val toRemove = mutableMapOf<Key, List<Value>>()
doForAllWithNextPaging {
keys(it).also {
it.results.forEach {
if (contains(it, v)) {
toRemove[it] = listOf(v)
}
}
}
}
remove(toRemove)
}
2024-02-15 09:36:32 +00:00
override suspend fun set(toSet: Map<Key, List<Value>>) {
toSet.forEach { (k, v) ->
val diff = getAll(k).diff(v)
remove(k, diff.removed.map { it.value })
add(k, diff.added.map { it.value })
}
}
2021-06-15 08:24:00 +00:00
}
2022-06-04 09:00:23 +00:00
typealias OneToManyKeyValueRepo<Key,Value> = KeyValuesRepo<Key, Value>
2020-11-08 18:46:26 +00:00
2022-06-04 09:00:23 +00:00
class DelegateBasedKeyValuesRepo<Key, Value>(
readDelegate: ReadKeyValuesRepo<Key, Value>,
writeDelegate: WriteKeyValuesRepo<Key, Value>
) : KeyValuesRepo<Key, Value>,
ReadKeyValuesRepo<Key, Value> by readDelegate,
WriteKeyValuesRepo<Key, Value> by writeDelegate
2022-06-04 09:00:23 +00:00
suspend inline fun <Key, Value> WriteKeyValuesRepo<Key, Value>.remove(
2020-10-25 16:21:23 +00:00
keysAndValues: List<Pair<Key, List<Value>>>
) = remove(keysAndValues.toMap())
2022-06-04 09:00:23 +00:00
suspend inline fun <Key, Value> WriteKeyValuesRepo<Key, Value>.remove(
2020-10-25 16:21:23 +00:00
vararg keysAndValues: Pair<Key, List<Value>>
) = remove(keysAndValues.toMap())
2020-11-08 18:46:26 +00:00
2022-06-04 09:00:23 +00:00
suspend inline fun <Key, Value> WriteKeyValuesRepo<Key, Value>.remove(
2020-11-08 18:46:26 +00:00
k: Key,
v: List<Value>
) = remove(mapOf(k to v))
2022-06-04 09:00:23 +00:00
suspend inline fun <Key, Value> WriteKeyValuesRepo<Key, Value>.remove(
2020-11-08 18:46:26 +00:00
k: Key,
vararg v: Value
) = remove(k, v.toList())