MicroUtils/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/keyvalue/ExposedKeyValueRepo.kt

94 lines
3.1 KiB
Kotlin
Raw Normal View History

2020-09-22 01:47:01 +00:00
package dev.inmo.micro_utils.repos.exposed.keyvalue
2022-06-04 08:42:16 +00:00
import dev.inmo.micro_utils.repos.KeyValueRepo
2020-11-02 15:34:49 +00:00
import dev.inmo.micro_utils.repos.exposed.ColumnAllocator
2024-04-01 12:20:05 +00:00
import kotlinx.coroutines.channels.BufferOverflow
2020-11-06 20:25:50 +00:00
import kotlinx.coroutines.flow.*
2020-09-22 01:47:01 +00:00
import org.jetbrains.exposed.sql.*
2022-11-08 06:47:59 +00:00
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
import org.jetbrains.exposed.sql.SqlExpressionBuilder.inList
2023-07-23 07:47:20 +00:00
import org.jetbrains.exposed.sql.SqlExpressionBuilder.inSubQuery
2020-09-22 01:47:01 +00:00
import org.jetbrains.exposed.sql.transactions.transaction
2020-10-17 11:41:56 +00:00
open class ExposedKeyValueRepo<Key, Value>(
2020-09-22 01:47:01 +00:00
database: Database,
2020-10-17 11:41:56 +00:00
keyColumnAllocator: ColumnAllocator<Key>,
valueColumnAllocator: ColumnAllocator<Value>,
2024-04-01 12:20:05 +00:00
tableName: String? = null,
flowsExtraBufferCapacity: Int = Int.MAX_VALUE,
flowsBufferOverflow: BufferOverflow = BufferOverflow.SUSPEND
2022-06-04 08:42:16 +00:00
) : KeyValueRepo<Key, Value>, ExposedReadKeyValueRepo<Key, Value>(
2020-09-22 01:47:01 +00:00
database,
2020-10-17 11:41:56 +00:00
keyColumnAllocator,
valueColumnAllocator,
tableName
2020-09-22 01:47:01 +00:00
) {
2024-04-01 12:20:05 +00:00
protected val _onNewValue = MutableSharedFlow<Pair<Key, Value>>(extraBufferCapacity = flowsExtraBufferCapacity, onBufferOverflow = flowsBufferOverflow)
protected val _onValueRemoved = MutableSharedFlow<Key>(extraBufferCapacity = flowsExtraBufferCapacity, onBufferOverflow = flowsBufferOverflow)
2020-09-22 01:47:01 +00:00
2020-11-06 20:25:50 +00:00
override val onNewValue: Flow<Pair<Key, Value>> = _onNewValue.asSharedFlow()
override val onValueRemoved: Flow<Key> = _onValueRemoved.asSharedFlow()
2020-09-22 01:47:01 +00:00
2020-11-06 20:25:50 +00:00
override suspend fun set(toSet: Map<Key, Value>) {
transaction(database) {
toSet.mapNotNull { (k, v) ->
if (update({ keyColumn.eq(k) }) { it[valueColumn] = v } > 0) {
k to v
} else {
val inserted = insert {
it[keyColumn] = k
it[valueColumn] = v
}.getOrNull(keyColumn) != null
if (inserted) {
k to v
} else {
null
}
}
}
}.forEach {
_onNewValue.emit(it)
}
2020-09-22 01:47:01 +00:00
}
2020-11-06 20:25:50 +00:00
override suspend fun unset(toUnset: List<Key>) {
transaction(database) {
2022-11-08 06:47:59 +00:00
toUnset.mapNotNull { item ->
if (deleteWhere { keyColumn.eq(item) } > 0) {
item
2020-11-06 20:25:50 +00:00
} else {
null
}
}
}.forEach {
_onValueRemoved.emit(it)
}
2020-09-22 01:47:01 +00:00
}
override suspend fun unsetWithValues(toUnset: List<Value>) {
transaction(database) {
toUnset.flatMap {
2024-01-11 17:09:17 +00:00
val keys = selectAll().where { valueColumn.eq(it) }.mapNotNull { it[keyColumn] }
deleteWhere { keyColumn.inList(keys) }
keys
}
}.distinct().forEach {
_onValueRemoved.emit(it)
}
}
2023-07-23 07:47:20 +00:00
override suspend fun clear() {
transaction(database) {
val keys = selectAll().map { it.asKey }
deleteAll()
keys
}.also {
it.forEach {
_onValueRemoved.emit(it)
}
}
}
2020-09-22 01:47:01 +00:00
}