mirror of
https://github.com/InsanusMokrassar/MicroUtils.git
synced 2025-10-06 07:39:27 +00:00
Compare commits
13 Commits
Author | SHA1 | Date | |
---|---|---|---|
f81a2f309b | |||
5fc760f4a5 | |||
091cb38339 | |||
3ae9b3e576 | |||
b03b4cbeec | |||
f2c1b3c76a | |||
f3bec34882 | |||
d6aa9fe9c2 | |||
2d5304a770 | |||
88f2c16c82 | |||
490c318d1c | |||
8beaf61a08 | |||
8b61c984eb |
19
CHANGELOG.md
19
CHANGELOG.md
@@ -1,5 +1,24 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 0.4.10
|
||||||
|
|
||||||
|
* `Versions`:
|
||||||
|
* `Klock`: `2.0.0` -> `2.0.1`
|
||||||
|
* `Repo`
|
||||||
|
* Repo `WriteStandardKeyValueRepo` got new method `unsetWithValues`
|
||||||
|
|
||||||
|
## 0.4.9
|
||||||
|
|
||||||
|
* `Versions`:
|
||||||
|
* `Ktor`: `1.4.2` -> `1.4.3`
|
||||||
|
* `Coroutines`:
|
||||||
|
* `launchSynchronously` has been added in JVM
|
||||||
|
* `Repo`
|
||||||
|
* `Common`
|
||||||
|
* In repos different usages of `BroadcastChannel`s has been replaced with `MutableSharedFlow`
|
||||||
|
* `Exposed`
|
||||||
|
* `asObject` open fun has been added in CRUD realization
|
||||||
|
|
||||||
## 0.4.8
|
## 0.4.8
|
||||||
|
|
||||||
* `Versions`:
|
* `Versions`:
|
||||||
|
@@ -0,0 +1,28 @@
|
|||||||
|
package dev.inmo.micro_utils.coroutines
|
||||||
|
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
|
||||||
|
fun <T> launchSynchronously(scope: CoroutineScope = CoroutineScope(Dispatchers.Default), block: suspend CoroutineScope.() -> T): T {
|
||||||
|
var throwable: Throwable? = null
|
||||||
|
var result: T? = null
|
||||||
|
val objectToSynchronize = java.lang.Object()
|
||||||
|
val launchCallback = {
|
||||||
|
scope.launch {
|
||||||
|
safely(
|
||||||
|
{
|
||||||
|
throwable = it
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
result = block()
|
||||||
|
}
|
||||||
|
synchronized(objectToSynchronize) {
|
||||||
|
objectToSynchronize.notifyAll()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
synchronized(objectToSynchronize) {
|
||||||
|
launchCallback()
|
||||||
|
objectToSynchronize.wait()
|
||||||
|
}
|
||||||
|
throw throwable ?: return result!!
|
||||||
|
}
|
@@ -0,0 +1,13 @@
|
|||||||
|
package dev.inmo.micro_utils.coroutines
|
||||||
|
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class LaunchSynchronouslyTest {
|
||||||
|
@Test
|
||||||
|
fun testRunInCoroutine() {
|
||||||
|
(0 .. 10000).forEach {
|
||||||
|
assertEquals(it, launchSynchronously { it })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,3 +1,5 @@
|
|||||||
|
apply plugin: 'com.getkeepsafe.dexcount'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion "$android_compileSdkVersion".toInteger()
|
compileSdkVersion "$android_compileSdkVersion".toInteger()
|
||||||
buildToolsVersion "$android_buildToolsVersion"
|
buildToolsVersion "$android_buildToolsVersion"
|
||||||
|
@@ -11,9 +11,9 @@ kotlin_coroutines_version=1.4.2
|
|||||||
kotlin_serialisation_core_version=1.0.1
|
kotlin_serialisation_core_version=1.0.1
|
||||||
kotlin_exposed_version=0.28.1
|
kotlin_exposed_version=0.28.1
|
||||||
|
|
||||||
ktor_version=1.4.2
|
ktor_version=1.4.3
|
||||||
|
|
||||||
klockVersion=2.0.0
|
klockVersion=2.0.1
|
||||||
|
|
||||||
github_release_plugin_version=2.2.12
|
github_release_plugin_version=2.2.12
|
||||||
|
|
||||||
@@ -28,17 +28,17 @@ appcompat_version=1.2.0
|
|||||||
android_minSdkVersion=19
|
android_minSdkVersion=19
|
||||||
android_compileSdkVersion=30
|
android_compileSdkVersion=30
|
||||||
android_buildToolsVersion=30.0.2
|
android_buildToolsVersion=30.0.2
|
||||||
dexcount_version=2.0.0-RC1
|
dexcount_version=2.0.0
|
||||||
junit_version=4.12
|
junit_version=4.12
|
||||||
test_ext_junit_version=1.1.2
|
test_ext_junit_version=1.1.2
|
||||||
espresso_core=3.3.0
|
espresso_core=3.3.0
|
||||||
|
|
||||||
# Dokka
|
# Dokka
|
||||||
|
|
||||||
dokka_version=1.4.10.2
|
dokka_version=1.4.20
|
||||||
|
|
||||||
# Project data
|
# Project data
|
||||||
|
|
||||||
group=dev.inmo
|
group=dev.inmo
|
||||||
version=0.4.8
|
version=0.4.10
|
||||||
android_code_version=12
|
android_code_version=14
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
package dev.inmo.micro_utils.repos
|
package dev.inmo.micro_utils.repos
|
||||||
|
|
||||||
import dev.inmo.micro_utils.pagination.Pagination
|
import dev.inmo.micro_utils.pagination.*
|
||||||
import dev.inmo.micro_utils.pagination.PaginationResult
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
interface ReadStandardKeyValueRepo<Key, Value> : Repo {
|
interface ReadStandardKeyValueRepo<Key, Value> : Repo {
|
||||||
@@ -20,6 +19,7 @@ interface WriteStandardKeyValueRepo<Key, Value> : Repo {
|
|||||||
|
|
||||||
suspend fun set(toSet: Map<Key, Value>)
|
suspend fun set(toSet: Map<Key, Value>)
|
||||||
suspend fun unset(toUnset: List<Key>)
|
suspend fun unset(toUnset: List<Key>)
|
||||||
|
suspend fun unsetWithValues(toUnset: List<Value>)
|
||||||
}
|
}
|
||||||
typealias WriteKeyValueRepo<Key,Value> = WriteStandardKeyValueRepo<Key, Value>
|
typealias WriteKeyValueRepo<Key,Value> = WriteStandardKeyValueRepo<Key, Value>
|
||||||
|
|
||||||
@@ -35,5 +35,17 @@ suspend inline fun <Key, Value> WriteStandardKeyValueRepo<Key, Value>.unset(
|
|||||||
vararg k: Key
|
vararg k: Key
|
||||||
) = unset(k.toList())
|
) = unset(k.toList())
|
||||||
|
|
||||||
interface StandardKeyValueRepo<Key, Value> : ReadStandardKeyValueRepo<Key, Value>, WriteStandardKeyValueRepo<Key, Value>
|
suspend inline fun <Key, Value> WriteStandardKeyValueRepo<Key, Value>.unsetWithValues(
|
||||||
|
vararg v: Value
|
||||||
|
) = unsetWithValues(v.toList())
|
||||||
|
|
||||||
|
interface StandardKeyValueRepo<Key, Value> : ReadStandardKeyValueRepo<Key, Value>, WriteStandardKeyValueRepo<Key, Value> {
|
||||||
|
override suspend fun unsetWithValues(toUnset: List<Value>) = toUnset.forEach { v ->
|
||||||
|
doWithPagination {
|
||||||
|
keys(v, it).also {
|
||||||
|
unset(it.results)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
typealias KeyValueRepo<Key,Value> = StandardKeyValueRepo<Key, Value>
|
typealias KeyValueRepo<Key,Value> = StandardKeyValueRepo<Key, Value>
|
||||||
|
@@ -105,6 +105,10 @@ open class MapperWriteStandardKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
|
|||||||
k.toOutKey()
|
k.toOutKey()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
override suspend fun unsetWithValues(toUnset: List<FromValue>) = to.unsetWithValues(
|
||||||
|
toUnset.map { it.toOutValue() }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
@@ -160,6 +160,18 @@ class FileWriteStandardKeyValueRepo(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun unsetWithValues(toUnset: List<File>) {
|
||||||
|
val keys = toUnset.mapNotNull { v ->
|
||||||
|
val key = v.absolutePath.removePrefix(folder.absolutePath)
|
||||||
|
if (key != v.absolutePath) {
|
||||||
|
key
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset(keys)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Warning("Files watching will not correctly works on Android Platform with version of API lower than API 26")
|
@Warning("Files watching will not correctly works on Android Platform with version of API lower than API 26")
|
||||||
|
@@ -3,20 +3,18 @@ package dev.inmo.micro_utils.repos.crud
|
|||||||
import android.content.ContentValues
|
import android.content.ContentValues
|
||||||
import dev.inmo.micro_utils.common.mapNotNullA
|
import dev.inmo.micro_utils.common.mapNotNullA
|
||||||
import dev.inmo.micro_utils.repos.*
|
import dev.inmo.micro_utils.repos.*
|
||||||
import kotlinx.coroutines.channels.BroadcastChannel
|
import kotlinx.coroutines.flow.*
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
import kotlinx.coroutines.flow.asFlow
|
|
||||||
|
|
||||||
abstract class AbstractMutableAndroidCRUDRepo<ObjectType, IdType, InputValueType>(
|
abstract class AbstractMutableAndroidCRUDRepo<ObjectType, IdType, InputValueType>(
|
||||||
helper: StandardSQLHelper
|
helper: StandardSQLHelper
|
||||||
) : WriteStandardCRUDRepo<ObjectType, IdType, InputValueType>,
|
) : WriteStandardCRUDRepo<ObjectType, IdType, InputValueType>,
|
||||||
AbstractAndroidCRUDRepo<ObjectType, IdType>(helper) {
|
AbstractAndroidCRUDRepo<ObjectType, IdType>(helper) {
|
||||||
protected val newObjectsChannel = BroadcastChannel<ObjectType>(64)
|
protected val newObjectsChannel = MutableSharedFlow<ObjectType>(64)
|
||||||
protected val updateObjectsChannel = BroadcastChannel<ObjectType>(64)
|
protected val updateObjectsChannel = MutableSharedFlow<ObjectType>(64)
|
||||||
protected val deleteObjectsIdsChannel = BroadcastChannel<IdType>(64)
|
protected val deleteObjectsIdsChannel = MutableSharedFlow<IdType>(64)
|
||||||
override val newObjectsFlow: Flow<ObjectType> = newObjectsChannel.asFlow()
|
override val newObjectsFlow: Flow<ObjectType> = newObjectsChannel.asSharedFlow()
|
||||||
override val updatedObjectsFlow: Flow<ObjectType> = updateObjectsChannel.asFlow()
|
override val updatedObjectsFlow: Flow<ObjectType> = updateObjectsChannel.asSharedFlow()
|
||||||
override val deletedObjectsIdsFlow: Flow<IdType> = deleteObjectsIdsChannel.asFlow()
|
override val deletedObjectsIdsFlow: Flow<IdType> = deleteObjectsIdsChannel.asSharedFlow()
|
||||||
|
|
||||||
protected abstract suspend fun InputValueType.asContentValues(id: IdType? = null): ContentValues
|
protected abstract suspend fun InputValueType.asContentValues(id: IdType? = null): ContentValues
|
||||||
|
|
||||||
@@ -42,7 +40,7 @@ abstract class AbstractMutableAndroidCRUDRepo<ObjectType, IdType, InputValueType
|
|||||||
}
|
}
|
||||||
}.also {
|
}.also {
|
||||||
it.forEach {
|
it.forEach {
|
||||||
newObjectsChannel.send(it)
|
newObjectsChannel.emit(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -59,7 +57,7 @@ abstract class AbstractMutableAndroidCRUDRepo<ObjectType, IdType, InputValueType
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
deleted.forEach {
|
deleted.forEach {
|
||||||
deleteObjectsIdsChannel.send(it)
|
deleteObjectsIdsChannel.emit(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +74,7 @@ abstract class AbstractMutableAndroidCRUDRepo<ObjectType, IdType, InputValueType
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return getById(id) ?.also {
|
return getById(id) ?.also {
|
||||||
updateObjectsChannel.send(it)
|
updateObjectsChannel.emit(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,7 +93,7 @@ abstract class AbstractMutableAndroidCRUDRepo<ObjectType, IdType, InputValueType
|
|||||||
getById(it.first)
|
getById(it.first)
|
||||||
}.also {
|
}.also {
|
||||||
it.forEach {
|
it.forEach {
|
||||||
updateObjectsChannel.send(it)
|
updateObjectsChannel.emit(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,10 +8,7 @@ import dev.inmo.micro_utils.pagination.PaginationResult
|
|||||||
import dev.inmo.micro_utils.pagination.utils.paginate
|
import dev.inmo.micro_utils.pagination.utils.paginate
|
||||||
import dev.inmo.micro_utils.pagination.utils.reverse
|
import dev.inmo.micro_utils.pagination.utils.reverse
|
||||||
import dev.inmo.micro_utils.repos.StandardKeyValueRepo
|
import dev.inmo.micro_utils.repos.StandardKeyValueRepo
|
||||||
import kotlinx.coroutines.channels.BroadcastChannel
|
import kotlinx.coroutines.flow.*
|
||||||
import kotlinx.coroutines.channels.Channel
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
import kotlinx.coroutines.flow.asFlow
|
|
||||||
|
|
||||||
private val cache = HashMap<String, KeyValueStore<*>>()
|
private val cache = HashMap<String, KeyValueStore<*>>()
|
||||||
|
|
||||||
@@ -37,11 +34,11 @@ class KeyValueStore<T : Any> internal constructor (
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
private val onNewValueChannel = BroadcastChannel<Pair<String, T>>(Channel.BUFFERED)
|
private val onNewValueChannel = MutableSharedFlow<Pair<String, T>>()
|
||||||
private val onValueRemovedChannel = BroadcastChannel<String>(Channel.BUFFERED)
|
private val _onValueRemovedFlow = MutableSharedFlow<String>()
|
||||||
|
|
||||||
override val onNewValue: Flow<Pair<String, T>> = onNewValueChannel.asFlow()
|
override val onNewValue: Flow<Pair<String, T>> = onNewValueChannel.asSharedFlow()
|
||||||
override val onValueRemoved: Flow<String> = onValueRemovedChannel.asFlow()
|
override val onValueRemoved: Flow<String> = _onValueRemovedFlow.asSharedFlow()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
cachedData ?.let {
|
cachedData ?.let {
|
||||||
@@ -131,7 +128,7 @@ class KeyValueStore<T : Any> internal constructor (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
toSet.forEach { (k, v) ->
|
toSet.forEach { (k, v) ->
|
||||||
onNewValueChannel.send(k to v)
|
onNewValueChannel.emit(k to v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,6 +136,18 @@ class KeyValueStore<T : Any> internal constructor (
|
|||||||
sharedPreferences.edit {
|
sharedPreferences.edit {
|
||||||
toUnset.forEach { remove(it) }
|
toUnset.forEach { remove(it) }
|
||||||
}
|
}
|
||||||
toUnset.forEach { onValueRemovedChannel.send(it) }
|
toUnset.forEach { _onValueRemovedFlow.emit(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun unsetWithValues(toUnset: List<T>) {
|
||||||
|
val keysToRemove = sharedPreferences.all.mapNotNull { if (it.value in toUnset) it.key else null }
|
||||||
|
sharedPreferences.edit {
|
||||||
|
keysToRemove.map {
|
||||||
|
remove(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
keysToRemove.forEach {
|
||||||
|
_onValueRemovedFlow.emit(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -32,11 +32,11 @@ class AndroidSQLStandardVersionsRepoProxy(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getTableVersion(table: String): Int? = database.writableTransaction {
|
override suspend fun getTableVersion(tableName: String): Int? = database.writableTransaction {
|
||||||
select(
|
select(
|
||||||
tableName,
|
this@AndroidSQLStandardVersionsRepoProxy.tableName,
|
||||||
selection = "$tableNameColumnName=?",
|
selection = "$tableNameColumnName=?",
|
||||||
selectionArgs = arrayOf(table),
|
selectionArgs = arrayOf(tableName),
|
||||||
limit = limitClause(1)
|
limit = limitClause(1)
|
||||||
).use {
|
).use {
|
||||||
if (it.moveToFirst()) {
|
if (it.moveToFirst()) {
|
||||||
@@ -47,16 +47,16 @@ class AndroidSQLStandardVersionsRepoProxy(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun updateTableVersion(table: String, version: Int) {
|
override suspend fun updateTableVersion(tableName: String, version: Int) {
|
||||||
database.writableTransaction {
|
database.writableTransaction {
|
||||||
val updated = update(
|
val updated = update(
|
||||||
tableName,
|
this@AndroidSQLStandardVersionsRepoProxy.tableName,
|
||||||
contentValuesOf(tableVersionColumnName to version),
|
contentValuesOf(tableVersionColumnName to version),
|
||||||
"$tableNameColumnName=?",
|
"$tableNameColumnName=?",
|
||||||
arrayOf(table)
|
arrayOf(tableName)
|
||||||
) > 0
|
) > 0
|
||||||
if (!updated) {
|
if (!updated) {
|
||||||
insert(tableName, null, contentValuesOf(tableNameColumnName to table, tableVersionColumnName to version))
|
insert(this@AndroidSQLStandardVersionsRepoProxy.tableName, null, contentValuesOf(tableNameColumnName to tableName, tableVersionColumnName to version))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,6 @@ package dev.inmo.micro_utils.repos.exposed
|
|||||||
|
|
||||||
import dev.inmo.micro_utils.repos.UpdatedValuePair
|
import dev.inmo.micro_utils.repos.UpdatedValuePair
|
||||||
import dev.inmo.micro_utils.repos.WriteStandardCRUDRepo
|
import dev.inmo.micro_utils.repos.WriteStandardCRUDRepo
|
||||||
import kotlinx.coroutines.channels.BroadcastChannel
|
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
import org.jetbrains.exposed.sql.*
|
import org.jetbrains.exposed.sql.*
|
||||||
import org.jetbrains.exposed.sql.statements.InsertStatement
|
import org.jetbrains.exposed.sql.statements.InsertStatement
|
||||||
@@ -25,8 +24,10 @@ abstract class AbstractExposedWriteCRUDRepo<ObjectType, IdType, InputValueType>(
|
|||||||
override val updatedObjectsFlow: Flow<ObjectType> = updateObjectsChannel.asSharedFlow()
|
override val updatedObjectsFlow: Flow<ObjectType> = updateObjectsChannel.asSharedFlow()
|
||||||
override val deletedObjectsIdsFlow: Flow<IdType> = deleteObjectsIdsChannel.asSharedFlow()
|
override val deletedObjectsIdsFlow: Flow<IdType> = deleteObjectsIdsChannel.asSharedFlow()
|
||||||
|
|
||||||
|
@Deprecated("Will be removed in near major update. Override open fun with the same name instead")
|
||||||
abstract val InsertStatement<Number>.asObject: ObjectType
|
abstract val InsertStatement<Number>.asObject: ObjectType
|
||||||
abstract val selectByIds: SqlExpressionBuilder.(List<out IdType>) -> Op<Boolean>
|
protected open fun InsertStatement<Number>.asObject(value: InputValueType): ObjectType = asObject
|
||||||
|
abstract val selectByIds: SqlExpressionBuilder.(List<IdType>) -> Op<Boolean>
|
||||||
|
|
||||||
protected abstract fun insert(value: InputValueType, it: InsertStatement<Number>)
|
protected abstract fun insert(value: InputValueType, it: InsertStatement<Number>)
|
||||||
protected abstract fun update(id: IdType, value: InputValueType, it: UpdateStatement)
|
protected abstract fun update(id: IdType, value: InputValueType, it: UpdateStatement)
|
||||||
@@ -34,7 +35,7 @@ abstract class AbstractExposedWriteCRUDRepo<ObjectType, IdType, InputValueType>(
|
|||||||
protected open suspend fun onBeforeCreate(value: List<InputValueType>) {}
|
protected open suspend fun onBeforeCreate(value: List<InputValueType>) {}
|
||||||
private fun createWithoutNotification(value: InputValueType): ObjectType {
|
private fun createWithoutNotification(value: InputValueType): ObjectType {
|
||||||
return transaction(database) {
|
return transaction(database) {
|
||||||
insert { insert(value, it) }.asObject
|
insert { insert(value, it) }.asObject(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,10 +43,8 @@ abstract class AbstractExposedWriteCRUDRepo<ObjectType, IdType, InputValueType>(
|
|||||||
onBeforeCreate(values)
|
onBeforeCreate(values)
|
||||||
return transaction(db = database) {
|
return transaction(db = database) {
|
||||||
values.map { value -> createWithoutNotification(value) }
|
values.map { value -> createWithoutNotification(value) }
|
||||||
}.also {
|
}.onEach {
|
||||||
it.forEach {
|
newObjectsChannel.emit(it)
|
||||||
newObjectsChannel.emit(it)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,13 +82,9 @@ abstract class AbstractExposedWriteCRUDRepo<ObjectType, IdType, InputValueType>(
|
|||||||
return (
|
return (
|
||||||
transaction(db = database) {
|
transaction(db = database) {
|
||||||
values.map { (id, value) -> updateWithoutNotification(id, value) }
|
values.map { (id, value) -> updateWithoutNotification(id, value) }
|
||||||
}.filter {
|
}.filterNotNull()
|
||||||
it != null
|
).onEach {
|
||||||
} as List<ObjectType>
|
updateObjectsChannel.emit(it)
|
||||||
).also {
|
|
||||||
it.forEach {
|
|
||||||
updateObjectsChannel.emit(it)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
protected open suspend fun onBeforeDelete(ids: List<IdType>) {}
|
protected open suspend fun onBeforeDelete(ids: List<IdType>) {}
|
||||||
|
@@ -60,4 +60,16 @@ open class ExposedKeyValueRepo<Key, Value>(
|
|||||||
_onValueRemoved.emit(it)
|
_onValueRemoved.emit(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun unsetWithValues(toUnset: List<Value>) {
|
||||||
|
transaction(database) {
|
||||||
|
toUnset.flatMap {
|
||||||
|
val keys = select { valueColumn.eq(it) }.mapNotNull { it[keyColumn] }
|
||||||
|
deleteWhere { keyColumn.inList(keys) }
|
||||||
|
keys
|
||||||
|
}
|
||||||
|
}.distinct().forEach {
|
||||||
|
_onValueRemoved.emit(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -76,6 +76,15 @@ class WriteMapKeyValueRepo<Key, Value>(
|
|||||||
map.remove(k) ?.also { _ -> _onValueRemoved.emit(k) }
|
map.remove(k) ?.also { _ -> _onValueRemoved.emit(k) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun unsetWithValues(toUnset: List<Value>) {
|
||||||
|
map.forEach {
|
||||||
|
if (it.value in toUnset) {
|
||||||
|
map.remove(it.key)
|
||||||
|
_onValueRemoved.emit(it.key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MapKeyValueRepo<Key, Value>(
|
class MapKeyValueRepo<Key, Value>(
|
||||||
|
@@ -7,6 +7,7 @@ import dev.inmo.micro_utils.repos.*
|
|||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
|
@Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE")
|
||||||
class KtorStandartKeyValueRepo<K, V> (
|
class KtorStandartKeyValueRepo<K, V> (
|
||||||
baseUrl: String,
|
baseUrl: String,
|
||||||
baseSubpart: String,
|
baseSubpart: String,
|
||||||
|
@@ -17,6 +17,7 @@ class KtorWriteStandardKeyValueRepo<K, V> (
|
|||||||
) : WriteStandardKeyValueRepo<K, V> {
|
) : WriteStandardKeyValueRepo<K, V> {
|
||||||
private val keyValueMapSerializer = MapSerializer(keySerializer, valueSerializer)
|
private val keyValueMapSerializer = MapSerializer(keySerializer, valueSerializer)
|
||||||
private val keysListSerializer = ListSerializer(keySerializer)
|
private val keysListSerializer = ListSerializer(keySerializer)
|
||||||
|
private val valuesListSerializer = ListSerializer(valueSerializer)
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
baseUrl: String,
|
baseUrl: String,
|
||||||
@@ -55,4 +56,13 @@ class KtorWriteStandardKeyValueRepo<K, V> (
|
|||||||
BodyPair(keysListSerializer, toUnset),
|
BodyPair(keysListSerializer, toUnset),
|
||||||
Unit.serializer()
|
Unit.serializer()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
override suspend fun unsetWithValues(toUnset: List<V>) = unifiedRequester.unipost(
|
||||||
|
buildStandardUrl(
|
||||||
|
baseUrl,
|
||||||
|
unsetWithValuesRoute,
|
||||||
|
),
|
||||||
|
BodyPair(valuesListSerializer, toUnset),
|
||||||
|
Unit.serializer()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
@@ -10,3 +10,4 @@ const val onNewValueRoute = "onNewValue"
|
|||||||
const val onValueRemovedRoute = "onValueRemoved"
|
const val onValueRemovedRoute = "onValueRemoved"
|
||||||
const val setRoute = "set"
|
const val setRoute = "set"
|
||||||
const val unsetRoute = "unset"
|
const val unsetRoute = "unset"
|
||||||
|
const val unsetWithValuesRoute = "unsetWithValues"
|
@@ -19,6 +19,7 @@ fun <K, V> Route.configureWriteStandardKeyValueRepoRoutes (
|
|||||||
) {
|
) {
|
||||||
val keyValueMapSerializer = MapSerializer(keySerializer, valueSerializer)
|
val keyValueMapSerializer = MapSerializer(keySerializer, valueSerializer)
|
||||||
val keysListSerializer = ListSerializer(keySerializer)
|
val keysListSerializer = ListSerializer(keySerializer)
|
||||||
|
val valuesListSerializer = ListSerializer(valueSerializer)
|
||||||
unifiedRouter.apply {
|
unifiedRouter.apply {
|
||||||
includeWebsocketHandling(
|
includeWebsocketHandling(
|
||||||
onNewValueRoute,
|
onNewValueRoute,
|
||||||
@@ -50,6 +51,14 @@ fun <K, V> Route.configureWriteStandardKeyValueRepoRoutes (
|
|||||||
unianswer(Unit.serializer(), originalRepo.unset(toUnset))
|
unianswer(Unit.serializer(), originalRepo.unset(toUnset))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
post(unsetWithValuesRoute) {
|
||||||
|
unifiedRouter.apply {
|
||||||
|
val toUnset = uniload(valuesListSerializer)
|
||||||
|
|
||||||
|
unianswer(Unit.serializer(), originalRepo.unsetWithValues(toUnset))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <K, V> Route.configureWriteStandartKeyValueRepoRoutes (
|
fun <K, V> Route.configureWriteStandartKeyValueRepoRoutes (
|
||||||
|
Reference in New Issue
Block a user