mirror of
https://github.com/InsanusMokrassar/MicroUtils.git
synced 2024-12-02 15:00:08 +00:00
Compare commits
15 Commits
1af5faa440
...
b796620267
Author | SHA1 | Date | |
---|---|---|---|
b796620267 | |||
62df81bb4e | |||
0a8e0f6178 | |||
f705020aaa | |||
78bd3b9853 | |||
992b283597 | |||
8fc1ff1d59 | |||
3bbde61f39 | |||
8d955c4b9d | |||
18593c530b | |||
78903cd4eb | |||
eaa143f7d7 | |||
bcb0e42fa2 | |||
8eed435302 | |||
0e4a63057f |
15
CHANGELOG.md
15
CHANGELOG.md
@ -1,5 +1,20 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 0.11.0
|
||||||
|
|
||||||
|
* `Versions`
|
||||||
|
* `UUID`: `0.4.0` -> `0.4.1`
|
||||||
|
* `Ktor`
|
||||||
|
* `Client`:
|
||||||
|
* New extension fun `HttpResponse#throwOnUnsuccess`
|
||||||
|
* All old functions, classes and extensions has been rewritten with new ktor-way with types info and keeping `ContentNegotiation` in mind
|
||||||
|
* `Server`:
|
||||||
|
* All old functions, classes and extensions has been rewritten with new ktor-way with types info and keeping `ContentNegotiation` in mind
|
||||||
|
* `Repos`
|
||||||
|
* `Ktor`:
|
||||||
|
* Fully rewritten work with all declared repositories
|
||||||
|
* All old functions, classes and extensions has been rewritten with new ktor-way with types info and keeping `ContentNegotiation` in mind
|
||||||
|
|
||||||
## 0.10.8
|
## 0.10.8
|
||||||
|
|
||||||
* `Common`
|
* `Common`
|
||||||
|
@ -14,5 +14,5 @@ crypto_js_version=4.1.1
|
|||||||
# Project data
|
# Project data
|
||||||
|
|
||||||
group=dev.inmo
|
group=dev.inmo
|
||||||
version=0.10.8
|
version=0.11.0
|
||||||
android_code_version=123
|
android_code_version=124
|
||||||
|
@ -9,7 +9,7 @@ jb-exposed = "0.38.2"
|
|||||||
jb-dokka = "1.6.21"
|
jb-dokka = "1.6.21"
|
||||||
|
|
||||||
klock = "2.7.0"
|
klock = "2.7.0"
|
||||||
uuid = "0.4.0"
|
uuid = "0.4.1"
|
||||||
|
|
||||||
ktor = "2.0.2"
|
ktor = "2.0.2"
|
||||||
|
|
||||||
@ -37,17 +37,24 @@ kt-serialization-cbor = { module = "org.jetbrains.kotlinx:kotlinx-serialization-
|
|||||||
|
|
||||||
kt-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kt-coroutines" }
|
kt-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kt-coroutines" }
|
||||||
kt-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kt-coroutines" }
|
kt-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kt-coroutines" }
|
||||||
|
kt-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kt-coroutines" }
|
||||||
|
|
||||||
|
|
||||||
ktor-io = { module = "io.ktor:ktor-io", version.ref = "ktor" }
|
ktor-io = { module = "io.ktor:ktor-io", version.ref = "ktor" }
|
||||||
|
ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" }
|
||||||
ktor-client = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
|
ktor-client = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
|
||||||
|
ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" }
|
||||||
ktor-client-java = { module = "io.ktor:ktor-client-java", version.ref = "ktor" }
|
ktor-client-java = { module = "io.ktor:ktor-client-java", version.ref = "ktor" }
|
||||||
|
ktor-client-websockets = { module = "io.ktor:ktor-client-websockets", version.ref = "ktor" }
|
||||||
|
ktor-client-logging = { module = "io.ktor:ktor-client-logging", version.ref = "ktor" }
|
||||||
|
ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" }
|
||||||
ktor-server = { module = "io.ktor:ktor-server", version.ref = "ktor" }
|
ktor-server = { module = "io.ktor:ktor-server", version.ref = "ktor" }
|
||||||
ktor-server-cio = { module = "io.ktor:ktor-server-cio", version.ref = "ktor" }
|
ktor-server-cio = { module = "io.ktor:ktor-server-cio", version.ref = "ktor" }
|
||||||
ktor-server-host-common = { module = "io.ktor:ktor-server-host-common", version.ref = "ktor" }
|
ktor-server-host-common = { module = "io.ktor:ktor-server-host-common", version.ref = "ktor" }
|
||||||
ktor-websockets = { module = "io.ktor:ktor-websockets", version.ref = "ktor" }
|
ktor-websockets = { module = "io.ktor:ktor-websockets", version.ref = "ktor" }
|
||||||
ktor-server-websockets = { module = "io.ktor:ktor-server-websockets", version.ref = "ktor" }
|
ktor-server-websockets = { module = "io.ktor:ktor-server-websockets", version.ref = "ktor" }
|
||||||
ktor-server-statusPages = { module = "io.ktor:ktor-server-status-pages", version.ref = "ktor" }
|
ktor-server-statusPages = { module = "io.ktor:ktor-server-status-pages", version.ref = "ktor" }
|
||||||
|
ktor-server-content-negotiation = { module = "io.ktor:ktor-server-content-negotiation", version.ref = "ktor" }
|
||||||
|
|
||||||
|
|
||||||
klock = { module = "com.soywiz.korlibs.klock:klock", version.ref = "klock" }
|
klock = { module = "com.soywiz.korlibs.klock:klock", version.ref = "klock" }
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
package dev.inmo.micro_utils.ktor.client
|
||||||
|
|
||||||
|
import io.ktor.client.plugins.ClientRequestException
|
||||||
|
import io.ktor.client.statement.HttpResponse
|
||||||
|
import io.ktor.http.isSuccess
|
||||||
|
|
||||||
|
inline fun HttpResponse.throwOnUnsuccess(
|
||||||
|
unsuccessMessage: () -> String
|
||||||
|
) {
|
||||||
|
if (status.isSuccess()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
throw ClientRequestException(this, unsuccessMessage())
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
package dev.inmo.micro_utils.ktor.client
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.coroutines.runCatchingSafely
|
||||||
|
import dev.inmo.micro_utils.coroutines.safely
|
||||||
|
import dev.inmo.micro_utils.ktor.common.*
|
||||||
|
import io.ktor.client.HttpClient
|
||||||
|
import io.ktor.client.plugins.pluginOrNull
|
||||||
|
import io.ktor.client.plugins.websocket.*
|
||||||
|
import io.ktor.client.request.HttpRequestBuilder
|
||||||
|
import io.ktor.websocket.Frame
|
||||||
|
import io.ktor.websocket.readBytes
|
||||||
|
import io.ktor.websocket.serialization.sendSerializedBase
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.channelFlow
|
||||||
|
import kotlinx.coroutines.isActive
|
||||||
|
import kotlinx.serialization.DeserializationStrategy
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param checkReconnection This lambda will be called when it is required to reconnect to websocket to establish
|
||||||
|
* connection. Must return true in case if must be reconnected. By default always reconnecting
|
||||||
|
*/
|
||||||
|
inline fun <reified T> HttpClient.createStandardWebsocketFlow(
|
||||||
|
url: String,
|
||||||
|
noinline checkReconnection: suspend (Throwable?) -> Boolean = { true },
|
||||||
|
noinline requestBuilder: HttpRequestBuilder.() -> Unit = {}
|
||||||
|
): Flow<T> {
|
||||||
|
pluginOrNull(WebSockets) ?: error("Plugin $WebSockets must be installed for using createStandardWebsocketFlow")
|
||||||
|
|
||||||
|
val correctedUrl = url.asCorrectWebSocketUrl
|
||||||
|
|
||||||
|
return channelFlow {
|
||||||
|
do {
|
||||||
|
val reconnect = runCatchingSafely {
|
||||||
|
ws(correctedUrl, requestBuilder) {
|
||||||
|
for (received in incoming) {
|
||||||
|
sendSerialized(received.data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkReconnection(null)
|
||||||
|
}.getOrElse { e ->
|
||||||
|
checkReconnection(e).also {
|
||||||
|
if (!it) {
|
||||||
|
close(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (reconnect && isActive)
|
||||||
|
|
||||||
|
if (isActive) {
|
||||||
|
safely {
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package dev.inmo.micro_utils.ktor.server
|
||||||
|
|
||||||
|
import io.ktor.server.application.ApplicationCall
|
||||||
|
import io.ktor.server.response.responseType
|
||||||
|
import io.ktor.util.InternalAPI
|
||||||
|
import io.ktor.util.reflect.TypeInfo
|
||||||
|
|
||||||
|
@InternalAPI
|
||||||
|
suspend fun <T : Any> ApplicationCall.respond(
|
||||||
|
message: T,
|
||||||
|
typeInfo: TypeInfo
|
||||||
|
) {
|
||||||
|
response.responseType = typeInfo
|
||||||
|
response.pipeline.execute(this, message as Any)
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package dev.inmo.micro_utils.ktor.server
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.coroutines.safely
|
||||||
|
import dev.inmo.micro_utils.ktor.common.*
|
||||||
|
import io.ktor.http.URLProtocol
|
||||||
|
import io.ktor.server.application.install
|
||||||
|
import io.ktor.server.application.pluginOrNull
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
import io.ktor.server.routing.application
|
||||||
|
import io.ktor.server.websocket.*
|
||||||
|
import io.ktor.websocket.send
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.serialization.SerializationStrategy
|
||||||
|
|
||||||
|
inline fun <reified T : Any> Route.includeWebsocketHandling(
|
||||||
|
suburl: String,
|
||||||
|
flow: Flow<T>,
|
||||||
|
protocol: URLProtocol? = null
|
||||||
|
) {
|
||||||
|
application.apply {
|
||||||
|
pluginOrNull(WebSockets) ?: install(WebSockets)
|
||||||
|
}
|
||||||
|
webSocket(suburl, protocol ?.name) {
|
||||||
|
safely {
|
||||||
|
flow.collect {
|
||||||
|
sendSerialized(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -4,8 +4,6 @@ import dev.inmo.micro_utils.repos.*
|
|||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
import kotlinx.coroutines.sync.Mutex
|
|
||||||
import kotlinx.coroutines.sync.withLock
|
|
||||||
|
|
||||||
open class ReadKeyValueCacheRepo<Key,Value>(
|
open class ReadKeyValueCacheRepo<Key,Value>(
|
||||||
protected val parentRepo: ReadKeyValueRepo<Key, Value>,
|
protected val parentRepo: ReadKeyValueRepo<Key, Value>,
|
||||||
|
@ -8,8 +8,6 @@ import dev.inmo.micro_utils.repos.*
|
|||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
import kotlinx.coroutines.sync.Mutex
|
|
||||||
import kotlinx.coroutines.sync.withLock
|
|
||||||
|
|
||||||
open class ReadKeyValuesCacheRepo<Key,Value>(
|
open class ReadKeyValuesCacheRepo<Key,Value>(
|
||||||
protected val parentRepo: ReadKeyValuesRepo<Key, Value>,
|
protected val parentRepo: ReadKeyValuesRepo<Key, Value>,
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
package dev.inmo.micro_utils.repos
|
package dev.inmo.micro_utils.repos
|
||||||
|
|
||||||
import dev.inmo.micro_utils.pagination.*
|
import dev.inmo.micro_utils.pagination.*
|
||||||
import dev.inmo.micro_utils.pagination.utils.doForAllWithCurrentPaging
|
|
||||||
import dev.inmo.micro_utils.pagination.utils.getAllWithNextPaging
|
import dev.inmo.micro_utils.pagination.utils.getAllWithNextPaging
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
interface ReadOneToManyKeyValueRepo<Key, Value> : Repo {
|
interface ReadKeyValuesRepo<Key, Value> : Repo {
|
||||||
suspend fun get(k: Key, pagination: Pagination, reversed: Boolean = false): PaginationResult<Value>
|
suspend fun get(k: Key, pagination: Pagination, reversed: Boolean = false): PaginationResult<Value>
|
||||||
suspend fun keys(pagination: Pagination, reversed: Boolean = false): PaginationResult<Key>
|
suspend fun keys(pagination: Pagination, reversed: Boolean = false): PaginationResult<Key>
|
||||||
suspend fun keys(v: Value, pagination: Pagination, reversed: Boolean = false): PaginationResult<Key>
|
suspend fun keys(v: Value, pagination: Pagination, reversed: Boolean = false): PaginationResult<Key>
|
||||||
@ -36,9 +35,9 @@ interface ReadOneToManyKeyValueRepo<Key, Value> : Repo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
typealias ReadKeyValuesRepo<Key,Value> = ReadOneToManyKeyValueRepo<Key, Value>
|
typealias ReadOneToManyKeyValueRepo<Key,Value> = ReadKeyValuesRepo<Key, Value>
|
||||||
|
|
||||||
interface WriteOneToManyKeyValueRepo<Key, Value> : Repo {
|
interface WriteKeyValuesRepo<Key, Value> : Repo {
|
||||||
val onNewValue: Flow<Pair<Key, Value>>
|
val onNewValue: Flow<Pair<Key, Value>>
|
||||||
val onValueRemoved: Flow<Pair<Key, Value>>
|
val onValueRemoved: Flow<Pair<Key, Value>>
|
||||||
val onDataCleared: Flow<Key>
|
val onDataCleared: Flow<Key>
|
||||||
@ -55,41 +54,41 @@ interface WriteOneToManyKeyValueRepo<Key, Value> : Repo {
|
|||||||
add(toSet)
|
add(toSet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
typealias WriteKeyValuesRepo<Key,Value> = WriteOneToManyKeyValueRepo<Key, Value>
|
typealias WriteOneToManyKeyValueRepo<Key,Value> = WriteKeyValuesRepo<Key, Value>
|
||||||
|
|
||||||
suspend inline fun <Key, Value, REPO : WriteOneToManyKeyValueRepo<Key, Value>> REPO.add(
|
suspend inline fun <Key, Value, REPO : WriteKeyValuesRepo<Key, Value>> REPO.add(
|
||||||
keysAndValues: List<Pair<Key, List<Value>>>
|
keysAndValues: List<Pair<Key, List<Value>>>
|
||||||
) = add(keysAndValues.toMap())
|
) = add(keysAndValues.toMap())
|
||||||
|
|
||||||
suspend inline fun <Key, Value, REPO : WriteOneToManyKeyValueRepo<Key, Value>> REPO.add(
|
suspend inline fun <Key, Value, REPO : WriteKeyValuesRepo<Key, Value>> REPO.add(
|
||||||
vararg keysAndValues: Pair<Key, List<Value>>
|
vararg keysAndValues: Pair<Key, List<Value>>
|
||||||
) = add(keysAndValues.toMap())
|
) = add(keysAndValues.toMap())
|
||||||
|
|
||||||
suspend inline fun <Key, Value> WriteOneToManyKeyValueRepo<Key, Value>.add(
|
suspend inline fun <Key, Value> WriteKeyValuesRepo<Key, Value>.add(
|
||||||
k: Key, v: List<Value>
|
k: Key, v: List<Value>
|
||||||
) = add(mapOf(k to v))
|
) = add(mapOf(k to v))
|
||||||
|
|
||||||
suspend inline fun <Key, Value> WriteOneToManyKeyValueRepo<Key, Value>.add(
|
suspend inline fun <Key, Value> WriteKeyValuesRepo<Key, Value>.add(
|
||||||
k: Key, vararg v: Value
|
k: Key, vararg v: Value
|
||||||
) = add(k, v.toList())
|
) = add(k, v.toList())
|
||||||
|
|
||||||
suspend inline fun <Key, Value, REPO : WriteOneToManyKeyValueRepo<Key, Value>> REPO.set(
|
suspend inline fun <Key, Value, REPO : WriteKeyValuesRepo<Key, Value>> REPO.set(
|
||||||
keysAndValues: List<Pair<Key, List<Value>>>
|
keysAndValues: List<Pair<Key, List<Value>>>
|
||||||
) = set(keysAndValues.toMap())
|
) = set(keysAndValues.toMap())
|
||||||
|
|
||||||
suspend inline fun <Key, Value, REPO : WriteOneToManyKeyValueRepo<Key, Value>> REPO.set(
|
suspend inline fun <Key, Value, REPO : WriteKeyValuesRepo<Key, Value>> REPO.set(
|
||||||
vararg keysAndValues: Pair<Key, List<Value>>
|
vararg keysAndValues: Pair<Key, List<Value>>
|
||||||
) = set(keysAndValues.toMap())
|
) = set(keysAndValues.toMap())
|
||||||
|
|
||||||
suspend inline fun <Key, Value> WriteOneToManyKeyValueRepo<Key, Value>.set(
|
suspend inline fun <Key, Value> WriteKeyValuesRepo<Key, Value>.set(
|
||||||
k: Key, v: List<Value>
|
k: Key, v: List<Value>
|
||||||
) = set(mapOf(k to v))
|
) = set(mapOf(k to v))
|
||||||
|
|
||||||
suspend inline fun <Key, Value> WriteOneToManyKeyValueRepo<Key, Value>.set(
|
suspend inline fun <Key, Value> WriteKeyValuesRepo<Key, Value>.set(
|
||||||
k: Key, vararg v: Value
|
k: Key, vararg v: Value
|
||||||
) = set(k, v.toList())
|
) = set(k, v.toList())
|
||||||
|
|
||||||
interface OneToManyKeyValueRepo<Key, Value> : ReadOneToManyKeyValueRepo<Key, Value>, WriteOneToManyKeyValueRepo<Key, Value> {
|
interface KeyValuesRepo<Key, Value> : ReadKeyValuesRepo<Key, Value>, WriteKeyValuesRepo<Key, Value> {
|
||||||
override suspend fun clearWithValue(v: Value) {
|
override suspend fun clearWithValue(v: Value) {
|
||||||
doWithPagination {
|
doWithPagination {
|
||||||
val keysResult = keys(v, it)
|
val keysResult = keys(v, it)
|
||||||
@ -102,22 +101,29 @@ interface OneToManyKeyValueRepo<Key, Value> : ReadOneToManyKeyValueRepo<Key, Val
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
typealias KeyValuesRepo<Key,Value> = OneToManyKeyValueRepo<Key, Value>
|
typealias OneToManyKeyValueRepo<Key,Value> = KeyValuesRepo<Key, Value>
|
||||||
|
|
||||||
suspend inline fun <Key, Value> WriteOneToManyKeyValueRepo<Key, Value>.remove(
|
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
|
||||||
|
|
||||||
|
suspend inline fun <Key, Value> WriteKeyValuesRepo<Key, Value>.remove(
|
||||||
keysAndValues: List<Pair<Key, List<Value>>>
|
keysAndValues: List<Pair<Key, List<Value>>>
|
||||||
) = remove(keysAndValues.toMap())
|
) = remove(keysAndValues.toMap())
|
||||||
|
|
||||||
suspend inline fun <Key, Value> WriteOneToManyKeyValueRepo<Key, Value>.remove(
|
suspend inline fun <Key, Value> WriteKeyValuesRepo<Key, Value>.remove(
|
||||||
vararg keysAndValues: Pair<Key, List<Value>>
|
vararg keysAndValues: Pair<Key, List<Value>>
|
||||||
) = remove(keysAndValues.toMap())
|
) = remove(keysAndValues.toMap())
|
||||||
|
|
||||||
suspend inline fun <Key, Value> WriteOneToManyKeyValueRepo<Key, Value>.remove(
|
suspend inline fun <Key, Value> WriteKeyValuesRepo<Key, Value>.remove(
|
||||||
k: Key,
|
k: Key,
|
||||||
v: List<Value>
|
v: List<Value>
|
||||||
) = remove(mapOf(k to v))
|
) = remove(mapOf(k to v))
|
||||||
|
|
||||||
suspend inline fun <Key, Value> WriteOneToManyKeyValueRepo<Key, Value>.remove(
|
suspend inline fun <Key, Value> WriteKeyValuesRepo<Key, Value>.remove(
|
||||||
k: Key,
|
k: Key,
|
||||||
vararg v: Value
|
vararg v: Value
|
||||||
) = remove(k, v.toList())
|
) = remove(k, v.toList())
|
@ -4,13 +4,13 @@ import dev.inmo.micro_utils.pagination.Pagination
|
|||||||
import dev.inmo.micro_utils.pagination.PaginationResult
|
import dev.inmo.micro_utils.pagination.PaginationResult
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
interface ReadStandardCRUDRepo<ObjectType, IdType> : Repo {
|
interface ReadCRUDRepo<ObjectType, IdType> : Repo {
|
||||||
suspend fun getByPagination(pagination: Pagination): PaginationResult<ObjectType>
|
suspend fun getByPagination(pagination: Pagination): PaginationResult<ObjectType>
|
||||||
suspend fun getById(id: IdType): ObjectType?
|
suspend fun getById(id: IdType): ObjectType?
|
||||||
suspend fun contains(id: IdType): Boolean
|
suspend fun contains(id: IdType): Boolean
|
||||||
suspend fun count(): Long
|
suspend fun count(): Long
|
||||||
}
|
}
|
||||||
typealias ReadCRUDRepo<ObjectType, IdType> = ReadStandardCRUDRepo<ObjectType, IdType>
|
typealias ReadStandardCRUDRepo<ObjectType, IdType> = ReadCRUDRepo<ObjectType, IdType>
|
||||||
|
|
||||||
typealias UpdatedValuePair<IdType, ValueType> = Pair<IdType, ValueType>
|
typealias UpdatedValuePair<IdType, ValueType> = Pair<IdType, ValueType>
|
||||||
val <IdType> UpdatedValuePair<IdType, *>.id
|
val <IdType> UpdatedValuePair<IdType, *>.id
|
||||||
@ -18,7 +18,7 @@ val <IdType> UpdatedValuePair<IdType, *>.id
|
|||||||
val <ValueType> UpdatedValuePair<*, ValueType>.value
|
val <ValueType> UpdatedValuePair<*, ValueType>.value
|
||||||
get() = second
|
get() = second
|
||||||
|
|
||||||
interface WriteStandardCRUDRepo<ObjectType, IdType, InputValueType> : Repo {
|
interface WriteCRUDRepo<ObjectType, IdType, InputValueType> : Repo {
|
||||||
val newObjectsFlow: Flow<ObjectType>
|
val newObjectsFlow: Flow<ObjectType>
|
||||||
val updatedObjectsFlow: Flow<ObjectType>
|
val updatedObjectsFlow: Flow<ObjectType>
|
||||||
val deletedObjectsIdsFlow: Flow<IdType>
|
val deletedObjectsIdsFlow: Flow<IdType>
|
||||||
@ -28,18 +28,25 @@ interface WriteStandardCRUDRepo<ObjectType, IdType, InputValueType> : Repo {
|
|||||||
suspend fun update(values: List<UpdatedValuePair<IdType, InputValueType>>): List<ObjectType>
|
suspend fun update(values: List<UpdatedValuePair<IdType, InputValueType>>): List<ObjectType>
|
||||||
suspend fun deleteById(ids: List<IdType>)
|
suspend fun deleteById(ids: List<IdType>)
|
||||||
}
|
}
|
||||||
typealias WriteCRUDRepo<ObjectType, IdType, InputValueType> = WriteStandardCRUDRepo<ObjectType, IdType, InputValueType>
|
typealias WriteStandardCRUDRepo<ObjectType, IdType, InputValueType> = WriteCRUDRepo<ObjectType, IdType, InputValueType>
|
||||||
|
|
||||||
suspend fun <ObjectType, IdType, InputValueType> WriteStandardCRUDRepo<ObjectType, IdType, InputValueType>.create(
|
suspend fun <ObjectType, IdType, InputValueType> WriteCRUDRepo<ObjectType, IdType, InputValueType>.create(
|
||||||
vararg values: InputValueType
|
vararg values: InputValueType
|
||||||
): List<ObjectType> = create(values.toList())
|
): List<ObjectType> = create(values.toList())
|
||||||
suspend fun <ObjectType, IdType, InputValueType> WriteStandardCRUDRepo<ObjectType, IdType, InputValueType>.update(
|
suspend fun <ObjectType, IdType, InputValueType> WriteCRUDRepo<ObjectType, IdType, InputValueType>.update(
|
||||||
vararg values: UpdatedValuePair<IdType, InputValueType>
|
vararg values: UpdatedValuePair<IdType, InputValueType>
|
||||||
): List<ObjectType> = update(values.toList())
|
): List<ObjectType> = update(values.toList())
|
||||||
suspend fun <ObjectType, IdType, InputValueType> WriteStandardCRUDRepo<ObjectType, IdType, InputValueType>.deleteById(
|
suspend fun <ObjectType, IdType, InputValueType> WriteCRUDRepo<ObjectType, IdType, InputValueType>.deleteById(
|
||||||
vararg ids: IdType
|
vararg ids: IdType
|
||||||
) = deleteById(ids.toList())
|
) = deleteById(ids.toList())
|
||||||
|
|
||||||
interface StandardCRUDRepo<ObjectType, IdType, InputValueType> : ReadStandardCRUDRepo<ObjectType, IdType>,
|
interface CRUDRepo<ObjectType, IdType, InputValueType> : ReadCRUDRepo<ObjectType, IdType>,
|
||||||
WriteStandardCRUDRepo<ObjectType, IdType, InputValueType>
|
WriteCRUDRepo<ObjectType, IdType, InputValueType>
|
||||||
typealias CRUDRepo<ObjectType, IdType, InputValueType> = StandardCRUDRepo<ObjectType, IdType, InputValueType>
|
typealias StandardCRUDRepo<ObjectType, IdType, InputValueType> = CRUDRepo<ObjectType, IdType, InputValueType>
|
||||||
|
|
||||||
|
class DelegateBasedCRUDRepo<ObjectType, IdType, InputValueType>(
|
||||||
|
readDelegate: ReadCRUDRepo<ObjectType, IdType>,
|
||||||
|
writeDelegate: WriteCRUDRepo<ObjectType, IdType, InputValueType>
|
||||||
|
) : CRUDRepo<ObjectType, IdType, InputValueType>,
|
||||||
|
ReadCRUDRepo<ObjectType, IdType> by readDelegate,
|
||||||
|
WriteCRUDRepo<ObjectType, IdType, InputValueType> by writeDelegate
|
||||||
|
@ -4,7 +4,7 @@ import dev.inmo.micro_utils.pagination.*
|
|||||||
import dev.inmo.micro_utils.pagination.utils.doAllWithCurrentPaging
|
import dev.inmo.micro_utils.pagination.utils.doAllWithCurrentPaging
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
interface ReadStandardKeyValueRepo<Key, Value> : Repo {
|
interface ReadKeyValueRepo<Key, Value> : Repo {
|
||||||
suspend fun get(k: Key): Value?
|
suspend fun get(k: Key): Value?
|
||||||
suspend fun values(pagination: Pagination, reversed: Boolean = false): PaginationResult<Value>
|
suspend fun values(pagination: Pagination, reversed: Boolean = false): PaginationResult<Value>
|
||||||
suspend fun keys(pagination: Pagination, reversed: Boolean = false): PaginationResult<Key>
|
suspend fun keys(pagination: Pagination, reversed: Boolean = false): PaginationResult<Key>
|
||||||
@ -12,9 +12,9 @@ interface ReadStandardKeyValueRepo<Key, Value> : Repo {
|
|||||||
suspend fun contains(key: Key): Boolean
|
suspend fun contains(key: Key): Boolean
|
||||||
suspend fun count(): Long
|
suspend fun count(): Long
|
||||||
}
|
}
|
||||||
typealias ReadKeyValueRepo<Key,Value> = ReadStandardKeyValueRepo<Key, Value>
|
typealias ReadStandardKeyValueRepo<Key,Value> = ReadKeyValueRepo<Key, Value>
|
||||||
|
|
||||||
interface WriteStandardKeyValueRepo<Key, Value> : Repo {
|
interface WriteKeyValueRepo<Key, Value> : Repo {
|
||||||
val onNewValue: Flow<Pair<Key, Value>>
|
val onNewValue: Flow<Pair<Key, Value>>
|
||||||
val onValueRemoved: Flow<Key>
|
val onValueRemoved: Flow<Key>
|
||||||
|
|
||||||
@ -22,25 +22,25 @@ interface WriteStandardKeyValueRepo<Key, Value> : Repo {
|
|||||||
suspend fun unset(toUnset: List<Key>)
|
suspend fun unset(toUnset: List<Key>)
|
||||||
suspend fun unsetWithValues(toUnset: List<Value>)
|
suspend fun unsetWithValues(toUnset: List<Value>)
|
||||||
}
|
}
|
||||||
typealias WriteKeyValueRepo<Key,Value> = WriteStandardKeyValueRepo<Key, Value>
|
typealias WriteStandardKeyValueRepo<Key,Value> = WriteKeyValueRepo<Key, Value>
|
||||||
|
|
||||||
suspend inline fun <Key, Value> WriteStandardKeyValueRepo<Key, Value>.set(
|
suspend inline fun <Key, Value> WriteKeyValueRepo<Key, Value>.set(
|
||||||
vararg toSet: Pair<Key, Value>
|
vararg toSet: Pair<Key, Value>
|
||||||
) = set(toSet.toMap())
|
) = set(toSet.toMap())
|
||||||
|
|
||||||
suspend inline fun <Key, Value> WriteStandardKeyValueRepo<Key, Value>.set(
|
suspend inline fun <Key, Value> WriteKeyValueRepo<Key, Value>.set(
|
||||||
k: Key, v: Value
|
k: Key, v: Value
|
||||||
) = set(k to v)
|
) = set(k to v)
|
||||||
|
|
||||||
suspend inline fun <Key, Value> WriteStandardKeyValueRepo<Key, Value>.unset(
|
suspend inline fun <Key, Value> WriteKeyValueRepo<Key, Value>.unset(
|
||||||
vararg k: Key
|
vararg k: Key
|
||||||
) = unset(k.toList())
|
) = unset(k.toList())
|
||||||
|
|
||||||
suspend inline fun <Key, Value> WriteStandardKeyValueRepo<Key, Value>.unsetWithValues(
|
suspend inline fun <Key, Value> WriteKeyValueRepo<Key, Value>.unsetWithValues(
|
||||||
vararg v: Value
|
vararg v: Value
|
||||||
) = unsetWithValues(v.toList())
|
) = unsetWithValues(v.toList())
|
||||||
|
|
||||||
interface StandardKeyValueRepo<Key, Value> : ReadStandardKeyValueRepo<Key, Value>, WriteStandardKeyValueRepo<Key, Value> {
|
interface KeyValueRepo<Key, Value> : ReadKeyValueRepo<Key, Value>, WriteKeyValueRepo<Key, Value> {
|
||||||
override suspend fun unsetWithValues(toUnset: List<Value>) = toUnset.forEach { v ->
|
override suspend fun unsetWithValues(toUnset: List<Value>) = toUnset.forEach { v ->
|
||||||
doAllWithCurrentPaging {
|
doAllWithCurrentPaging {
|
||||||
keys(v, it).also {
|
keys(v, it).also {
|
||||||
@ -49,4 +49,11 @@ interface StandardKeyValueRepo<Key, Value> : ReadStandardKeyValueRepo<Key, Value
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
typealias KeyValueRepo<Key,Value> = StandardKeyValueRepo<Key, Value>
|
typealias StandardKeyValueRepo<Key,Value> = KeyValueRepo<Key, Value>
|
||||||
|
|
||||||
|
class DelegateBasedKeyValueRepo<Key, Value>(
|
||||||
|
readDelegate: ReadKeyValueRepo<Key, Value>,
|
||||||
|
writeDelegate: WriteKeyValueRepo<Key, Value>
|
||||||
|
) : KeyValueRepo<Key, Value>,
|
||||||
|
ReadKeyValueRepo<Key, Value> by readDelegate,
|
||||||
|
WriteKeyValueRepo<Key, Value> by writeDelegate
|
||||||
|
@ -6,10 +6,12 @@ import dev.inmo.micro_utils.repos.*
|
|||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
|
|
||||||
open class MapperReadStandardKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
|
@Deprecated("Renamed", ReplaceWith("MapperReadKeyValueRepo", "dev.inmo.micro_utils.repos.mappers.MapperReadKeyValueRepo"))
|
||||||
private val to: ReadStandardKeyValueRepo<ToKey, ToValue>,
|
typealias MapperReadStandardKeyValueRepo<FromKey, FromValue, ToKey, ToValue> = MapperReadKeyValueRepo<FromKey, FromValue, ToKey, ToValue>
|
||||||
|
open class MapperReadKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
|
||||||
|
private val to: ReadKeyValueRepo<ToKey, ToValue>,
|
||||||
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
||||||
) : ReadStandardKeyValueRepo<FromKey, FromValue>, MapperRepo<FromKey, FromValue, ToKey, ToValue> by mapper {
|
) : ReadKeyValueRepo<FromKey, FromValue>, MapperRepo<FromKey, FromValue, ToKey, ToValue> by mapper {
|
||||||
override suspend fun get(k: FromKey): FromValue? = to.get(
|
override suspend fun get(k: FromKey): FromValue? = to.get(
|
||||||
k.toOutKey()
|
k.toOutKey()
|
||||||
) ?.toInnerValue()
|
) ?.toInnerValue()
|
||||||
@ -69,24 +71,26 @@ open class MapperReadStandardKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
inline fun <FromKey, FromValue, ToKey, ToValue> ReadStandardKeyValueRepo<ToKey, ToValue>.withMapper(
|
inline fun <FromKey, FromValue, ToKey, ToValue> ReadKeyValueRepo<ToKey, ToValue>.withMapper(
|
||||||
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
||||||
): ReadStandardKeyValueRepo<FromKey, FromValue> = MapperReadStandardKeyValueRepo(this, mapper)
|
): ReadKeyValueRepo<FromKey, FromValue> = MapperReadKeyValueRepo(this, mapper)
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> ReadStandardKeyValueRepo<ToKey, ToValue>.withMapper(
|
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> ReadKeyValueRepo<ToKey, ToValue>.withMapper(
|
||||||
crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
||||||
crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
|
crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
|
||||||
crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
|
crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
|
||||||
crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
|
crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
|
||||||
): ReadStandardKeyValueRepo<FromKey, FromValue> = withMapper(
|
): ReadKeyValueRepo<FromKey, FromValue> = withMapper(
|
||||||
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
|
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
|
||||||
)
|
)
|
||||||
|
|
||||||
open class MapperWriteStandardKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
|
@Deprecated("Renamed", ReplaceWith("MapperWriteKeyValueRepo", "dev.inmo.micro_utils.repos.mappers.MapperWriteKeyValueRepo"))
|
||||||
private val to: WriteStandardKeyValueRepo<ToKey, ToValue>,
|
typealias MapperWriteStandardKeyValueRepo<FromKey, FromValue, ToKey, ToValue> = MapperWriteKeyValueRepo<FromKey, FromValue, ToKey, ToValue>
|
||||||
|
open class MapperWriteKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
|
||||||
|
private val to: WriteKeyValueRepo<ToKey, ToValue>,
|
||||||
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
||||||
) : WriteStandardKeyValueRepo<FromKey, FromValue>, MapperRepo<FromKey, FromValue, ToKey, ToValue> by mapper {
|
) : WriteKeyValueRepo<FromKey, FromValue>, MapperRepo<FromKey, FromValue, ToKey, ToValue> by mapper {
|
||||||
override val onNewValue: Flow<Pair<FromKey, FromValue>> = to.onNewValue.map { (k, v) ->
|
override val onNewValue: Flow<Pair<FromKey, FromValue>> = to.onNewValue.map { (k, v) ->
|
||||||
k.toInnerKey() to v.toInnerValue()
|
k.toInnerKey() to v.toInnerValue()
|
||||||
}
|
}
|
||||||
@ -112,40 +116,42 @@ open class MapperWriteStandardKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
inline fun <FromKey, FromValue, ToKey, ToValue> WriteStandardKeyValueRepo<ToKey, ToValue>.withMapper(
|
inline fun <FromKey, FromValue, ToKey, ToValue> WriteKeyValueRepo<ToKey, ToValue>.withMapper(
|
||||||
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
||||||
): WriteStandardKeyValueRepo<FromKey, FromValue> = MapperWriteStandardKeyValueRepo(this, mapper)
|
): WriteKeyValueRepo<FromKey, FromValue> = MapperWriteKeyValueRepo(this, mapper)
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> WriteStandardKeyValueRepo<ToKey, ToValue>.withMapper(
|
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> WriteKeyValueRepo<ToKey, ToValue>.withMapper(
|
||||||
crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
||||||
crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
|
crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
|
||||||
crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
|
crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
|
||||||
crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
|
crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
|
||||||
): WriteStandardKeyValueRepo<FromKey, FromValue> = withMapper(
|
): WriteKeyValueRepo<FromKey, FromValue> = withMapper(
|
||||||
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
|
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Deprecated("Renamed", ReplaceWith("MapperKeyValueRepo", "dev.inmo.micro_utils.repos.mappers.MapperKeyValueRepo"))
|
||||||
|
typealias MapperStandardKeyValueRepo<FromKey, FromValue, ToKey, ToValue> = MapperKeyValueRepo<FromKey, FromValue, ToKey, ToValue>
|
||||||
@Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE")
|
@Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE")
|
||||||
open class MapperStandardKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
|
open class MapperKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
|
||||||
private val to: StandardKeyValueRepo<ToKey, ToValue>,
|
private val to: KeyValueRepo<ToKey, ToValue>,
|
||||||
private val mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
private val mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
||||||
) : StandardKeyValueRepo<FromKey, FromValue>,
|
) : KeyValueRepo<FromKey, FromValue>,
|
||||||
MapperRepo<FromKey, FromValue, ToKey, ToValue> by mapper,
|
MapperRepo<FromKey, FromValue, ToKey, ToValue> by mapper,
|
||||||
ReadStandardKeyValueRepo<FromKey, FromValue> by MapperReadStandardKeyValueRepo(to, mapper),
|
ReadKeyValueRepo<FromKey, FromValue> by MapperReadKeyValueRepo(to, mapper),
|
||||||
WriteStandardKeyValueRepo<FromKey, FromValue> by MapperWriteStandardKeyValueRepo(to, mapper)
|
WriteKeyValueRepo<FromKey, FromValue> by MapperWriteKeyValueRepo(to, mapper)
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
inline fun <FromKey, FromValue, ToKey, ToValue> StandardKeyValueRepo<ToKey, ToValue>.withMapper(
|
inline fun <FromKey, FromValue, ToKey, ToValue> KeyValueRepo<ToKey, ToValue>.withMapper(
|
||||||
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
||||||
): StandardKeyValueRepo<FromKey, FromValue> = MapperStandardKeyValueRepo(this, mapper)
|
): KeyValueRepo<FromKey, FromValue> = MapperKeyValueRepo(this, mapper)
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> StandardKeyValueRepo<ToKey, ToValue>.withMapper(
|
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> KeyValueRepo<ToKey, ToValue>.withMapper(
|
||||||
crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
||||||
crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
|
crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
|
||||||
crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
|
crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
|
||||||
crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
|
crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
|
||||||
): StandardKeyValueRepo<FromKey, FromValue> = withMapper(
|
): KeyValueRepo<FromKey, FromValue> = withMapper(
|
||||||
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
|
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
|
||||||
)
|
)
|
||||||
|
@ -6,10 +6,12 @@ import dev.inmo.micro_utils.repos.*
|
|||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
|
|
||||||
open class MapperReadOneToManyKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
|
@Deprecated("Renamed", ReplaceWith("MapperReadKeyValuesRepo", "dev.inmo.micro_utils.repos.mappers.MapperReadKeyValuesRepo"))
|
||||||
private val to: ReadOneToManyKeyValueRepo<ToKey, ToValue>,
|
typealias MapperReadOneToManyKeyValueRepo<FromKey, FromValue, ToKey, ToValue> = MapperReadKeyValuesRepo<FromKey, FromValue, ToKey, ToValue>
|
||||||
|
open class MapperReadKeyValuesRepo<FromKey, FromValue, ToKey, ToValue>(
|
||||||
|
private val to: ReadKeyValuesRepo<ToKey, ToValue>,
|
||||||
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
||||||
) : ReadOneToManyKeyValueRepo<FromKey, FromValue>, MapperRepo<FromKey, FromValue, ToKey, ToValue> by mapper {
|
) : ReadKeyValuesRepo<FromKey, FromValue>, MapperRepo<FromKey, FromValue, ToKey, ToValue> by mapper {
|
||||||
override suspend fun get(
|
override suspend fun get(
|
||||||
k: FromKey,
|
k: FromKey,
|
||||||
pagination: Pagination,
|
pagination: Pagination,
|
||||||
@ -67,24 +69,26 @@ open class MapperReadOneToManyKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
inline fun <FromKey, FromValue, ToKey, ToValue> ReadOneToManyKeyValueRepo<ToKey, ToValue>.withMapper(
|
inline fun <FromKey, FromValue, ToKey, ToValue> ReadKeyValuesRepo<ToKey, ToValue>.withMapper(
|
||||||
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
||||||
): ReadOneToManyKeyValueRepo<FromKey, FromValue> = MapperReadOneToManyKeyValueRepo(this, mapper)
|
): ReadKeyValuesRepo<FromKey, FromValue> = MapperReadKeyValuesRepo(this, mapper)
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> ReadOneToManyKeyValueRepo<ToKey, ToValue>.withMapper(
|
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> ReadKeyValuesRepo<ToKey, ToValue>.withMapper(
|
||||||
crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
||||||
crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
|
crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
|
||||||
crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
|
crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
|
||||||
crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
|
crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
|
||||||
): ReadOneToManyKeyValueRepo<FromKey, FromValue> = withMapper(
|
): ReadKeyValuesRepo<FromKey, FromValue> = withMapper(
|
||||||
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
|
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
|
||||||
)
|
)
|
||||||
|
|
||||||
open class MapperWriteOneToManyKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
|
@Deprecated("Renamed", ReplaceWith("MapperWriteKeyValuesRepo", "dev.inmo.micro_utils.repos.mappers.MapperWriteKeyValuesRepo"))
|
||||||
private val to: WriteOneToManyKeyValueRepo<ToKey, ToValue>,
|
typealias MapperWriteOneToManyKeyValueRepo<FromKey, FromValue, ToKey, ToValue> = MapperWriteKeyValuesRepo<FromKey, FromValue, ToKey, ToValue>
|
||||||
|
open class MapperWriteKeyValuesRepo<FromKey, FromValue, ToKey, ToValue>(
|
||||||
|
private val to: WriteKeyValuesRepo<ToKey, ToValue>,
|
||||||
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
||||||
) : WriteOneToManyKeyValueRepo<FromKey, FromValue>, MapperRepo<FromKey, FromValue, ToKey, ToValue> by mapper {
|
) : WriteKeyValuesRepo<FromKey, FromValue>, MapperRepo<FromKey, FromValue, ToKey, ToValue> by mapper {
|
||||||
override val onNewValue: Flow<Pair<FromKey, FromValue>> = to.onNewValue.map { (k, v) ->
|
override val onNewValue: Flow<Pair<FromKey, FromValue>> = to.onNewValue.map { (k, v) ->
|
||||||
k.toInnerKey() to v.toInnerValue()
|
k.toInnerKey() to v.toInnerValue()
|
||||||
}
|
}
|
||||||
@ -118,40 +122,42 @@ open class MapperWriteOneToManyKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
inline fun <FromKey, FromValue, ToKey, ToValue> WriteOneToManyKeyValueRepo<ToKey, ToValue>.withMapper(
|
inline fun <FromKey, FromValue, ToKey, ToValue> WriteKeyValuesRepo<ToKey, ToValue>.withMapper(
|
||||||
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
||||||
): WriteOneToManyKeyValueRepo<FromKey, FromValue> = MapperWriteOneToManyKeyValueRepo(this, mapper)
|
): WriteKeyValuesRepo<FromKey, FromValue> = MapperWriteKeyValuesRepo(this, mapper)
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> WriteOneToManyKeyValueRepo<ToKey, ToValue>.withMapper(
|
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> WriteKeyValuesRepo<ToKey, ToValue>.withMapper(
|
||||||
crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
||||||
crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
|
crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
|
||||||
crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
|
crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
|
||||||
crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
|
crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
|
||||||
): WriteOneToManyKeyValueRepo<FromKey, FromValue> = withMapper(
|
): WriteKeyValuesRepo<FromKey, FromValue> = withMapper(
|
||||||
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
|
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Deprecated("Renamed", ReplaceWith("MapperKeyValuesRepo", "dev.inmo.micro_utils.repos.mappers.MapperKeyValuesRepo"))
|
||||||
|
typealias MapperOneToManyKeyValueRepo<FromKey, FromValue, ToKey, ToValue> = MapperKeyValuesRepo<FromKey, FromValue, ToKey, ToValue>
|
||||||
@Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE")
|
@Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE")
|
||||||
open class MapperOneToManyKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
|
open class MapperKeyValuesRepo<FromKey, FromValue, ToKey, ToValue>(
|
||||||
private val to: OneToManyKeyValueRepo<ToKey, ToValue>,
|
private val to: KeyValuesRepo<ToKey, ToValue>,
|
||||||
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
||||||
) : OneToManyKeyValueRepo<FromKey, FromValue>,
|
) : KeyValuesRepo<FromKey, FromValue>,
|
||||||
MapperRepo<FromKey, FromValue, ToKey, ToValue> by mapper,
|
MapperRepo<FromKey, FromValue, ToKey, ToValue> by mapper,
|
||||||
ReadOneToManyKeyValueRepo<FromKey, FromValue> by MapperReadOneToManyKeyValueRepo(to, mapper),
|
ReadKeyValuesRepo<FromKey, FromValue> by MapperReadKeyValuesRepo(to, mapper),
|
||||||
WriteOneToManyKeyValueRepo<FromKey, FromValue> by MapperWriteOneToManyKeyValueRepo(to, mapper)
|
WriteKeyValuesRepo<FromKey, FromValue> by MapperWriteKeyValuesRepo(to, mapper)
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
inline fun <FromKey, FromValue, ToKey, ToValue> OneToManyKeyValueRepo<ToKey, ToValue>.withMapper(
|
inline fun <FromKey, FromValue, ToKey, ToValue> KeyValuesRepo<ToKey, ToValue>.withMapper(
|
||||||
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
||||||
): OneToManyKeyValueRepo<FromKey, FromValue> = MapperOneToManyKeyValueRepo(this, mapper)
|
): KeyValuesRepo<FromKey, FromValue> = MapperKeyValuesRepo(this, mapper)
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> OneToManyKeyValueRepo<ToKey, ToValue>.withMapper(
|
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> KeyValuesRepo<ToKey, ToValue>.withMapper(
|
||||||
crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
||||||
crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
|
crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
|
||||||
crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
|
crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
|
||||||
crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
|
crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
|
||||||
): OneToManyKeyValueRepo<FromKey, FromValue> = withMapper(
|
): KeyValuesRepo<FromKey, FromValue> = withMapper(
|
||||||
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
|
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
|
||||||
)
|
)
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
package dev.inmo.micro_utils.repos.pagination
|
package dev.inmo.micro_utils.repos.pagination
|
||||||
|
|
||||||
import dev.inmo.micro_utils.pagination.*
|
import dev.inmo.micro_utils.pagination.*
|
||||||
import dev.inmo.micro_utils.pagination.utils.doForAllWithNextPaging
|
|
||||||
import dev.inmo.micro_utils.pagination.utils.getAllWithNextPaging
|
import dev.inmo.micro_utils.pagination.utils.getAllWithNextPaging
|
||||||
import dev.inmo.micro_utils.repos.ReadStandardCRUDRepo
|
import dev.inmo.micro_utils.repos.ReadCRUDRepo
|
||||||
|
|
||||||
suspend inline fun <T, ID, REPO : ReadStandardCRUDRepo<T, ID>> REPO.getAll(
|
suspend inline fun <T, ID, REPO : ReadCRUDRepo<T, ID>> REPO.getAll(
|
||||||
@Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE")
|
@Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE")
|
||||||
crossinline methodCaller: suspend REPO.(Pagination) -> PaginationResult<T>
|
crossinline methodCaller: suspend REPO.(Pagination) -> PaginationResult<T>
|
||||||
): List<T> = getAllWithNextPaging {
|
): List<T> = getAllWithNextPaging {
|
||||||
|
@ -2,9 +2,9 @@ package dev.inmo.micro_utils.repos.pagination
|
|||||||
|
|
||||||
import dev.inmo.micro_utils.pagination.*
|
import dev.inmo.micro_utils.pagination.*
|
||||||
import dev.inmo.micro_utils.pagination.utils.getAllWithNextPaging
|
import dev.inmo.micro_utils.pagination.utils.getAllWithNextPaging
|
||||||
import dev.inmo.micro_utils.repos.ReadStandardKeyValueRepo
|
import dev.inmo.micro_utils.repos.ReadKeyValueRepo
|
||||||
|
|
||||||
suspend inline fun <Key, Value, REPO : ReadStandardKeyValueRepo<Key, Value>> REPO.getAll(
|
suspend inline fun <Key, Value, REPO : ReadKeyValueRepo<Key, Value>> REPO.getAll(
|
||||||
@Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE")
|
@Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE")
|
||||||
crossinline methodCaller: suspend REPO.(Pagination) -> PaginationResult<Key>
|
crossinline methodCaller: suspend REPO.(Pagination) -> PaginationResult<Key>
|
||||||
): List<Pair<Key, Value>> = getAllWithNextPaging {
|
): List<Pair<Key, Value>> = getAllWithNextPaging {
|
||||||
|
@ -2,9 +2,9 @@ package dev.inmo.micro_utils.repos.pagination
|
|||||||
|
|
||||||
import dev.inmo.micro_utils.pagination.*
|
import dev.inmo.micro_utils.pagination.*
|
||||||
import dev.inmo.micro_utils.pagination.utils.getAllWithNextPaging
|
import dev.inmo.micro_utils.pagination.utils.getAllWithNextPaging
|
||||||
import dev.inmo.micro_utils.repos.ReadOneToManyKeyValueRepo
|
import dev.inmo.micro_utils.repos.ReadKeyValuesRepo
|
||||||
|
|
||||||
suspend inline fun <Key, Value, REPO : ReadOneToManyKeyValueRepo<Key, Value>> REPO.getAll(
|
suspend inline fun <Key, Value, REPO : ReadKeyValuesRepo<Key, Value>> REPO.getAll(
|
||||||
@Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE")
|
@Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE")
|
||||||
crossinline methodCaller: suspend REPO.(Pagination) -> PaginationResult<Key>
|
crossinline methodCaller: suspend REPO.(Pagination) -> PaginationResult<Key>
|
||||||
): List<Pair<Key, List<Value>>> = getAllWithNextPaging {
|
): List<Pair<Key, List<Value>>> = getAllWithNextPaging {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package dev.inmo.micro_utils.repos.versions
|
package dev.inmo.micro_utils.repos.versions
|
||||||
|
|
||||||
import dev.inmo.micro_utils.repos.StandardKeyValueRepo
|
import dev.inmo.micro_utils.repos.KeyValueRepo
|
||||||
import dev.inmo.micro_utils.repos.set
|
import dev.inmo.micro_utils.repos.set
|
||||||
|
|
||||||
class KeyValueBasedVersionsRepoProxy<T>(
|
class KeyValueBasedVersionsRepoProxy<T>(
|
||||||
private val keyValueStore: StandardKeyValueRepo<String, Int>,
|
private val keyValueStore: KeyValueRepo<String, Int>,
|
||||||
override val database: T
|
override val database: T
|
||||||
) : StandardVersionsRepoProxy<T> {
|
) : StandardVersionsRepoProxy<T> {
|
||||||
override suspend fun getTableVersion(tableName: String): Int? = keyValueStore.get(tableName)
|
override suspend fun getTableVersion(tableName: String): Int? = keyValueStore.get(tableName)
|
||||||
|
@ -13,9 +13,12 @@ import java.nio.file.StandardWatchEventKinds.*
|
|||||||
private inline val String.isAbsolute
|
private inline val String.isAbsolute
|
||||||
get() = startsWith(File.separator)
|
get() = startsWith(File.separator)
|
||||||
|
|
||||||
class FileReadStandardKeyValueRepo(
|
@Deprecated("Renamed", ReplaceWith("FileReadKeyValueRepo", "dev.inmo.micro_utils.repos.FileReadKeyValueRepo"))
|
||||||
|
typealias FileReadStandardKeyValueRepo = FileReadKeyValueRepo
|
||||||
|
|
||||||
|
class FileReadKeyValueRepo(
|
||||||
private val folder: File
|
private val folder: File
|
||||||
) : ReadStandardKeyValueRepo<String, File> {
|
) : ReadKeyValueRepo<String, File> {
|
||||||
init {
|
init {
|
||||||
folder.mkdirs()
|
folder.mkdirs()
|
||||||
}
|
}
|
||||||
@ -79,14 +82,17 @@ class FileReadStandardKeyValueRepo(
|
|||||||
override suspend fun count(): Long = folder.list() ?.size ?.toLong() ?: 0L
|
override suspend fun count(): Long = folder.list() ?.size ?.toLong() ?: 0L
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("Renamed", ReplaceWith("FileWriteKeyValueRepo", "dev.inmo.micro_utils.repos.FileWriteKeyValueRepo"))
|
||||||
|
typealias FileWriteStandardKeyValueRepo = FileWriteKeyValueRepo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Files watching will not correctly works on Android with version of API lower than API 26
|
* Files watching will not correctly works on Android 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")
|
@Warning("Files watching will not correctly works on Android Platform with version of API lower than API 26")
|
||||||
class FileWriteStandardKeyValueRepo(
|
class FileWriteKeyValueRepo(
|
||||||
private val folder: File,
|
private val folder: File,
|
||||||
filesChangedProcessingScope: CoroutineScope? = null
|
filesChangedProcessingScope: CoroutineScope? = null
|
||||||
) : WriteStandardKeyValueRepo<String, File> {
|
) : WriteKeyValueRepo<String, File> {
|
||||||
private val _onNewValue = MutableSharedFlow<Pair<String, File>>()
|
private val _onNewValue = MutableSharedFlow<Pair<String, File>>()
|
||||||
override val onNewValue: Flow<Pair<String, File>> = _onNewValue.asSharedFlow()
|
override val onNewValue: Flow<Pair<String, File>> = _onNewValue.asSharedFlow()
|
||||||
private val _onValueRemoved = MutableSharedFlow<String>()
|
private val _onValueRemoved = MutableSharedFlow<String>()
|
||||||
@ -174,12 +180,15 @@ class FileWriteStandardKeyValueRepo(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("Renamed", ReplaceWith("FileKeyValueRepo", "dev.inmo.micro_utils.repos.FileKeyValueRepo"))
|
||||||
|
typealias FileStandardKeyValueRepo = FileKeyValueRepo
|
||||||
|
|
||||||
@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")
|
||||||
@Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE")
|
@Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE")
|
||||||
class FileStandardKeyValueRepo(
|
class FileKeyValueRepo(
|
||||||
folder: File,
|
folder: File,
|
||||||
filesChangedProcessingScope: CoroutineScope? = null
|
filesChangedProcessingScope: CoroutineScope? = null
|
||||||
) : StandardKeyValueRepo<String, File>,
|
) : KeyValueRepo<String, File>,
|
||||||
WriteStandardKeyValueRepo<String, File> by FileWriteStandardKeyValueRepo(folder, filesChangedProcessingScope),
|
WriteKeyValueRepo<String, File> by FileWriteKeyValueRepo(folder, filesChangedProcessingScope),
|
||||||
ReadStandardKeyValueRepo<String, File> by FileReadStandardKeyValueRepo(folder) {
|
ReadKeyValueRepo<String, File> by FileReadKeyValueRepo(folder) {
|
||||||
}
|
}
|
@ -12,7 +12,7 @@ val <T> T.asId: String
|
|||||||
|
|
||||||
abstract class AbstractAndroidCRUDRepo<ObjectType, IdType>(
|
abstract class AbstractAndroidCRUDRepo<ObjectType, IdType>(
|
||||||
protected val helper: StandardSQLHelper
|
protected val helper: StandardSQLHelper
|
||||||
) : ReadStandardCRUDRepo<ObjectType, IdType> {
|
) : ReadCRUDRepo<ObjectType, IdType> {
|
||||||
protected abstract val tableName: String
|
protected abstract val tableName: String
|
||||||
protected abstract val idColumnName: String
|
protected abstract val idColumnName: String
|
||||||
protected abstract suspend fun Cursor.toObject(): ObjectType
|
protected abstract suspend fun Cursor.toObject(): ObjectType
|
||||||
|
@ -9,9 +9,9 @@ abstract class AbstractMutableAndroidCRUDRepo<ObjectType, IdType, InputValueType
|
|||||||
helper: StandardSQLHelper,
|
helper: StandardSQLHelper,
|
||||||
replyInFlows: Int = 0,
|
replyInFlows: Int = 0,
|
||||||
extraBufferCapacityInFlows: Int = 64
|
extraBufferCapacityInFlows: Int = 64
|
||||||
) : WriteStandardCRUDRepo<ObjectType, IdType, InputValueType>,
|
) : WriteCRUDRepo<ObjectType, IdType, InputValueType>,
|
||||||
AbstractAndroidCRUDRepo<ObjectType, IdType>(helper),
|
AbstractAndroidCRUDRepo<ObjectType, IdType>(helper),
|
||||||
StandardCRUDRepo<ObjectType, IdType, InputValueType> {
|
CRUDRepo<ObjectType, IdType, InputValueType> {
|
||||||
protected val newObjectsChannel = MutableSharedFlow<ObjectType>(replyInFlows, extraBufferCapacityInFlows)
|
protected val newObjectsChannel = MutableSharedFlow<ObjectType>(replyInFlows, extraBufferCapacityInFlows)
|
||||||
protected val updateObjectsChannel = MutableSharedFlow<ObjectType>(replyInFlows, extraBufferCapacityInFlows)
|
protected val updateObjectsChannel = MutableSharedFlow<ObjectType>(replyInFlows, extraBufferCapacityInFlows)
|
||||||
protected val deleteObjectsIdsChannel = MutableSharedFlow<IdType>(replyInFlows, extraBufferCapacityInFlows)
|
protected val deleteObjectsIdsChannel = MutableSharedFlow<IdType>(replyInFlows, extraBufferCapacityInFlows)
|
||||||
|
@ -7,7 +7,7 @@ import dev.inmo.micro_utils.pagination.Pagination
|
|||||||
import dev.inmo.micro_utils.pagination.PaginationResult
|
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.KeyValueRepo
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
|
|
||||||
private val cache = HashMap<String, KeyValueStore<*>>()
|
private val cache = HashMap<String, KeyValueStore<*>>()
|
||||||
@ -15,7 +15,7 @@ private val cache = HashMap<String, KeyValueStore<*>>()
|
|||||||
fun <T : Any> Context.keyValueStore(
|
fun <T : Any> Context.keyValueStore(
|
||||||
name: String = "default",
|
name: String = "default",
|
||||||
cacheValues: Boolean = false
|
cacheValues: Boolean = false
|
||||||
): StandardKeyValueRepo<String, T> {
|
): KeyValueRepo<String, T> {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
return cache.getOrPut(name) {
|
return cache.getOrPut(name) {
|
||||||
KeyValueStore<T>(this, name, cacheValues)
|
KeyValueStore<T>(this, name, cacheValues)
|
||||||
@ -26,7 +26,7 @@ class KeyValueStore<T : Any> internal constructor (
|
|||||||
c: Context,
|
c: Context,
|
||||||
preferencesName: String,
|
preferencesName: String,
|
||||||
useCache: Boolean = false
|
useCache: Boolean = false
|
||||||
) : SharedPreferences.OnSharedPreferenceChangeListener, StandardKeyValueRepo<String, T> {
|
) : SharedPreferences.OnSharedPreferenceChangeListener, KeyValueRepo<String, T> {
|
||||||
private val sharedPreferences = c.getSharedPreferences(preferencesName, Context.MODE_PRIVATE)
|
private val sharedPreferences = c.getSharedPreferences(preferencesName, Context.MODE_PRIVATE)
|
||||||
|
|
||||||
private val cachedData = if (useCache) {
|
private val cachedData = if (useCache) {
|
||||||
|
@ -9,7 +9,6 @@ import dev.inmo.micro_utils.repos.*
|
|||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
import kotlinx.coroutines.flow.asSharedFlow
|
import kotlinx.coroutines.flow.asSharedFlow
|
||||||
import kotlinx.coroutines.runBlocking
|
|
||||||
import kotlinx.serialization.KSerializer
|
import kotlinx.serialization.KSerializer
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
|
|
||||||
@ -26,7 +25,7 @@ class OneToManyAndroidRepo<Key, Value>(
|
|||||||
private val keyFromString: String.() -> Key,
|
private val keyFromString: String.() -> Key,
|
||||||
private val valueFromString: String.() -> Value,
|
private val valueFromString: String.() -> Value,
|
||||||
private val helper: SQLiteOpenHelper
|
private val helper: SQLiteOpenHelper
|
||||||
) : OneToManyKeyValueRepo<Key, Value> {
|
) : KeyValuesRepo<Key, Value> {
|
||||||
private val _onNewValue: MutableSharedFlow<Pair<Key, Value>> = MutableSharedFlow()
|
private val _onNewValue: MutableSharedFlow<Pair<Key, Value>> = MutableSharedFlow()
|
||||||
override val onNewValue: Flow<Pair<Key, Value>> = _onNewValue.asSharedFlow()
|
override val onNewValue: Flow<Pair<Key, Value>> = _onNewValue.asSharedFlow()
|
||||||
private val _onValueRemoved: MutableSharedFlow<Pair<Key, Value>> = MutableSharedFlow()
|
private val _onValueRemoved: MutableSharedFlow<Pair<Key, Value>> = MutableSharedFlow()
|
||||||
|
@ -4,13 +4,11 @@ package dev.inmo.micro_utils.repos.versions
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.database.sqlite.SQLiteOpenHelper
|
import android.database.sqlite.SQLiteOpenHelper
|
||||||
import androidx.core.content.contentValuesOf
|
|
||||||
import dev.inmo.micro_utils.repos.*
|
import dev.inmo.micro_utils.repos.*
|
||||||
import dev.inmo.micro_utils.repos.keyvalue.keyValueStore
|
import dev.inmo.micro_utils.repos.keyvalue.keyValueStore
|
||||||
import kotlinx.coroutines.runBlocking
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Will create [VersionsRepo] based on [T], but versions will be stored in [StandardKeyValueRepo]
|
* Will create [VersionsRepo] based on [T], but versions will be stored in [KeyValueRepo]
|
||||||
*
|
*
|
||||||
* @receiver Will be used to create [KeyValueBasedVersionsRepoProxy] via [keyValueStore] and pass it to [StandardVersionsRepo]
|
* @receiver Will be used to create [KeyValueBasedVersionsRepoProxy] via [keyValueStore] and pass it to [StandardVersionsRepo]
|
||||||
*
|
*
|
||||||
@ -26,9 +24,9 @@ inline fun <T> Context.versionsKeyValueRepo(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
/**
|
/**
|
||||||
* Will create [VersionsRepo] based on [SQLiteOpenHelper], but versions will be stored in [StandardKeyValueRepo]
|
* Will create [VersionsRepo] based on [SQLiteOpenHelper], but versions will be stored in [KeyValueRepo]
|
||||||
*
|
*
|
||||||
* @receiver Will be used to create [StandardKeyValueRepo] via [keyValueStore] and pass it to [StandardVersionsRepo]
|
* @receiver Will be used to create [KeyValueRepo] via [keyValueStore] and pass it to [StandardVersionsRepo]
|
||||||
*
|
*
|
||||||
* @see [keyValueStore]
|
* @see [keyValueStore]
|
||||||
*/
|
*/
|
||||||
@ -37,9 +35,9 @@ inline fun Context.versionsKeyValueRepoForSQL(
|
|||||||
) = versionsKeyValueRepo(database)
|
) = versionsKeyValueRepo(database)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Will create [VersionsRepo] based on [SQLiteOpenHelper], but versions will be stored in [StandardKeyValueRepo]
|
* Will create [VersionsRepo] based on [SQLiteOpenHelper], but versions will be stored in [KeyValueRepo]
|
||||||
*
|
*
|
||||||
* @param context Will be used to create [StandardKeyValueRepo] via [keyValueStore] and pass it to [StandardVersionsRepo]
|
* @param context Will be used to create [KeyValueRepo] via [keyValueStore] and pass it to [StandardVersionsRepo]
|
||||||
*
|
*
|
||||||
* @see [keyValueStore]
|
* @see [keyValueStore]
|
||||||
*/
|
*/
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package dev.inmo.micro_utils.repos.exposed
|
package dev.inmo.micro_utils.repos.exposed
|
||||||
|
|
||||||
import dev.inmo.micro_utils.repos.StandardCRUDRepo
|
import dev.inmo.micro_utils.repos.CRUDRepo
|
||||||
|
|
||||||
abstract class AbstractExposedCRUDRepo<ObjectType, IdType, InputValueType>(
|
abstract class AbstractExposedCRUDRepo<ObjectType, IdType, InputValueType>(
|
||||||
flowsChannelsSize: Int = 0,
|
flowsChannelsSize: Int = 0,
|
||||||
@ -11,4 +11,4 @@ abstract class AbstractExposedCRUDRepo<ObjectType, IdType, InputValueType>(
|
|||||||
tableName
|
tableName
|
||||||
),
|
),
|
||||||
ExposedCRUDRepo<ObjectType, IdType>,
|
ExposedCRUDRepo<ObjectType, IdType>,
|
||||||
StandardCRUDRepo<ObjectType, IdType, InputValueType>
|
CRUDRepo<ObjectType, IdType, InputValueType>
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
package dev.inmo.micro_utils.repos.exposed
|
package dev.inmo.micro_utils.repos.exposed
|
||||||
|
|
||||||
import dev.inmo.micro_utils.pagination.*
|
import dev.inmo.micro_utils.pagination.*
|
||||||
import dev.inmo.micro_utils.repos.ReadStandardCRUDRepo
|
import dev.inmo.micro_utils.repos.ReadCRUDRepo
|
||||||
import org.jetbrains.exposed.sql.*
|
import org.jetbrains.exposed.sql.*
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
|
|
||||||
abstract class AbstractExposedReadCRUDRepo<ObjectType, IdType>(
|
abstract class AbstractExposedReadCRUDRepo<ObjectType, IdType>(
|
||||||
tableName: String
|
tableName: String
|
||||||
) :
|
) :
|
||||||
ReadStandardCRUDRepo<ObjectType, IdType>,
|
ReadCRUDRepo<ObjectType, IdType>,
|
||||||
ExposedCRUDRepo<ObjectType, IdType>,
|
ExposedCRUDRepo<ObjectType, IdType>,
|
||||||
Table(tableName)
|
Table(tableName)
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package dev.inmo.micro_utils.repos.exposed
|
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.WriteCRUDRepo
|
||||||
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
|
||||||
@ -15,7 +15,7 @@ abstract class AbstractExposedWriteCRUDRepo<ObjectType, IdType, InputValueType>(
|
|||||||
) :
|
) :
|
||||||
AbstractExposedReadCRUDRepo<ObjectType, IdType>(tableName),
|
AbstractExposedReadCRUDRepo<ObjectType, IdType>(tableName),
|
||||||
ExposedCRUDRepo<ObjectType, IdType>,
|
ExposedCRUDRepo<ObjectType, IdType>,
|
||||||
WriteStandardCRUDRepo<ObjectType, IdType, InputValueType>
|
WriteCRUDRepo<ObjectType, IdType, InputValueType>
|
||||||
{
|
{
|
||||||
protected val _newObjectsFlow = MutableSharedFlow<ObjectType>(replyCacheInFlows, flowsChannelsSize)
|
protected val _newObjectsFlow = MutableSharedFlow<ObjectType>(replyCacheInFlows, flowsChannelsSize)
|
||||||
protected val _updatedObjectsFlow = MutableSharedFlow<ObjectType>(replyCacheInFlows, flowsChannelsSize)
|
protected val _updatedObjectsFlow = MutableSharedFlow<ObjectType>(replyCacheInFlows, flowsChannelsSize)
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
package dev.inmo.micro_utils.repos.exposed.keyvalue
|
package dev.inmo.micro_utils.repos.exposed.keyvalue
|
||||||
|
|
||||||
import dev.inmo.micro_utils.repos.StandardKeyValueRepo
|
import dev.inmo.micro_utils.repos.KeyValueRepo
|
||||||
import dev.inmo.micro_utils.repos.exposed.ColumnAllocator
|
import dev.inmo.micro_utils.repos.exposed.ColumnAllocator
|
||||||
import dev.inmo.micro_utils.repos.exposed.initTable
|
|
||||||
import kotlinx.coroutines.channels.Channel
|
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
import org.jetbrains.exposed.sql.*
|
import org.jetbrains.exposed.sql.*
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
@ -13,7 +11,7 @@ open class ExposedKeyValueRepo<Key, Value>(
|
|||||||
keyColumnAllocator: ColumnAllocator<Key>,
|
keyColumnAllocator: ColumnAllocator<Key>,
|
||||||
valueColumnAllocator: ColumnAllocator<Value>,
|
valueColumnAllocator: ColumnAllocator<Value>,
|
||||||
tableName: String? = null
|
tableName: String? = null
|
||||||
) : StandardKeyValueRepo<Key, Value>, ExposedReadKeyValueRepo<Key, Value>(
|
) : KeyValueRepo<Key, Value>, ExposedReadKeyValueRepo<Key, Value>(
|
||||||
database,
|
database,
|
||||||
keyColumnAllocator,
|
keyColumnAllocator,
|
||||||
valueColumnAllocator,
|
valueColumnAllocator,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package dev.inmo.micro_utils.repos.exposed.keyvalue
|
package dev.inmo.micro_utils.repos.exposed.keyvalue
|
||||||
|
|
||||||
import dev.inmo.micro_utils.pagination.*
|
import dev.inmo.micro_utils.pagination.*
|
||||||
import dev.inmo.micro_utils.repos.ReadStandardKeyValueRepo
|
import dev.inmo.micro_utils.repos.ReadKeyValueRepo
|
||||||
import dev.inmo.micro_utils.repos.exposed.*
|
import dev.inmo.micro_utils.repos.exposed.*
|
||||||
import org.jetbrains.exposed.sql.*
|
import org.jetbrains.exposed.sql.*
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
@ -11,7 +11,7 @@ open class ExposedReadKeyValueRepo<Key, Value>(
|
|||||||
keyColumnAllocator: ColumnAllocator<Key>,
|
keyColumnAllocator: ColumnAllocator<Key>,
|
||||||
valueColumnAllocator: ColumnAllocator<Value>,
|
valueColumnAllocator: ColumnAllocator<Value>,
|
||||||
tableName: String? = null
|
tableName: String? = null
|
||||||
) : ReadStandardKeyValueRepo<Key, Value>, ExposedRepo, Table(tableName ?: "") {
|
) : ReadKeyValueRepo<Key, Value>, ExposedRepo, Table(tableName ?: "") {
|
||||||
val keyColumn: Column<Key> = keyColumnAllocator()
|
val keyColumn: Column<Key> = keyColumnAllocator()
|
||||||
val valueColumn: Column<Value> = valueColumnAllocator()
|
val valueColumn: Column<Value> = valueColumnAllocator()
|
||||||
override val primaryKey: PrimaryKey = PrimaryKey(keyColumn, valueColumn)
|
override val primaryKey: PrimaryKey = PrimaryKey(keyColumn, valueColumn)
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
package dev.inmo.micro_utils.repos.exposed.onetomany
|
package dev.inmo.micro_utils.repos.exposed.onetomany
|
||||||
|
|
||||||
import dev.inmo.micro_utils.repos.OneToManyKeyValueRepo
|
import dev.inmo.micro_utils.repos.KeyValuesRepo
|
||||||
import dev.inmo.micro_utils.repos.exposed.ColumnAllocator
|
import dev.inmo.micro_utils.repos.exposed.ColumnAllocator
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
import org.jetbrains.exposed.sql.*
|
import org.jetbrains.exposed.sql.*
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
|
|
||||||
typealias ExposedKeyValuesRepo<Key, Value> = ExposedOneToManyKeyValueRepo<Key, Value>
|
typealias ExposedOneToManyKeyValueRepo1<Key, Value> = ExposedKeyValuesRepo<Key, Value>
|
||||||
open class ExposedOneToManyKeyValueRepo<Key, Value>(
|
open class ExposedKeyValuesRepo<Key, Value>(
|
||||||
database: Database,
|
database: Database,
|
||||||
keyColumnAllocator: ColumnAllocator<Key>,
|
keyColumnAllocator: ColumnAllocator<Key>,
|
||||||
valueColumnAllocator: ColumnAllocator<Value>,
|
valueColumnAllocator: ColumnAllocator<Value>,
|
||||||
tableName: String? = null
|
tableName: String? = null
|
||||||
) : OneToManyKeyValueRepo<Key, Value>, ExposedReadOneToManyKeyValueRepo<Key, Value>(
|
) : KeyValuesRepo<Key, Value>, ExposedReadKeyValuesRepo<Key, Value>(
|
||||||
database,
|
database,
|
||||||
keyColumnAllocator,
|
keyColumnAllocator,
|
||||||
valueColumnAllocator,
|
valueColumnAllocator,
|
@ -1,20 +1,19 @@
|
|||||||
package dev.inmo.micro_utils.repos.exposed.onetomany
|
package dev.inmo.micro_utils.repos.exposed.onetomany
|
||||||
|
|
||||||
import dev.inmo.micro_utils.pagination.*
|
import dev.inmo.micro_utils.pagination.*
|
||||||
import dev.inmo.micro_utils.repos.ReadOneToManyKeyValueRepo
|
import dev.inmo.micro_utils.repos.ReadKeyValuesRepo
|
||||||
import dev.inmo.micro_utils.repos.exposed.*
|
import dev.inmo.micro_utils.repos.exposed.*
|
||||||
import dev.inmo.micro_utils.repos.exposed.keyvalue.ExposedReadKeyValueRepo
|
|
||||||
import org.jetbrains.exposed.sql.*
|
import org.jetbrains.exposed.sql.*
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
|
|
||||||
typealias ExposedReadKeyValuesRepo<Key, Value> = ExposedReadOneToManyKeyValueRepo<Key, Value>
|
typealias ExposedReadOneToManyKeyValueRepo<Key, Value> = ExposedReadKeyValuesRepo<Key, Value>
|
||||||
|
|
||||||
open class ExposedReadOneToManyKeyValueRepo<Key, Value>(
|
open class ExposedReadKeyValuesRepo<Key, Value>(
|
||||||
override val database: Database,
|
override val database: Database,
|
||||||
keyColumnAllocator: ColumnAllocator<Key>,
|
keyColumnAllocator: ColumnAllocator<Key>,
|
||||||
valueColumnAllocator: ColumnAllocator<Value>,
|
valueColumnAllocator: ColumnAllocator<Value>,
|
||||||
tableName: String? = null
|
tableName: String? = null
|
||||||
) : ReadOneToManyKeyValueRepo<Key, Value>, ExposedRepo, Table(tableName ?: "") {
|
) : ReadKeyValuesRepo<Key, Value>, ExposedRepo, Table(tableName ?: "") {
|
||||||
val keyColumn: Column<Key> = keyColumnAllocator()
|
val keyColumn: Column<Key> = keyColumnAllocator()
|
||||||
val valueColumn: Column<Value> = valueColumnAllocator()
|
val valueColumn: Column<Value> = valueColumnAllocator()
|
||||||
|
|
@ -5,7 +5,7 @@ import kotlinx.coroutines.flow.*
|
|||||||
|
|
||||||
class ReadMapCRUDRepo<ObjectType, IdType>(
|
class ReadMapCRUDRepo<ObjectType, IdType>(
|
||||||
private val map: Map<IdType, ObjectType> = emptyMap()
|
private val map: Map<IdType, ObjectType> = emptyMap()
|
||||||
) : ReadStandardCRUDRepo<ObjectType, IdType> {
|
) : ReadCRUDRepo<ObjectType, IdType> {
|
||||||
override suspend fun getByPagination(pagination: Pagination): PaginationResult<ObjectType> {
|
override suspend fun getByPagination(pagination: Pagination): PaginationResult<ObjectType> {
|
||||||
return map.keys.drop(pagination.firstIndex).take(pagination.size).mapNotNull {
|
return map.keys.drop(pagination.firstIndex).take(pagination.size).mapNotNull {
|
||||||
map[it]
|
map[it]
|
||||||
@ -24,7 +24,7 @@ class ReadMapCRUDRepo<ObjectType, IdType>(
|
|||||||
|
|
||||||
abstract class WriteMapCRUDRepo<ObjectType, IdType, InputValueType>(
|
abstract class WriteMapCRUDRepo<ObjectType, IdType, InputValueType>(
|
||||||
protected val map: MutableMap<IdType, ObjectType> = mutableMapOf()
|
protected val map: MutableMap<IdType, ObjectType> = mutableMapOf()
|
||||||
) : WriteStandardCRUDRepo<ObjectType, IdType, InputValueType> {
|
) : WriteCRUDRepo<ObjectType, IdType, InputValueType> {
|
||||||
protected val _newObjectsFlow: MutableSharedFlow<ObjectType> = MutableSharedFlow()
|
protected val _newObjectsFlow: MutableSharedFlow<ObjectType> = MutableSharedFlow()
|
||||||
override val newObjectsFlow: Flow<ObjectType> = _newObjectsFlow.asSharedFlow()
|
override val newObjectsFlow: Flow<ObjectType> = _newObjectsFlow.asSharedFlow()
|
||||||
protected val _updatedObjectsFlow: MutableSharedFlow<ObjectType> = MutableSharedFlow()
|
protected val _updatedObjectsFlow: MutableSharedFlow<ObjectType> = MutableSharedFlow()
|
||||||
@ -68,25 +68,30 @@ abstract class WriteMapCRUDRepo<ObjectType, IdType, InputValueType>(
|
|||||||
|
|
||||||
abstract class MapCRUDRepo<ObjectType, IdType, InputValueType>(
|
abstract class MapCRUDRepo<ObjectType, IdType, InputValueType>(
|
||||||
map: MutableMap<IdType, ObjectType>
|
map: MutableMap<IdType, ObjectType>
|
||||||
) : StandardCRUDRepo<ObjectType, IdType, InputValueType>,
|
) : CRUDRepo<ObjectType, IdType, InputValueType>,
|
||||||
ReadStandardCRUDRepo<ObjectType, IdType> by ReadMapCRUDRepo(map),
|
ReadCRUDRepo<ObjectType, IdType> by ReadMapCRUDRepo(map),
|
||||||
WriteMapCRUDRepo<ObjectType, IdType, InputValueType>(map)
|
WriteMapCRUDRepo<ObjectType, IdType, InputValueType>(map)
|
||||||
|
|
||||||
fun <ObjectType, IdType, InputValueType> MapCRUDRepo(
|
fun <ObjectType, IdType, InputValueType> MapCRUDRepo(
|
||||||
map: MutableMap<IdType, ObjectType>,
|
map: MutableMap<IdType, ObjectType>,
|
||||||
updateCallback: suspend (newValue: InputValueType, id: IdType, old: ObjectType) -> ObjectType,
|
updateCallback: suspend MutableMap<IdType, ObjectType>.(newValue: InputValueType, id: IdType, old: ObjectType) -> ObjectType,
|
||||||
createCallback: suspend (newValue: InputValueType) -> Pair<IdType, ObjectType>
|
createCallback: suspend MutableMap<IdType, ObjectType>.(newValue: InputValueType) -> Pair<IdType, ObjectType>
|
||||||
) = object : MapCRUDRepo<ObjectType, IdType, InputValueType>(map) {
|
) = object : MapCRUDRepo<ObjectType, IdType, InputValueType>(map) {
|
||||||
override suspend fun updateObject(
|
override suspend fun updateObject(
|
||||||
newValue: InputValueType,
|
newValue: InputValueType,
|
||||||
id: IdType,
|
id: IdType,
|
||||||
old: ObjectType
|
old: ObjectType
|
||||||
): ObjectType = updateCallback(newValue, id, old)
|
): ObjectType = map.updateCallback(newValue, id, old)
|
||||||
|
|
||||||
override suspend fun createObject(newValue: InputValueType): Pair<IdType, ObjectType> = createCallback(newValue)
|
override suspend fun createObject(newValue: InputValueType): Pair<IdType, ObjectType> = map.createCallback(newValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <ObjectType, IdType, InputValueType> MapCRUDRepo(
|
||||||
|
updateCallback: suspend MutableMap<IdType, ObjectType>.(newValue: InputValueType, id: IdType, old: ObjectType) -> ObjectType,
|
||||||
|
createCallback: suspend MutableMap<IdType, ObjectType>.(newValue: InputValueType) -> Pair<IdType, ObjectType>
|
||||||
|
) = MapCRUDRepo(mutableMapOf(), updateCallback, createCallback)
|
||||||
|
|
||||||
fun <ObjectType, IdType, InputValueType> MutableMap<IdType, ObjectType>.asCrudRepo(
|
fun <ObjectType, IdType, InputValueType> MutableMap<IdType, ObjectType>.asCrudRepo(
|
||||||
updateCallback: suspend (newValue: InputValueType, id: IdType, old: ObjectType) -> ObjectType,
|
updateCallback: suspend MutableMap<IdType, ObjectType>.(newValue: InputValueType, id: IdType, old: ObjectType) -> ObjectType,
|
||||||
createCallback: suspend (newValue: InputValueType) -> Pair<IdType, ObjectType>
|
createCallback: suspend MutableMap<IdType, ObjectType>.(newValue: InputValueType) -> Pair<IdType, ObjectType>
|
||||||
) = MapCRUDRepo(this, updateCallback, createCallback)
|
) = MapCRUDRepo(this, updateCallback, createCallback)
|
||||||
|
@ -9,7 +9,7 @@ import kotlinx.coroutines.flow.MutableSharedFlow
|
|||||||
|
|
||||||
class ReadMapKeyValueRepo<Key, Value>(
|
class ReadMapKeyValueRepo<Key, Value>(
|
||||||
protected val map: Map<Key, Value> = emptyMap()
|
protected val map: Map<Key, Value> = emptyMap()
|
||||||
) : ReadStandardKeyValueRepo<Key, Value> {
|
) : ReadKeyValueRepo<Key, Value> {
|
||||||
override suspend fun get(k: Key): Value? = map[k]
|
override suspend fun get(k: Key): Value? = map[k]
|
||||||
|
|
||||||
override suspend fun values(
|
override suspend fun values(
|
||||||
@ -58,7 +58,7 @@ class ReadMapKeyValueRepo<Key, Value>(
|
|||||||
|
|
||||||
class WriteMapKeyValueRepo<Key, Value>(
|
class WriteMapKeyValueRepo<Key, Value>(
|
||||||
private val map: MutableMap<Key, Value> = mutableMapOf()
|
private val map: MutableMap<Key, Value> = mutableMapOf()
|
||||||
) : WriteStandardKeyValueRepo<Key, Value> {
|
) : WriteKeyValueRepo<Key, Value> {
|
||||||
private val _onNewValue: MutableSharedFlow<Pair<Key, Value>> = MutableSharedFlow()
|
private val _onNewValue: MutableSharedFlow<Pair<Key, Value>> = MutableSharedFlow()
|
||||||
override val onNewValue: Flow<Pair<Key, Value>>
|
override val onNewValue: Flow<Pair<Key, Value>>
|
||||||
get() = _onNewValue
|
get() = _onNewValue
|
||||||
@ -78,19 +78,19 @@ class WriteMapKeyValueRepo<Key, Value>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun unsetWithValues(toUnset: List<Value>) {
|
override suspend fun unsetWithValues(toUnset: List<Value>) {
|
||||||
map.forEach {
|
map.mapNotNull { (k, v) ->
|
||||||
if (it.value in toUnset) {
|
k.takeIf { v in toUnset }
|
||||||
map.remove(it.key)
|
}.forEach {
|
||||||
_onValueRemoved.emit(it.key)
|
map.remove(it)
|
||||||
}
|
_onValueRemoved.emit(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MapKeyValueRepo<Key, Value>(
|
class MapKeyValueRepo<Key, Value>(
|
||||||
private val map: MutableMap<Key, Value> = mutableMapOf()
|
private val map: MutableMap<Key, Value> = mutableMapOf()
|
||||||
) : StandardKeyValueRepo<Key, Value>,
|
) : KeyValueRepo<Key, Value>,
|
||||||
ReadStandardKeyValueRepo<Key, Value> by ReadMapKeyValueRepo(map),
|
ReadKeyValueRepo<Key, Value> by ReadMapKeyValueRepo(map),
|
||||||
WriteStandardKeyValueRepo<Key, Value> by WriteMapKeyValueRepo(map)
|
WriteKeyValueRepo<Key, Value> by WriteMapKeyValueRepo(map)
|
||||||
|
|
||||||
fun <K, V> MutableMap<K, V>.asKeyValueRepo(): StandardKeyValueRepo<K, V> = MapKeyValueRepo(this)
|
fun <K, V> MutableMap<K, V>.asKeyValueRepo(): KeyValueRepo<K, V> = MapKeyValueRepo(this)
|
||||||
|
@ -5,9 +5,11 @@ 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 kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
|
|
||||||
class MapReadOneToManyKeyValueRepo<Key, Value>(
|
@Deprecated("Renamed", ReplaceWith("MapReadKeyValuesRepo", "dev.inmo.micro_utils.repos.MapReadKeyValuesRepo"))
|
||||||
|
typealias MapReadOneToManyKeyValueRepo<Key, Value> = MapReadKeyValuesRepo<Key, Value>
|
||||||
|
class MapReadKeyValuesRepo<Key, Value>(
|
||||||
private val map: Map<Key, List<Value>> = emptyMap()
|
private val map: Map<Key, List<Value>> = emptyMap()
|
||||||
) : ReadOneToManyKeyValueRepo<Key, Value> {
|
) : ReadKeyValuesRepo<Key, Value> {
|
||||||
override suspend fun get(k: Key, pagination: Pagination, reversed: Boolean): PaginationResult<Value> {
|
override suspend fun get(k: Key, pagination: Pagination, reversed: Boolean): PaginationResult<Value> {
|
||||||
val list = map[k] ?: return emptyPaginationResult()
|
val list = map[k] ?: return emptyPaginationResult()
|
||||||
|
|
||||||
@ -53,9 +55,11 @@ class MapReadOneToManyKeyValueRepo<Key, Value>(
|
|||||||
override suspend fun count(): Long = map.size.toLong()
|
override suspend fun count(): Long = map.size.toLong()
|
||||||
}
|
}
|
||||||
|
|
||||||
class MapWriteOneToManyKeyValueRepo<Key, Value>(
|
@Deprecated("Renamed", ReplaceWith("MapWriteKeyValuesRepo", "dev.inmo.micro_utils.repos.MapWriteKeyValuesRepo"))
|
||||||
|
typealias MapWriteOneToManyKeyValueRepo<Key, Value> = MapWriteKeyValuesRepo<Key, Value>
|
||||||
|
class MapWriteKeyValuesRepo<Key, Value>(
|
||||||
private val map: MutableMap<Key, MutableList<Value>> = mutableMapOf()
|
private val map: MutableMap<Key, MutableList<Value>> = mutableMapOf()
|
||||||
) : WriteOneToManyKeyValueRepo<Key, Value> {
|
) : WriteKeyValuesRepo<Key, Value> {
|
||||||
private val _onNewValue: MutableSharedFlow<Pair<Key, Value>> = MutableSharedFlow()
|
private val _onNewValue: MutableSharedFlow<Pair<Key, Value>> = MutableSharedFlow()
|
||||||
override val onNewValue: Flow<Pair<Key, Value>> = _onNewValue.asSharedFlow()
|
override val onNewValue: Flow<Pair<Key, Value>> = _onNewValue.asSharedFlow()
|
||||||
private val _onValueRemoved: MutableSharedFlow<Pair<Key, Value>> = MutableSharedFlow()
|
private val _onValueRemoved: MutableSharedFlow<Pair<Key, Value>> = MutableSharedFlow()
|
||||||
@ -80,6 +84,10 @@ class MapWriteOneToManyKeyValueRepo<Key, Value>(
|
|||||||
_onValueRemoved.emit(k to v)
|
_onValueRemoved.emit(k to v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (map[k] ?.isEmpty() == true) {
|
||||||
|
map.remove(k)
|
||||||
|
_onDataCleared.emit(k)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,12 +102,17 @@ class MapWriteOneToManyKeyValueRepo<Key, Value>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MapOneToManyKeyValueRepo<Key, Value>(
|
@Deprecated("Renamed", ReplaceWith("MapKeyValuesRepo", "dev.inmo.micro_utils.repos.MapKeyValuesRepo"))
|
||||||
|
typealias MapOneToManyKeyValueRepo1<Key, Value> = MapKeyValuesRepo<Key, Value>
|
||||||
|
class MapKeyValuesRepo<Key, Value>(
|
||||||
private val map: MutableMap<Key, MutableList<Value>> = mutableMapOf()
|
private val map: MutableMap<Key, MutableList<Value>> = mutableMapOf()
|
||||||
) : OneToManyKeyValueRepo<Key, Value>,
|
) : KeyValuesRepo<Key, Value>,
|
||||||
ReadOneToManyKeyValueRepo<Key, Value> by MapReadOneToManyKeyValueRepo(map),
|
ReadKeyValuesRepo<Key, Value> by MapReadKeyValuesRepo(map),
|
||||||
WriteOneToManyKeyValueRepo<Key, Value> by MapWriteOneToManyKeyValueRepo(map)
|
WriteKeyValuesRepo<Key, Value> by MapWriteKeyValuesRepo(map)
|
||||||
|
|
||||||
fun <K, V> MutableMap<K, List<V>>.asOneToManyKeyValueRepo(): OneToManyKeyValueRepo<K, V> = MapOneToManyKeyValueRepo(
|
fun <K, V> MutableMap<K, List<V>>.asKeyValuesRepo(): KeyValuesRepo<K, V> = MapKeyValuesRepo(
|
||||||
map { (k, v) -> k to v.toMutableList() }.toMap().toMutableMap()
|
map { (k, v) -> k to v.toMutableList() }.toMap().toMutableMap()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Deprecated("Renamed", ReplaceWith("asKeyValuesRepo", "dev.inmo.micro_utils.repos.asKeyValuesRepo"))
|
||||||
|
fun <K, V> MutableMap<K, List<V>>.asOneToManyKeyValueRepo(): KeyValuesRepo<K, V> = asKeyValuesRepo()
|
@ -0,0 +1,121 @@
|
|||||||
|
package dev.inmo.micro_utils.repos.ktor.client.crud
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.ktor.common.*
|
||||||
|
import dev.inmo.micro_utils.repos.*
|
||||||
|
import io.ktor.client.HttpClient
|
||||||
|
import io.ktor.http.ContentType
|
||||||
|
import io.ktor.util.reflect.TypeInfo
|
||||||
|
import io.ktor.util.reflect.typeInfo
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
|
class KtorCRUDRepoClient<ObjectType, IdType, InputValue> (
|
||||||
|
readDelegate: ReadCRUDRepo<ObjectType, IdType>,
|
||||||
|
writeDelegate: WriteCRUDRepo<ObjectType, IdType, InputValue>
|
||||||
|
) : CRUDRepo<ObjectType, IdType, InputValue> by DelegateBasedCRUDRepo(
|
||||||
|
readDelegate,
|
||||||
|
writeDelegate
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
inline operator fun <reified ObjectType, reified IdType, reified InputValue> invoke(
|
||||||
|
baseUrl: String,
|
||||||
|
httpClient: HttpClient,
|
||||||
|
objectTypeInfo: TypeInfo,
|
||||||
|
contentType: ContentType,
|
||||||
|
noinline idSerializer: suspend (IdType) -> String
|
||||||
|
) = KtorCRUDRepoClient(
|
||||||
|
KtorReadCRUDRepoClient(
|
||||||
|
baseUrl,
|
||||||
|
httpClient,
|
||||||
|
objectTypeInfo,
|
||||||
|
contentType,
|
||||||
|
idSerializer
|
||||||
|
),
|
||||||
|
KtorWriteCrudRepoClient<ObjectType, IdType, InputValue>(
|
||||||
|
baseUrl,
|
||||||
|
httpClient,
|
||||||
|
contentType
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
inline operator fun <reified ObjectType, reified IdType, reified InputValue> invoke(
|
||||||
|
baseUrl: String,
|
||||||
|
subpart: String,
|
||||||
|
httpClient: HttpClient,
|
||||||
|
objectTypeInfo: TypeInfo,
|
||||||
|
contentType: ContentType,
|
||||||
|
noinline idSerializer: suspend (IdType) -> String
|
||||||
|
) = KtorCRUDRepoClient<ObjectType, IdType, InputValue>(
|
||||||
|
buildStandardUrl(baseUrl, subpart),
|
||||||
|
httpClient,
|
||||||
|
objectTypeInfo,
|
||||||
|
contentType,
|
||||||
|
idSerializer
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline fun <reified ObjectType, reified IdType, reified InputValue> KtorCRUDRepoClient(
|
||||||
|
baseUrl: String,
|
||||||
|
httpClient: HttpClient,
|
||||||
|
contentType: ContentType,
|
||||||
|
noinline idSerializer: suspend (IdType) -> String
|
||||||
|
) = KtorCRUDRepoClient<ObjectType, IdType, InputValue>(
|
||||||
|
baseUrl,
|
||||||
|
httpClient,
|
||||||
|
typeInfo<ObjectType>(),
|
||||||
|
contentType,
|
||||||
|
idSerializer
|
||||||
|
)
|
||||||
|
|
||||||
|
inline fun <reified ObjectType, reified IdType, reified InputValue> KtorCRUDRepoClient(
|
||||||
|
baseUrl: String,
|
||||||
|
httpClient: HttpClient,
|
||||||
|
idsSerializer: KSerializer<IdType>,
|
||||||
|
serialFormat: StringFormat,
|
||||||
|
contentType: ContentType,
|
||||||
|
) = KtorCRUDRepoClient<ObjectType, IdType, InputValue>(baseUrl, httpClient, contentType) {
|
||||||
|
serialFormat.encodeToString(idsSerializer, it)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified ObjectType, reified IdType, reified InputValue> KtorCRUDRepoClient(
|
||||||
|
baseUrl: String,
|
||||||
|
httpClient: HttpClient,
|
||||||
|
idsSerializer: KSerializer<IdType>,
|
||||||
|
serialFormat: BinaryFormat,
|
||||||
|
contentType: ContentType,
|
||||||
|
) = KtorCRUDRepoClient<ObjectType, IdType, InputValue>(baseUrl, httpClient, contentType) {
|
||||||
|
serialFormat.encodeHex(idsSerializer, it)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline fun <reified ObjectType, reified IdType, reified InputValue> KtorCRUDRepoClient(
|
||||||
|
baseUrl: String,
|
||||||
|
subpart: String,
|
||||||
|
httpClient: HttpClient,
|
||||||
|
contentType: ContentType,
|
||||||
|
noinline idSerializer: suspend (IdType) -> String
|
||||||
|
) = KtorCRUDRepoClient<ObjectType, IdType, InputValue>(
|
||||||
|
buildStandardUrl(baseUrl, subpart),
|
||||||
|
httpClient,
|
||||||
|
contentType,
|
||||||
|
idSerializer
|
||||||
|
)
|
||||||
|
|
||||||
|
inline fun <reified ObjectType, reified IdType, reified InputValue> KtorCRUDRepoClient(
|
||||||
|
baseUrl: String,
|
||||||
|
subpart: String,
|
||||||
|
httpClient: HttpClient,
|
||||||
|
idsSerializer: KSerializer<IdType>,
|
||||||
|
serialFormat: StringFormat,
|
||||||
|
contentType: ContentType,
|
||||||
|
) = KtorCRUDRepoClient<ObjectType, IdType, InputValue>(buildStandardUrl(baseUrl, subpart), httpClient, idsSerializer, serialFormat, contentType)
|
||||||
|
|
||||||
|
inline fun <reified ObjectType, reified IdType, reified InputValue> KtorCRUDRepoClient(
|
||||||
|
baseUrl: String,
|
||||||
|
subpart: String,
|
||||||
|
httpClient: HttpClient,
|
||||||
|
idsSerializer: KSerializer<IdType>,
|
||||||
|
serialFormat: BinaryFormat,
|
||||||
|
contentType: ContentType,
|
||||||
|
) = KtorCRUDRepoClient<ObjectType, IdType, InputValue>(buildStandardUrl(baseUrl, subpart), httpClient, idsSerializer, serialFormat, contentType)
|
@ -0,0 +1,95 @@
|
|||||||
|
package dev.inmo.micro_utils.repos.ktor.client.crud
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.ktor.common.*
|
||||||
|
import dev.inmo.micro_utils.pagination.*
|
||||||
|
import dev.inmo.micro_utils.repos.ReadCRUDRepo
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.countRouting
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.crud.*
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.idParameterName
|
||||||
|
import io.ktor.client.HttpClient
|
||||||
|
import io.ktor.client.call.body
|
||||||
|
import io.ktor.client.request.get
|
||||||
|
import io.ktor.http.*
|
||||||
|
import io.ktor.util.reflect.TypeInfo
|
||||||
|
import io.ktor.util.reflect.typeInfo
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
|
class KtorReadCRUDRepoClient<ObjectType, IdType> (
|
||||||
|
private val baseUrl: String,
|
||||||
|
private val httpClient: HttpClient,
|
||||||
|
private val objectType: TypeInfo,
|
||||||
|
private val contentType: ContentType,
|
||||||
|
private val idSerializer: suspend (IdType) -> String
|
||||||
|
) : ReadCRUDRepo<ObjectType, IdType> {
|
||||||
|
override suspend fun getByPagination(pagination: Pagination): PaginationResult<ObjectType> = httpClient.get(
|
||||||
|
buildStandardUrl(baseUrl, getByPaginationRouting, pagination.asUrlQueryParts)
|
||||||
|
) {
|
||||||
|
contentType(contentType)
|
||||||
|
}.body()
|
||||||
|
|
||||||
|
override suspend fun getById(id: IdType): ObjectType? = httpClient.get(
|
||||||
|
buildStandardUrl(
|
||||||
|
baseUrl,
|
||||||
|
getByIdRouting,
|
||||||
|
mapOf(
|
||||||
|
idParameterName to idSerializer(id)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
contentType(contentType)
|
||||||
|
}.takeIf { it.status != HttpStatusCode.NoContent } ?.body<ObjectType>(objectType)
|
||||||
|
|
||||||
|
override suspend fun contains(id: IdType): Boolean = httpClient.get(
|
||||||
|
buildStandardUrl(
|
||||||
|
baseUrl,
|
||||||
|
containsRouting,
|
||||||
|
mapOf(
|
||||||
|
idParameterName to idSerializer(id)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
contentType(contentType)
|
||||||
|
}.body()
|
||||||
|
|
||||||
|
override suspend fun count(): Long = httpClient.get(
|
||||||
|
buildStandardUrl(
|
||||||
|
baseUrl,
|
||||||
|
countRouting
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
contentType(contentType)
|
||||||
|
}.body()
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified ObjectType, IdType> KtorReadCRUDRepoClient(
|
||||||
|
baseUrl: String,
|
||||||
|
httpClient: HttpClient,
|
||||||
|
contentType: ContentType,
|
||||||
|
noinline idSerializer: suspend (IdType) -> String
|
||||||
|
) = KtorReadCRUDRepoClient<ObjectType, IdType>(
|
||||||
|
baseUrl,
|
||||||
|
httpClient,
|
||||||
|
typeInfo<ObjectType>(),
|
||||||
|
contentType,
|
||||||
|
idSerializer
|
||||||
|
)
|
||||||
|
|
||||||
|
inline fun <reified ObjectType, IdType> KtorReadCRUDRepoClient(
|
||||||
|
baseUrl: String,
|
||||||
|
httpClient: HttpClient,
|
||||||
|
idsSerializer: KSerializer<IdType>,
|
||||||
|
serialFormat: StringFormat,
|
||||||
|
contentType: ContentType,
|
||||||
|
) = KtorReadCRUDRepoClient<ObjectType, IdType>(baseUrl, httpClient, contentType) {
|
||||||
|
serialFormat.encodeToString(idsSerializer, it)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified ObjectType, IdType> KtorReadCRUDRepoClient(
|
||||||
|
baseUrl: String,
|
||||||
|
httpClient: HttpClient,
|
||||||
|
idsSerializer: KSerializer<IdType>,
|
||||||
|
serialFormat: BinaryFormat,
|
||||||
|
contentType: ContentType,
|
||||||
|
) = KtorReadCRUDRepoClient<ObjectType, IdType>(baseUrl, httpClient, contentType) {
|
||||||
|
serialFormat.encodeHex(idsSerializer, it)
|
||||||
|
}
|
@ -3,19 +3,22 @@ package dev.inmo.micro_utils.repos.ktor.client.crud
|
|||||||
import dev.inmo.micro_utils.ktor.client.*
|
import dev.inmo.micro_utils.ktor.client.*
|
||||||
import dev.inmo.micro_utils.ktor.common.*
|
import dev.inmo.micro_utils.ktor.common.*
|
||||||
import dev.inmo.micro_utils.pagination.*
|
import dev.inmo.micro_utils.pagination.*
|
||||||
import dev.inmo.micro_utils.repos.ReadStandardCRUDRepo
|
import dev.inmo.micro_utils.repos.ReadCRUDRepo
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.countRouting
|
||||||
import dev.inmo.micro_utils.repos.ktor.common.crud.*
|
import dev.inmo.micro_utils.repos.ktor.common.crud.*
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.idParameterName
|
||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
import kotlinx.serialization.KSerializer
|
import kotlinx.serialization.KSerializer
|
||||||
import kotlinx.serialization.builtins.serializer
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
|
||||||
|
@Deprecated("Use KtorReadCRUDRepoClient instead")
|
||||||
class KtorReadStandardCrudRepo<ObjectType, IdType> (
|
class KtorReadStandardCrudRepo<ObjectType, IdType> (
|
||||||
private val baseUrl: String,
|
private val baseUrl: String,
|
||||||
private val unifiedRequester: UnifiedRequester,
|
private val unifiedRequester: UnifiedRequester,
|
||||||
private val objectsSerializer: KSerializer<ObjectType>,
|
private val objectsSerializer: KSerializer<ObjectType>,
|
||||||
private val objectsSerializerNullable: KSerializer<ObjectType?>,
|
private val objectsSerializerNullable: KSerializer<ObjectType?>,
|
||||||
private val idsSerializer: KSerializer<IdType>
|
private val idsSerializer: KSerializer<IdType>
|
||||||
) : ReadStandardCRUDRepo<ObjectType, IdType> {
|
) : ReadCRUDRepo<ObjectType, IdType> {
|
||||||
private val paginationResultSerializer = PaginationResult.serializer(objectsSerializer)
|
private val paginationResultSerializer = PaginationResult.serializer(objectsSerializer)
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@ -38,9 +41,7 @@ class KtorReadStandardCrudRepo<ObjectType, IdType> (
|
|||||||
buildStandardUrl(
|
buildStandardUrl(
|
||||||
baseUrl,
|
baseUrl,
|
||||||
getByIdRouting,
|
getByIdRouting,
|
||||||
mapOf(
|
idParameterName to unifiedRequester.encodeUrlQueryValue(idsSerializer, id)
|
||||||
"id" to unifiedRequester.encodeUrlQueryValue(idsSerializer, id)
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
objectsSerializerNullable
|
objectsSerializerNullable
|
||||||
)
|
)
|
||||||
@ -49,9 +50,7 @@ class KtorReadStandardCrudRepo<ObjectType, IdType> (
|
|||||||
buildStandardUrl(
|
buildStandardUrl(
|
||||||
baseUrl,
|
baseUrl,
|
||||||
containsRouting,
|
containsRouting,
|
||||||
mapOf(
|
idParameterName to unifiedRequester.encodeUrlQueryValue(idsSerializer, id)
|
||||||
"id" to unifiedRequester.encodeUrlQueryValue(idsSerializer, id)
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
Boolean.serializer()
|
Boolean.serializer()
|
||||||
)
|
)
|
||||||
|
@ -7,6 +7,7 @@ import dev.inmo.micro_utils.repos.*
|
|||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
import kotlinx.serialization.KSerializer
|
import kotlinx.serialization.KSerializer
|
||||||
|
|
||||||
|
@Deprecated("Use KtorCRUDRepoClient instead")
|
||||||
class KtorStandardCrudRepo<ObjectType, IdType, InputValue> (
|
class KtorStandardCrudRepo<ObjectType, IdType, InputValue> (
|
||||||
baseUrl: String,
|
baseUrl: String,
|
||||||
baseSubpart: String,
|
baseSubpart: String,
|
||||||
@ -15,15 +16,15 @@ class KtorStandardCrudRepo<ObjectType, IdType, InputValue> (
|
|||||||
objectsNullableSerializer: KSerializer<ObjectType?>,
|
objectsNullableSerializer: KSerializer<ObjectType?>,
|
||||||
inputsSerializer: KSerializer<InputValue>,
|
inputsSerializer: KSerializer<InputValue>,
|
||||||
idsSerializer: KSerializer<IdType>
|
idsSerializer: KSerializer<IdType>
|
||||||
) : StandardCRUDRepo<ObjectType, IdType, InputValue>,
|
) : CRUDRepo<ObjectType, IdType, InputValue>,
|
||||||
ReadStandardCRUDRepo<ObjectType, IdType> by KtorReadStandardCrudRepo(
|
ReadCRUDRepo<ObjectType, IdType> by KtorReadStandardCrudRepo(
|
||||||
"$baseUrl/$baseSubpart",
|
"$baseUrl/$baseSubpart",
|
||||||
unifiedRequester,
|
unifiedRequester,
|
||||||
objectsSerializer,
|
objectsSerializer,
|
||||||
objectsNullableSerializer,
|
objectsNullableSerializer,
|
||||||
idsSerializer
|
idsSerializer
|
||||||
),
|
),
|
||||||
WriteStandardCRUDRepo<ObjectType, IdType, InputValue> by KtorWriteStandardCrudRepo(
|
WriteCRUDRepo<ObjectType, IdType, InputValue> by KtorWriteStandardCrudRepo(
|
||||||
"$baseUrl/$baseSubpart",
|
"$baseUrl/$baseSubpart",
|
||||||
unifiedRequester,
|
unifiedRequester,
|
||||||
objectsSerializer,
|
objectsSerializer,
|
||||||
|
@ -0,0 +1,85 @@
|
|||||||
|
package dev.inmo.micro_utils.repos.ktor.client.crud
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.ktor.client.*
|
||||||
|
import dev.inmo.micro_utils.ktor.common.*
|
||||||
|
import dev.inmo.micro_utils.repos.UpdatedValuePair
|
||||||
|
import dev.inmo.micro_utils.repos.WriteCRUDRepo
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.crud.*
|
||||||
|
import io.ktor.client.HttpClient
|
||||||
|
import io.ktor.client.call.body
|
||||||
|
import io.ktor.client.request.*
|
||||||
|
import io.ktor.client.statement.HttpResponse
|
||||||
|
import io.ktor.http.ContentType
|
||||||
|
import io.ktor.http.contentType
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
class KtorWriteCrudRepoClient<ObjectType, IdType, InputValue> (
|
||||||
|
private val baseUrl: String,
|
||||||
|
private val httpClient: HttpClient,
|
||||||
|
override val newObjectsFlow: Flow<ObjectType>,
|
||||||
|
override val updatedObjectsFlow: Flow<ObjectType>,
|
||||||
|
override val deletedObjectsIdsFlow: Flow<IdType>,
|
||||||
|
private val createSetup: suspend HttpRequestBuilder.(List<InputValue>) -> Unit,
|
||||||
|
private val updateSetup: suspend HttpRequestBuilder.(List<UpdatedValuePair<IdType, InputValue>>) -> Unit,
|
||||||
|
private val deleteByIdSetup: suspend HttpRequestBuilder.(List<IdType>) -> Unit,
|
||||||
|
private val createBodyGetter: suspend HttpResponse.() -> List<ObjectType>,
|
||||||
|
private val updateBodyGetter: suspend HttpResponse.() -> List<ObjectType>
|
||||||
|
) : WriteCRUDRepo<ObjectType, IdType, InputValue> {
|
||||||
|
override suspend fun create(values: List<InputValue>): List<ObjectType> = httpClient.post(
|
||||||
|
buildStandardUrl(baseUrl, createRouting)
|
||||||
|
) {
|
||||||
|
createSetup(values)
|
||||||
|
}.createBodyGetter()
|
||||||
|
|
||||||
|
override suspend fun update(
|
||||||
|
values: List<UpdatedValuePair<IdType, InputValue>>
|
||||||
|
): List<ObjectType> = httpClient.post(
|
||||||
|
buildStandardUrl(baseUrl, updateRouting)
|
||||||
|
) {
|
||||||
|
updateSetup(values)
|
||||||
|
}.updateBodyGetter()
|
||||||
|
|
||||||
|
override suspend fun update(id: IdType, value: InputValue): ObjectType? = update(listOf(id to value)).firstOrNull()
|
||||||
|
|
||||||
|
override suspend fun deleteById(ids: List<IdType>) {
|
||||||
|
httpClient.post(
|
||||||
|
buildStandardUrl(baseUrl, deleteByIdRouting)
|
||||||
|
) {
|
||||||
|
deleteByIdSetup(ids)
|
||||||
|
}.throwOnUnsuccess { "Unable to delete $ids" }
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
inline operator fun <reified ObjectType, reified IdType, reified InputValue> invoke(
|
||||||
|
baseUrl: String,
|
||||||
|
httpClient: HttpClient,
|
||||||
|
contentType: ContentType
|
||||||
|
) = KtorWriteCrudRepoClient<ObjectType, IdType, InputValue>(
|
||||||
|
baseUrl,
|
||||||
|
httpClient,
|
||||||
|
httpClient.createStandardWebsocketFlow(
|
||||||
|
buildStandardUrl(baseUrl, newObjectsFlowRouting),
|
||||||
|
),
|
||||||
|
httpClient.createStandardWebsocketFlow(
|
||||||
|
buildStandardUrl(baseUrl, updatedObjectsFlowRouting),
|
||||||
|
),
|
||||||
|
httpClient.createStandardWebsocketFlow(
|
||||||
|
buildStandardUrl(baseUrl, deletedObjectsIdsFlowRouting),
|
||||||
|
),
|
||||||
|
{
|
||||||
|
contentType(contentType)
|
||||||
|
setBody(it)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
contentType(contentType)
|
||||||
|
setBody(it)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
contentType(contentType)
|
||||||
|
setBody(it)
|
||||||
|
},
|
||||||
|
{ body() },
|
||||||
|
{ body() }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -3,13 +3,14 @@ package dev.inmo.micro_utils.repos.ktor.client.crud
|
|||||||
import dev.inmo.micro_utils.ktor.client.*
|
import dev.inmo.micro_utils.ktor.client.*
|
||||||
import dev.inmo.micro_utils.ktor.common.*
|
import dev.inmo.micro_utils.ktor.common.*
|
||||||
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.WriteCRUDRepo
|
||||||
import dev.inmo.micro_utils.repos.ktor.common.crud.*
|
import dev.inmo.micro_utils.repos.ktor.common.crud.*
|
||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.serialization.KSerializer
|
import kotlinx.serialization.KSerializer
|
||||||
import kotlinx.serialization.builtins.*
|
import kotlinx.serialization.builtins.*
|
||||||
|
|
||||||
|
@Deprecated("Use KtorWriteCRUDRepoClient instead")
|
||||||
class KtorWriteStandardCrudRepo<ObjectType, IdType, InputValue> (
|
class KtorWriteStandardCrudRepo<ObjectType, IdType, InputValue> (
|
||||||
private val baseUrl: String,
|
private val baseUrl: String,
|
||||||
private val unifiedRequester: UnifiedRequester,
|
private val unifiedRequester: UnifiedRequester,
|
||||||
@ -17,7 +18,7 @@ class KtorWriteStandardCrudRepo<ObjectType, IdType, InputValue> (
|
|||||||
private val objectsNullableSerializer: KSerializer<ObjectType?>,
|
private val objectsNullableSerializer: KSerializer<ObjectType?>,
|
||||||
private val inputsSerializer: KSerializer<InputValue>,
|
private val inputsSerializer: KSerializer<InputValue>,
|
||||||
private val idsSerializer: KSerializer<IdType>
|
private val idsSerializer: KSerializer<IdType>
|
||||||
) : WriteStandardCRUDRepo<ObjectType, IdType, InputValue> {
|
) : WriteCRUDRepo<ObjectType, IdType, InputValue> {
|
||||||
private val listObjectsSerializer = ListSerializer(objectsSerializer)
|
private val listObjectsSerializer = ListSerializer(objectsSerializer)
|
||||||
private val listInputSerializer = ListSerializer(inputsSerializer)
|
private val listInputSerializer = ListSerializer(inputsSerializer)
|
||||||
private val listIdsSerializer = ListSerializer(idsSerializer)
|
private val listIdsSerializer = ListSerializer(idsSerializer)
|
||||||
|
@ -0,0 +1,85 @@
|
|||||||
|
package dev.inmo.micro_utils.repos.ktor.client.key.value
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.ktor.common.*
|
||||||
|
import dev.inmo.micro_utils.repos.*
|
||||||
|
import io.ktor.client.HttpClient
|
||||||
|
import io.ktor.http.ContentType
|
||||||
|
import io.ktor.http.encodeURLQueryComponent
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
|
class KtorKeyValueRepoClient<Key, Value> (
|
||||||
|
readDelegate: ReadKeyValueRepo<Key, Value>,
|
||||||
|
writeDelegate: WriteKeyValueRepo<Key, Value>
|
||||||
|
) : KeyValueRepo<Key, Value> by DelegateBasedKeyValueRepo(
|
||||||
|
readDelegate,
|
||||||
|
writeDelegate
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
inline operator fun <reified Key, reified Value> invoke(
|
||||||
|
baseUrl: String,
|
||||||
|
httpClient: HttpClient,
|
||||||
|
contentType: ContentType,
|
||||||
|
noinline idSerializer: suspend (Key) -> String,
|
||||||
|
noinline valueSerializer: suspend (Value) -> String
|
||||||
|
) = KtorKeyValueRepoClient(
|
||||||
|
KtorReadKeyValueRepoClient(
|
||||||
|
baseUrl, httpClient, contentType, idSerializer, valueSerializer
|
||||||
|
),
|
||||||
|
KtorWriteKeyValueRepoClient(
|
||||||
|
baseUrl,
|
||||||
|
httpClient,
|
||||||
|
contentType
|
||||||
|
)
|
||||||
|
)
|
||||||
|
inline operator fun <reified Key, reified Value> invoke(
|
||||||
|
baseUrl: String,
|
||||||
|
subpart: String,
|
||||||
|
httpClient: HttpClient,
|
||||||
|
contentType: ContentType,
|
||||||
|
noinline idSerializer: suspend (Key) -> String,
|
||||||
|
noinline valueSerializer: suspend (Value) -> String
|
||||||
|
) = KtorKeyValueRepoClient(
|
||||||
|
buildStandardUrl(baseUrl, subpart),
|
||||||
|
httpClient,
|
||||||
|
contentType,
|
||||||
|
idSerializer,
|
||||||
|
valueSerializer
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified Key, reified Value> KtorKeyValueRepoClient(
|
||||||
|
baseUrl: String,
|
||||||
|
httpClient: HttpClient,
|
||||||
|
contentType: ContentType,
|
||||||
|
idSerializer: SerializationStrategy<Key>,
|
||||||
|
valueSerializer: SerializationStrategy<Value>,
|
||||||
|
serialFormat: StringFormat,
|
||||||
|
) = KtorKeyValueRepoClient<Key, Value>(
|
||||||
|
baseUrl,
|
||||||
|
httpClient,
|
||||||
|
contentType,
|
||||||
|
{
|
||||||
|
serialFormat.encodeToString(idSerializer, it).encodeURLQueryComponent()
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
serialFormat.encodeToString(valueSerializer, it).encodeURLQueryComponent()
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified Key, reified Value> KtorKeyValueRepoClient(
|
||||||
|
baseUrl: String,
|
||||||
|
httpClient: HttpClient,
|
||||||
|
contentType: ContentType,
|
||||||
|
idSerializer: SerializationStrategy<Key>,
|
||||||
|
valueSerializer: SerializationStrategy<Value>,
|
||||||
|
serialFormat: BinaryFormat,
|
||||||
|
) = KtorKeyValueRepoClient<Key, Value>(
|
||||||
|
baseUrl,
|
||||||
|
httpClient,
|
||||||
|
contentType,
|
||||||
|
{
|
||||||
|
serialFormat.encodeHex(idSerializer, it)
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
serialFormat.encodeHex(valueSerializer, it)
|
||||||
|
}
|
@ -0,0 +1,144 @@
|
|||||||
|
package dev.inmo.micro_utils.repos.ktor.client.key.value
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.ktor.common.*
|
||||||
|
import dev.inmo.micro_utils.pagination.*
|
||||||
|
import dev.inmo.micro_utils.repos.ReadKeyValueRepo
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.*
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.containsRoute
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.keyParameterName
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.key_value.*
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.reversedParameterName
|
||||||
|
import io.ktor.client.HttpClient
|
||||||
|
import io.ktor.client.call.body
|
||||||
|
import io.ktor.client.request.get
|
||||||
|
import io.ktor.http.*
|
||||||
|
import io.ktor.util.reflect.TypeInfo
|
||||||
|
import io.ktor.util.reflect.typeInfo
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
|
class KtorReadKeyValueRepoClient<Key, Value>(
|
||||||
|
private val baseUrl: String,
|
||||||
|
private val httpClient: HttpClient,
|
||||||
|
private val contentType: ContentType,
|
||||||
|
private val objectType: TypeInfo,
|
||||||
|
private val paginationResultObjectsTypeInfo: TypeInfo,
|
||||||
|
private val paginationResultIdsTypeInfo: TypeInfo,
|
||||||
|
private val idSerializer: suspend (Key) -> String,
|
||||||
|
private val valueSerializer: suspend (Value) -> String
|
||||||
|
) : ReadKeyValueRepo<Key, Value> {
|
||||||
|
override suspend fun get(k: Key): Value? = httpClient.get(
|
||||||
|
buildStandardUrl(
|
||||||
|
baseUrl,
|
||||||
|
getRoute,
|
||||||
|
mapOf(
|
||||||
|
keyParameterName to idSerializer(k)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
contentType(contentType)
|
||||||
|
}.takeIf { it.status != HttpStatusCode.NoContent } ?.body<Value>(objectType)
|
||||||
|
|
||||||
|
override suspend fun contains(key: Key): Boolean = httpClient.get(
|
||||||
|
buildStandardUrl(
|
||||||
|
baseUrl,
|
||||||
|
containsRoute,
|
||||||
|
keyParameterName to idSerializer(key)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
contentType(contentType)
|
||||||
|
}.body()
|
||||||
|
|
||||||
|
override suspend fun values(
|
||||||
|
pagination: Pagination,
|
||||||
|
reversed: Boolean
|
||||||
|
): PaginationResult<Value> = httpClient.get(
|
||||||
|
buildStandardUrl(baseUrl, valuesRoute, pagination.asUrlQueryParts + (reversedParameterName to reversed.toString()))
|
||||||
|
) {
|
||||||
|
contentType(contentType)
|
||||||
|
}.body(paginationResultObjectsTypeInfo)
|
||||||
|
|
||||||
|
override suspend fun keys(
|
||||||
|
pagination: Pagination,
|
||||||
|
reversed: Boolean
|
||||||
|
): PaginationResult<Key> = httpClient.get(
|
||||||
|
buildStandardUrl(baseUrl, keysRoute, pagination.asUrlQueryParts + (reversedParameterName to reversed.toString()))
|
||||||
|
) {
|
||||||
|
contentType(contentType)
|
||||||
|
}.body(paginationResultIdsTypeInfo)
|
||||||
|
|
||||||
|
override suspend fun keys(
|
||||||
|
v: Value,
|
||||||
|
pagination: Pagination,
|
||||||
|
reversed: Boolean
|
||||||
|
): PaginationResult<Key> = httpClient.get(
|
||||||
|
buildStandardUrl(
|
||||||
|
baseUrl,
|
||||||
|
keysRoute,
|
||||||
|
pagination.asUrlQueryParts + (reversedParameterName to reversed.toString()) + (valueParameterName to valueSerializer(v))
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
contentType(contentType)
|
||||||
|
}.body(paginationResultIdsTypeInfo)
|
||||||
|
|
||||||
|
override suspend fun count(): Long = httpClient.get(
|
||||||
|
buildStandardUrl(
|
||||||
|
baseUrl,
|
||||||
|
dev.inmo.micro_utils.repos.ktor.common.countRoute
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
contentType(contentType)
|
||||||
|
}.body()
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified Key, reified Value> KtorReadKeyValueRepoClient(
|
||||||
|
baseUrl: String,
|
||||||
|
httpClient: HttpClient,
|
||||||
|
contentType: ContentType,
|
||||||
|
noinline idSerializer: suspend (Key) -> String,
|
||||||
|
noinline valueSerializer: suspend (Value) -> String
|
||||||
|
) = KtorReadKeyValueRepoClient<Key, Value>(
|
||||||
|
baseUrl,
|
||||||
|
httpClient,
|
||||||
|
contentType,
|
||||||
|
typeInfo<Value>(),
|
||||||
|
typeInfo<PaginationResult<Value>>(),
|
||||||
|
typeInfo<PaginationResult<Key>>(),
|
||||||
|
idSerializer,
|
||||||
|
valueSerializer
|
||||||
|
)
|
||||||
|
|
||||||
|
inline fun <reified Key, reified Value> KtorReadKeyValueRepoClient(
|
||||||
|
baseUrl: String,
|
||||||
|
httpClient: HttpClient,
|
||||||
|
idsSerializer: KSerializer<Key>,
|
||||||
|
valueSerializer: KSerializer<Value>,
|
||||||
|
serialFormat: StringFormat,
|
||||||
|
contentType: ContentType,
|
||||||
|
) = KtorReadKeyValueRepoClient<Key, Value>(
|
||||||
|
baseUrl,
|
||||||
|
httpClient,
|
||||||
|
contentType,
|
||||||
|
{
|
||||||
|
serialFormat.encodeToString(idsSerializer, it).encodeURLQueryComponent()
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
serialFormat.encodeToString(valueSerializer, it).encodeURLQueryComponent()
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified Key, reified Value> KtorReadKeyValueRepoClient(
|
||||||
|
baseUrl: String,
|
||||||
|
httpClient: HttpClient,
|
||||||
|
idsSerializer: KSerializer<Key>,
|
||||||
|
valuesSerializer: KSerializer<Value>,
|
||||||
|
serialFormat: BinaryFormat,
|
||||||
|
contentType: ContentType,
|
||||||
|
) = KtorReadKeyValueRepoClient<Key, Value>(
|
||||||
|
baseUrl,
|
||||||
|
httpClient,
|
||||||
|
contentType,
|
||||||
|
{
|
||||||
|
serialFormat.encodeHex(idsSerializer, it)
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
serialFormat.encodeHex(valuesSerializer, it)
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
package dev.inmo.micro_utils.repos.ktor.client.key.value
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.ktor.client.createStandardWebsocketFlow
|
||||||
|
import dev.inmo.micro_utils.ktor.client.throwOnUnsuccess
|
||||||
|
import dev.inmo.micro_utils.ktor.common.*
|
||||||
|
import dev.inmo.micro_utils.repos.WriteKeyValueRepo
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.key_value.*
|
||||||
|
import io.ktor.client.HttpClient
|
||||||
|
import io.ktor.client.request.post
|
||||||
|
import io.ktor.http.*
|
||||||
|
import io.ktor.util.InternalAPI
|
||||||
|
import io.ktor.util.reflect.TypeInfo
|
||||||
|
import io.ktor.util.reflect.typeInfo
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
class KtorWriteKeyValueRepoClient<Key, Value>(
|
||||||
|
private val baseUrl: String,
|
||||||
|
private val httpClient: HttpClient,
|
||||||
|
private val contentType: ContentType,
|
||||||
|
override val onNewValue: Flow<Pair<Key, Value>>,
|
||||||
|
override val onValueRemoved: Flow<Key>,
|
||||||
|
private val idsListTypeInfo: TypeInfo,
|
||||||
|
private val objectsListTypeInfo: TypeInfo,
|
||||||
|
private val idsToObjectsMapTypeInfo: TypeInfo
|
||||||
|
) : WriteKeyValueRepo<Key, Value> {
|
||||||
|
@OptIn(InternalAPI::class)
|
||||||
|
override suspend fun unsetWithValues(toUnset: List<Value>) {
|
||||||
|
httpClient.post(
|
||||||
|
buildStandardUrl(baseUrl, unsetWithValuesRoute)
|
||||||
|
) {
|
||||||
|
body = toUnset
|
||||||
|
bodyType = objectsListTypeInfo
|
||||||
|
contentType(contentType)
|
||||||
|
}.throwOnUnsuccess { "Unable to unset data with values $toUnset" }
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(InternalAPI::class)
|
||||||
|
override suspend fun unset(toUnset: List<Key>) {
|
||||||
|
httpClient.post(
|
||||||
|
buildStandardUrl(baseUrl, unsetRoute)
|
||||||
|
) {
|
||||||
|
body = toUnset
|
||||||
|
bodyType = idsListTypeInfo
|
||||||
|
contentType(contentType)
|
||||||
|
}.throwOnUnsuccess { "Unable to unset $toUnset" }
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(InternalAPI::class)
|
||||||
|
override suspend fun set(toSet: Map<Key, Value>) {
|
||||||
|
httpClient.post(
|
||||||
|
buildStandardUrl(baseUrl, setRoute)
|
||||||
|
) {
|
||||||
|
body = toSet
|
||||||
|
bodyType = idsToObjectsMapTypeInfo
|
||||||
|
contentType(contentType)
|
||||||
|
}.throwOnUnsuccess { "Unable to set $toSet" }
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
inline operator fun <reified Key, reified Value> invoke(
|
||||||
|
baseUrl: String,
|
||||||
|
httpClient: HttpClient,
|
||||||
|
contentType: ContentType
|
||||||
|
) = KtorWriteKeyValueRepoClient<Key, Value>(
|
||||||
|
baseUrl,
|
||||||
|
httpClient,
|
||||||
|
contentType,
|
||||||
|
httpClient.createStandardWebsocketFlow(
|
||||||
|
buildStandardUrl(baseUrl, onNewValueRoute),
|
||||||
|
),
|
||||||
|
httpClient.createStandardWebsocketFlow(
|
||||||
|
buildStandardUrl(baseUrl, onValueRemovedRoute),
|
||||||
|
),
|
||||||
|
typeInfo<List<Key>>(),
|
||||||
|
typeInfo<List<Value>>(),
|
||||||
|
typeInfo<Map<Key, Value>>()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,89 @@
|
|||||||
|
package dev.inmo.micro_utils.repos.ktor.client.key.values
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.ktor.common.*
|
||||||
|
import dev.inmo.micro_utils.repos.*
|
||||||
|
import io.ktor.client.HttpClient
|
||||||
|
import io.ktor.http.ContentType
|
||||||
|
import io.ktor.http.encodeURLQueryComponent
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
|
class KtorKeyValuesRepoClient<Key, Value> (
|
||||||
|
readDelegate: ReadKeyValuesRepo<Key, Value>,
|
||||||
|
writeDelegate: WriteKeyValuesRepo<Key, Value>
|
||||||
|
) : KeyValuesRepo<Key, Value> by DelegateBasedKeyValuesRepo(
|
||||||
|
readDelegate,
|
||||||
|
writeDelegate
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
inline operator fun <reified Key : Any, reified Value : Any> invoke(
|
||||||
|
baseUrl: String,
|
||||||
|
httpClient: HttpClient,
|
||||||
|
contentType: ContentType,
|
||||||
|
noinline keySerializer: suspend (Key) -> String,
|
||||||
|
noinline valueSerializer: suspend (Value) -> String
|
||||||
|
) = KtorKeyValuesRepoClient(
|
||||||
|
KtorReadKeyValuesRepoClient(
|
||||||
|
baseUrl,
|
||||||
|
httpClient,
|
||||||
|
contentType,
|
||||||
|
keySerializer,
|
||||||
|
valueSerializer
|
||||||
|
),
|
||||||
|
KtorWriteKeyValuesRepoClient(
|
||||||
|
baseUrl,
|
||||||
|
httpClient,
|
||||||
|
contentType
|
||||||
|
)
|
||||||
|
)
|
||||||
|
inline operator fun <reified Key : Any, reified Value : Any> invoke(
|
||||||
|
baseUrl: String,
|
||||||
|
subpart: String,
|
||||||
|
httpClient: HttpClient,
|
||||||
|
contentType: ContentType,
|
||||||
|
noinline keySerializer: suspend (Key) -> String,
|
||||||
|
noinline valueSerializer: suspend (Value) -> String
|
||||||
|
) = KtorKeyValuesRepoClient(
|
||||||
|
buildStandardUrl(baseUrl, subpart),
|
||||||
|
httpClient,
|
||||||
|
contentType,
|
||||||
|
keySerializer,
|
||||||
|
valueSerializer
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified Key : Any, reified Value : Any> KtorKeyValuesRepoClient(
|
||||||
|
baseUrl: String,
|
||||||
|
httpClient: HttpClient,
|
||||||
|
contentType: ContentType,
|
||||||
|
keySerializer: SerializationStrategy<Key>,
|
||||||
|
valueSerializer: SerializationStrategy<Value>,
|
||||||
|
serialFormat: StringFormat,
|
||||||
|
) = KtorKeyValuesRepoClient<Key, Value>(
|
||||||
|
baseUrl,
|
||||||
|
httpClient,
|
||||||
|
contentType,
|
||||||
|
{
|
||||||
|
serialFormat.encodeToString(keySerializer, it).encodeURLQueryComponent()
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
serialFormat.encodeToString(valueSerializer, it).encodeURLQueryComponent()
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified Key : Any, reified Value : Any> KtorKeyValuesRepoClient(
|
||||||
|
baseUrl: String,
|
||||||
|
httpClient: HttpClient,
|
||||||
|
contentType: ContentType,
|
||||||
|
keySerializer: SerializationStrategy<Key>,
|
||||||
|
valueSerializer: SerializationStrategy<Value>,
|
||||||
|
serialFormat: BinaryFormat,
|
||||||
|
) = KtorKeyValuesRepoClient<Key, Value>(
|
||||||
|
baseUrl,
|
||||||
|
httpClient,
|
||||||
|
contentType,
|
||||||
|
{
|
||||||
|
serialFormat.encodeHex(keySerializer, it)
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
serialFormat.encodeHex(valueSerializer, it)
|
||||||
|
}
|
@ -0,0 +1,158 @@
|
|||||||
|
package dev.inmo.micro_utils.repos.ktor.client.key.values
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.ktor.common.*
|
||||||
|
import dev.inmo.micro_utils.pagination.*
|
||||||
|
import dev.inmo.micro_utils.repos.ReadKeyValuesRepo
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.*
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.one_to_many.*
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.reversedParameterName
|
||||||
|
import io.ktor.client.HttpClient
|
||||||
|
import io.ktor.client.call.body
|
||||||
|
import io.ktor.client.request.get
|
||||||
|
import io.ktor.http.*
|
||||||
|
import io.ktor.util.reflect.TypeInfo
|
||||||
|
import io.ktor.util.reflect.typeInfo
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
|
class KtorReadKeyValuesRepoClient<Key, Value>(
|
||||||
|
private val baseUrl: String,
|
||||||
|
private val httpClient: HttpClient,
|
||||||
|
private val contentType: ContentType,
|
||||||
|
private val paginationResultValuesTypeInfo: TypeInfo,
|
||||||
|
private val paginationResultKeysTypeInfo: TypeInfo,
|
||||||
|
private val keySerializer: suspend (Key) -> String,
|
||||||
|
private val valueSerializer: suspend (Value) -> String
|
||||||
|
) : ReadKeyValuesRepo<Key, Value> {
|
||||||
|
override suspend fun get(
|
||||||
|
k: Key,
|
||||||
|
pagination: Pagination,
|
||||||
|
reversed: Boolean
|
||||||
|
): PaginationResult<Value> = httpClient.get(
|
||||||
|
buildStandardUrl(
|
||||||
|
baseUrl,
|
||||||
|
getRoute,
|
||||||
|
pagination.asUrlQueryParts + (reversedParameterName to reversed.toString()) + (keyParameterName to keySerializer(k))
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
contentType(contentType)
|
||||||
|
}.body(paginationResultValuesTypeInfo)
|
||||||
|
|
||||||
|
override suspend fun keys(
|
||||||
|
pagination: Pagination,
|
||||||
|
reversed: Boolean
|
||||||
|
): PaginationResult<Key> = httpClient.get(
|
||||||
|
buildStandardUrl(
|
||||||
|
baseUrl,
|
||||||
|
keysRoute,
|
||||||
|
pagination.asUrlQueryParts + (reversedParameterName to reversed.toString())
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
contentType(contentType)
|
||||||
|
}.body(paginationResultKeysTypeInfo)
|
||||||
|
|
||||||
|
override suspend fun keys(
|
||||||
|
v: Value,
|
||||||
|
pagination: Pagination,
|
||||||
|
reversed: Boolean
|
||||||
|
): PaginationResult<Key> = httpClient.get(
|
||||||
|
buildStandardUrl(
|
||||||
|
baseUrl,
|
||||||
|
keysRoute,
|
||||||
|
pagination.asUrlQueryParts + (reversedParameterName to reversed.toString()) + (valueParameterName to valueSerializer(v))
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
contentType(contentType)
|
||||||
|
}.body(paginationResultKeysTypeInfo)
|
||||||
|
|
||||||
|
override suspend fun contains(k: Key): Boolean = httpClient.get(
|
||||||
|
buildStandardUrl(
|
||||||
|
baseUrl,
|
||||||
|
containsRoute,
|
||||||
|
keyParameterName to keySerializer(k)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
contentType(contentType)
|
||||||
|
}.body()
|
||||||
|
|
||||||
|
override suspend fun contains(k: Key, v: Value): Boolean = httpClient.get(
|
||||||
|
buildStandardUrl(
|
||||||
|
baseUrl,
|
||||||
|
containsRoute,
|
||||||
|
keyParameterName to keySerializer(k),
|
||||||
|
valueParameterName to valueSerializer(v)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
contentType(contentType)
|
||||||
|
}.body()
|
||||||
|
|
||||||
|
override suspend fun count(): Long = httpClient.get(
|
||||||
|
buildStandardUrl(
|
||||||
|
baseUrl,
|
||||||
|
countRouting
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
contentType(contentType)
|
||||||
|
}.body()
|
||||||
|
|
||||||
|
override suspend fun count(k: Key): Long = httpClient.get(
|
||||||
|
buildStandardUrl(
|
||||||
|
baseUrl,
|
||||||
|
countRouting,
|
||||||
|
keyParameterName to keySerializer(k),
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
contentType(contentType)
|
||||||
|
}.body()
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified Key, reified Value> KtorReadKeyValuesRepoClient(
|
||||||
|
baseUrl: String,
|
||||||
|
httpClient: HttpClient,
|
||||||
|
contentType: ContentType,
|
||||||
|
noinline keySerializer: suspend (Key) -> String,
|
||||||
|
noinline valueSerializer: suspend (Value) -> String
|
||||||
|
) = KtorReadKeyValuesRepoClient<Key, Value>(
|
||||||
|
baseUrl,
|
||||||
|
httpClient,
|
||||||
|
contentType,
|
||||||
|
typeInfo<PaginationResult<Value>>(),
|
||||||
|
typeInfo<PaginationResult<Key>>(),
|
||||||
|
keySerializer,
|
||||||
|
valueSerializer
|
||||||
|
)
|
||||||
|
|
||||||
|
inline fun <reified Key, reified Value> KtorReadKeyValuesRepoClient(
|
||||||
|
baseUrl: String,
|
||||||
|
httpClient: HttpClient,
|
||||||
|
idsSerializer: KSerializer<Key>,
|
||||||
|
valueSerializer: KSerializer<Value>,
|
||||||
|
serialFormat: StringFormat,
|
||||||
|
contentType: ContentType,
|
||||||
|
) = KtorReadKeyValuesRepoClient<Key, Value>(
|
||||||
|
baseUrl,
|
||||||
|
httpClient,
|
||||||
|
contentType,
|
||||||
|
{
|
||||||
|
serialFormat.encodeToString(idsSerializer, it).encodeURLQueryComponent()
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
serialFormat.encodeToString(valueSerializer, it).encodeURLQueryComponent()
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified Key, reified Value> KtorReadKeyValuesRepoClient(
|
||||||
|
baseUrl: String,
|
||||||
|
httpClient: HttpClient,
|
||||||
|
idsSerializer: KSerializer<Key>,
|
||||||
|
valuesSerializer: KSerializer<Value>,
|
||||||
|
serialFormat: BinaryFormat,
|
||||||
|
contentType: ContentType,
|
||||||
|
) = KtorReadKeyValuesRepoClient<Key, Value>(
|
||||||
|
baseUrl,
|
||||||
|
httpClient,
|
||||||
|
contentType,
|
||||||
|
{
|
||||||
|
serialFormat.encodeHex(idsSerializer, it)
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
serialFormat.encodeHex(valuesSerializer, it)
|
||||||
|
}
|
@ -0,0 +1,106 @@
|
|||||||
|
package dev.inmo.micro_utils.repos.ktor.client.key.values
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.ktor.client.createStandardWebsocketFlow
|
||||||
|
import dev.inmo.micro_utils.ktor.client.throwOnUnsuccess
|
||||||
|
import dev.inmo.micro_utils.ktor.common.*
|
||||||
|
import dev.inmo.micro_utils.repos.WriteKeyValuesRepo
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.one_to_many.*
|
||||||
|
import io.ktor.client.HttpClient
|
||||||
|
import io.ktor.client.request.post
|
||||||
|
import io.ktor.http.*
|
||||||
|
import io.ktor.util.InternalAPI
|
||||||
|
import io.ktor.util.reflect.TypeInfo
|
||||||
|
import io.ktor.util.reflect.typeInfo
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
class KtorWriteKeyValuesRepoClient<Key : Any, Value : Any>(
|
||||||
|
private val baseUrl: String,
|
||||||
|
private val httpClient: HttpClient,
|
||||||
|
private val contentType: ContentType,
|
||||||
|
override val onNewValue: Flow<Pair<Key, Value>>,
|
||||||
|
override val onValueRemoved: Flow<Pair<Key, Value>>,
|
||||||
|
override val onDataCleared: Flow<Key>,
|
||||||
|
private val keyTypeInfo: TypeInfo,
|
||||||
|
private val valueTypeInfo: TypeInfo,
|
||||||
|
private val keyToValuesMapTypeInfo: TypeInfo
|
||||||
|
) : WriteKeyValuesRepo<Key, Value> {
|
||||||
|
|
||||||
|
@OptIn(InternalAPI::class)
|
||||||
|
override suspend fun add(toAdd: Map<Key, List<Value>>) {
|
||||||
|
httpClient.post(
|
||||||
|
buildStandardUrl(baseUrl, addRoute)
|
||||||
|
) {
|
||||||
|
body = toAdd
|
||||||
|
bodyType = keyToValuesMapTypeInfo
|
||||||
|
contentType(contentType)
|
||||||
|
}.throwOnUnsuccess { "Unable to add $toAdd" }
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(InternalAPI::class)
|
||||||
|
override suspend fun remove(toRemove: Map<Key, List<Value>>) {
|
||||||
|
httpClient.post(
|
||||||
|
buildStandardUrl(baseUrl, removeRoute)
|
||||||
|
) {
|
||||||
|
body = toRemove
|
||||||
|
bodyType = keyToValuesMapTypeInfo
|
||||||
|
contentType(contentType)
|
||||||
|
}.throwOnUnsuccess { "Unable to remove $toRemove" }
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(InternalAPI::class)
|
||||||
|
override suspend fun clear(k: Key) {
|
||||||
|
httpClient.post(
|
||||||
|
buildStandardUrl(baseUrl, clearRoute)
|
||||||
|
) {
|
||||||
|
body = k
|
||||||
|
bodyType = keyTypeInfo
|
||||||
|
contentType(contentType)
|
||||||
|
}.throwOnUnsuccess { "Unable to clear data with key $k" }
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(InternalAPI::class)
|
||||||
|
override suspend fun clearWithValue(v: Value) {
|
||||||
|
httpClient.post(
|
||||||
|
buildStandardUrl(baseUrl, clearWithValueRoute)
|
||||||
|
) {
|
||||||
|
body = v
|
||||||
|
bodyType = valueTypeInfo
|
||||||
|
contentType(contentType)
|
||||||
|
}.throwOnUnsuccess { "Unable to clear data with value $v" }
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(InternalAPI::class)
|
||||||
|
override suspend fun set(toSet: Map<Key, List<Value>>) {
|
||||||
|
httpClient.post(
|
||||||
|
buildStandardUrl(baseUrl, setRoute)
|
||||||
|
) {
|
||||||
|
body = toSet
|
||||||
|
bodyType = keyToValuesMapTypeInfo
|
||||||
|
contentType(contentType)
|
||||||
|
}.throwOnUnsuccess { "Unable to set data $toSet" }
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
inline operator fun <reified Key : Any, reified Value : Any> invoke(
|
||||||
|
baseUrl: String,
|
||||||
|
httpClient: HttpClient,
|
||||||
|
contentType: ContentType
|
||||||
|
) = KtorWriteKeyValuesRepoClient<Key, Value>(
|
||||||
|
baseUrl,
|
||||||
|
httpClient,
|
||||||
|
contentType,
|
||||||
|
httpClient.createStandardWebsocketFlow(
|
||||||
|
buildStandardUrl(baseUrl, onNewValueRoute),
|
||||||
|
),
|
||||||
|
httpClient.createStandardWebsocketFlow(
|
||||||
|
buildStandardUrl(baseUrl, onValueRemovedRoute),
|
||||||
|
),
|
||||||
|
httpClient.createStandardWebsocketFlow(
|
||||||
|
buildStandardUrl(baseUrl, onDataClearedRoute),
|
||||||
|
),
|
||||||
|
typeInfo<Key>(),
|
||||||
|
typeInfo<Value>(),
|
||||||
|
typeInfo<Map<Key, List<Value>>>()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -3,20 +3,25 @@ package dev.inmo.micro_utils.repos.ktor.client.key_value
|
|||||||
import dev.inmo.micro_utils.ktor.client.*
|
import dev.inmo.micro_utils.ktor.client.*
|
||||||
import dev.inmo.micro_utils.ktor.common.*
|
import dev.inmo.micro_utils.ktor.common.*
|
||||||
import dev.inmo.micro_utils.pagination.*
|
import dev.inmo.micro_utils.pagination.*
|
||||||
import dev.inmo.micro_utils.repos.ReadStandardKeyValueRepo
|
import dev.inmo.micro_utils.repos.ReadKeyValueRepo
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.*
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.containsRoute
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.countRoute
|
||||||
import dev.inmo.micro_utils.repos.ktor.common.key_value.*
|
import dev.inmo.micro_utils.repos.ktor.common.key_value.*
|
||||||
import dev.inmo.micro_utils.repos.ktor.common.valueParameterName
|
import dev.inmo.micro_utils.repos.ktor.common.key_value.keyParameterName
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.key_value.reversedParameterName
|
||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
import kotlinx.serialization.builtins.serializer
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
|
||||||
|
@Deprecated("Replaced with KtorReadKeyValueRepoClient")
|
||||||
class KtorReadStandardKeyValueRepo<Key, Value> (
|
class KtorReadStandardKeyValueRepo<Key, Value> (
|
||||||
private val baseUrl: String,
|
private val baseUrl: String,
|
||||||
private val unifiedRequester: UnifiedRequester,
|
private val unifiedRequester: UnifiedRequester,
|
||||||
private val keySerializer: KSerializer<Key>,
|
private val keySerializer: KSerializer<Key>,
|
||||||
private val valueSerializer: KSerializer<Value>,
|
private val valueSerializer: KSerializer<Value>,
|
||||||
private val valueNullableSerializer: KSerializer<Value?>
|
private val valueNullableSerializer: KSerializer<Value?>
|
||||||
) : ReadStandardKeyValueRepo<Key, Value> {
|
) : ReadKeyValueRepo<Key, Value> {
|
||||||
constructor(
|
constructor(
|
||||||
baseUrl: String,
|
baseUrl: String,
|
||||||
client: HttpClient,
|
client: HttpClient,
|
||||||
|
@ -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.*
|
||||||
|
|
||||||
|
@Deprecated("Replaced with KtorKeyValueRepoClient")
|
||||||
@Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE")
|
@Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE")
|
||||||
class KtorStandartKeyValueRepo<K, V> (
|
class KtorStandartKeyValueRepo<K, V> (
|
||||||
baseUrl: String,
|
baseUrl: String,
|
||||||
@ -15,15 +16,15 @@ class KtorStandartKeyValueRepo<K, V> (
|
|||||||
keySerializer: KSerializer<K>,
|
keySerializer: KSerializer<K>,
|
||||||
valueSerializer: KSerializer<V>,
|
valueSerializer: KSerializer<V>,
|
||||||
valueNullableSerializer: KSerializer<V?>
|
valueNullableSerializer: KSerializer<V?>
|
||||||
) : StandardKeyValueRepo<K, V>,
|
) : KeyValueRepo<K, V>,
|
||||||
ReadStandardKeyValueRepo<K, V> by KtorReadStandardKeyValueRepo(
|
ReadKeyValueRepo<K, V> by KtorReadStandardKeyValueRepo(
|
||||||
"$baseUrl/$baseSubpart",
|
"$baseUrl/$baseSubpart",
|
||||||
unifiedRequester,
|
unifiedRequester,
|
||||||
keySerializer,
|
keySerializer,
|
||||||
valueSerializer,
|
valueSerializer,
|
||||||
valueNullableSerializer
|
valueNullableSerializer
|
||||||
),
|
),
|
||||||
WriteStandardKeyValueRepo<K, V> by KtorWriteStandardKeyValueRepo(
|
WriteKeyValueRepo<K, V> by KtorWriteStandardKeyValueRepo(
|
||||||
"$baseUrl/$baseSubpart",
|
"$baseUrl/$baseSubpart",
|
||||||
unifiedRequester,
|
unifiedRequester,
|
||||||
keySerializer,
|
keySerializer,
|
||||||
|
@ -2,19 +2,20 @@ package dev.inmo.micro_utils.repos.ktor.client.key_value
|
|||||||
|
|
||||||
import dev.inmo.micro_utils.ktor.client.*
|
import dev.inmo.micro_utils.ktor.client.*
|
||||||
import dev.inmo.micro_utils.ktor.common.*
|
import dev.inmo.micro_utils.ktor.common.*
|
||||||
import dev.inmo.micro_utils.repos.WriteStandardKeyValueRepo
|
import dev.inmo.micro_utils.repos.WriteKeyValueRepo
|
||||||
import dev.inmo.micro_utils.repos.ktor.common.key_value.*
|
import dev.inmo.micro_utils.repos.ktor.common.key_value.*
|
||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.serialization.KSerializer
|
import kotlinx.serialization.KSerializer
|
||||||
import kotlinx.serialization.builtins.*
|
import kotlinx.serialization.builtins.*
|
||||||
|
|
||||||
|
@Deprecated("Replaced with KtorWriteKeyValueRepoClient")
|
||||||
class KtorWriteStandardKeyValueRepo<K, V> (
|
class KtorWriteStandardKeyValueRepo<K, V> (
|
||||||
private var baseUrl: String,
|
private var baseUrl: String,
|
||||||
private var unifiedRequester: UnifiedRequester,
|
private var unifiedRequester: UnifiedRequester,
|
||||||
private var keySerializer: KSerializer<K>,
|
private var keySerializer: KSerializer<K>,
|
||||||
private var valueSerializer: KSerializer<V>,
|
private var valueSerializer: KSerializer<V>,
|
||||||
) : WriteStandardKeyValueRepo<K, V> {
|
) : WriteKeyValueRepo<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)
|
private val valuesListSerializer = ListSerializer(valueSerializer)
|
||||||
|
@ -7,20 +7,21 @@ import dev.inmo.micro_utils.repos.*
|
|||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
import kotlinx.serialization.KSerializer
|
import kotlinx.serialization.KSerializer
|
||||||
|
|
||||||
|
@Deprecated("Should be replaced with KtorKeyValuesRepoClient")
|
||||||
class KtorOneToManyKeyValueRepo<Key, Value>(
|
class KtorOneToManyKeyValueRepo<Key, Value>(
|
||||||
baseUrl: String,
|
baseUrl: String,
|
||||||
baseSubpart: String,
|
baseSubpart: String,
|
||||||
unifiedRequester: UnifiedRequester,
|
unifiedRequester: UnifiedRequester,
|
||||||
keySerializer: KSerializer<Key>,
|
keySerializer: KSerializer<Key>,
|
||||||
valueSerializer: KSerializer<Value>,
|
valueSerializer: KSerializer<Value>,
|
||||||
) : OneToManyKeyValueRepo<Key, Value>,
|
) : KeyValuesRepo<Key, Value>,
|
||||||
ReadOneToManyKeyValueRepo<Key, Value> by KtorReadOneToManyKeyValueRepo<Key, Value> (
|
ReadKeyValuesRepo<Key, Value> by KtorReadOneToManyKeyValueRepo<Key, Value> (
|
||||||
"$baseUrl/$baseSubpart",
|
"$baseUrl/$baseSubpart",
|
||||||
unifiedRequester,
|
unifiedRequester,
|
||||||
keySerializer,
|
keySerializer,
|
||||||
valueSerializer,
|
valueSerializer,
|
||||||
),
|
),
|
||||||
WriteOneToManyKeyValueRepo<Key, Value> by KtorWriteOneToManyKeyValueRepo<Key, Value> (
|
WriteKeyValuesRepo<Key, Value> by KtorWriteOneToManyKeyValueRepo<Key, Value> (
|
||||||
"$baseUrl/$baseSubpart",
|
"$baseUrl/$baseSubpart",
|
||||||
unifiedRequester,
|
unifiedRequester,
|
||||||
keySerializer,
|
keySerializer,
|
||||||
|
@ -3,7 +3,7 @@ package dev.inmo.micro_utils.repos.ktor.client.one_to_many
|
|||||||
import dev.inmo.micro_utils.ktor.client.*
|
import dev.inmo.micro_utils.ktor.client.*
|
||||||
import dev.inmo.micro_utils.ktor.common.*
|
import dev.inmo.micro_utils.ktor.common.*
|
||||||
import dev.inmo.micro_utils.pagination.*
|
import dev.inmo.micro_utils.pagination.*
|
||||||
import dev.inmo.micro_utils.repos.ReadOneToManyKeyValueRepo
|
import dev.inmo.micro_utils.repos.ReadKeyValuesRepo
|
||||||
import dev.inmo.micro_utils.repos.ktor.common.keyParameterName
|
import dev.inmo.micro_utils.repos.ktor.common.keyParameterName
|
||||||
import dev.inmo.micro_utils.repos.ktor.common.one_to_many.*
|
import dev.inmo.micro_utils.repos.ktor.common.one_to_many.*
|
||||||
import dev.inmo.micro_utils.repos.ktor.common.reversedParameterName
|
import dev.inmo.micro_utils.repos.ktor.common.reversedParameterName
|
||||||
@ -12,12 +12,13 @@ import io.ktor.client.HttpClient
|
|||||||
import kotlinx.serialization.KSerializer
|
import kotlinx.serialization.KSerializer
|
||||||
import kotlinx.serialization.builtins.serializer
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
|
||||||
|
@Deprecated("Should be replaced with KtorReadKeyValuesRepoClient")
|
||||||
class KtorReadOneToManyKeyValueRepo<Key, Value> (
|
class KtorReadOneToManyKeyValueRepo<Key, Value> (
|
||||||
private val baseUrl: String,
|
private val baseUrl: String,
|
||||||
private val unifiedRequester: UnifiedRequester,
|
private val unifiedRequester: UnifiedRequester,
|
||||||
private val keySerializer: KSerializer<Key>,
|
private val keySerializer: KSerializer<Key>,
|
||||||
private val valueSerializer: KSerializer<Value>
|
private val valueSerializer: KSerializer<Value>
|
||||||
) : ReadOneToManyKeyValueRepo<Key, Value> {
|
) : ReadKeyValuesRepo<Key, Value> {
|
||||||
private val paginationValueResultSerializer = PaginationResult.serializer(valueSerializer)
|
private val paginationValueResultSerializer = PaginationResult.serializer(valueSerializer)
|
||||||
private val paginationKeyResultSerializer = PaginationResult.serializer(keySerializer)
|
private val paginationKeyResultSerializer = PaginationResult.serializer(keySerializer)
|
||||||
|
|
||||||
|
@ -2,19 +2,20 @@ package dev.inmo.micro_utils.repos.ktor.client.one_to_many
|
|||||||
|
|
||||||
import dev.inmo.micro_utils.ktor.client.*
|
import dev.inmo.micro_utils.ktor.client.*
|
||||||
import dev.inmo.micro_utils.ktor.common.*
|
import dev.inmo.micro_utils.ktor.common.*
|
||||||
import dev.inmo.micro_utils.repos.WriteOneToManyKeyValueRepo
|
import dev.inmo.micro_utils.repos.WriteKeyValuesRepo
|
||||||
import dev.inmo.micro_utils.repos.ktor.common.one_to_many.*
|
import dev.inmo.micro_utils.repos.ktor.common.one_to_many.*
|
||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.serialization.KSerializer
|
import kotlinx.serialization.KSerializer
|
||||||
import kotlinx.serialization.builtins.*
|
import kotlinx.serialization.builtins.*
|
||||||
|
|
||||||
|
@Deprecated("Should be replaced with KtorWriteKeyValuesRepoClient")
|
||||||
class KtorWriteOneToManyKeyValueRepo<Key, Value> (
|
class KtorWriteOneToManyKeyValueRepo<Key, Value> (
|
||||||
private val baseUrl: String,
|
private val baseUrl: String,
|
||||||
private val unifiedRequester: UnifiedRequester,
|
private val unifiedRequester: UnifiedRequester,
|
||||||
private val keySerializer: KSerializer<Key>,
|
private val keySerializer: KSerializer<Key>,
|
||||||
private val valueSerializer: KSerializer<Value>
|
private val valueSerializer: KSerializer<Value>
|
||||||
) : WriteOneToManyKeyValueRepo<Key, Value> {
|
) : WriteKeyValuesRepo<Key, Value> {
|
||||||
private val keyValueSerializer = PairSerializer(keySerializer, valueSerializer)
|
private val keyValueSerializer = PairSerializer(keySerializer, valueSerializer)
|
||||||
private val keyValueMapSerializer = MapSerializer(keySerializer, ListSerializer(valueSerializer))
|
private val keyValueMapSerializer = MapSerializer(keySerializer, ListSerializer(valueSerializer))
|
||||||
|
|
||||||
|
@ -13,5 +13,22 @@ kotlin {
|
|||||||
api internalProject("micro_utils.repos.common")
|
api internalProject("micro_utils.repos.common")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
jvmTest {
|
||||||
|
dependencies {
|
||||||
|
implementation internalProject("micro_utils.repos.common")
|
||||||
|
implementation internalProject("micro_utils.repos.ktor.client")
|
||||||
|
implementation internalProject("micro_utils.repos.ktor.server")
|
||||||
|
implementation internalProject("micro_utils.repos.inmemory")
|
||||||
|
implementation libs.kt.coroutines.test
|
||||||
|
|
||||||
|
implementation libs.ktor.server.cio
|
||||||
|
implementation libs.ktor.client.cio
|
||||||
|
implementation libs.ktor.server.content.negotiation
|
||||||
|
implementation libs.ktor.serialization.kotlinx.json
|
||||||
|
implementation libs.ktor.client.content.negotiation
|
||||||
|
implementation libs.ktor.client.logging
|
||||||
|
implementation libs.ktor.client.websockets
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
package dev.inmo.micro_utils.repos.ktor.common
|
||||||
|
|
||||||
|
const val containsRoute = "contains"
|
@ -0,0 +1,3 @@
|
|||||||
|
package dev.inmo.micro_utils.repos.ktor.common
|
||||||
|
|
||||||
|
const val countRoute = "count"
|
@ -0,0 +1,3 @@
|
|||||||
|
package dev.inmo.micro_utils.repos.ktor.common
|
||||||
|
|
||||||
|
const val countRouting = "count"
|
@ -1,5 +1,6 @@
|
|||||||
package dev.inmo.micro_utils.repos.ktor.common
|
package dev.inmo.micro_utils.repos.ktor.common
|
||||||
|
|
||||||
|
const val idParameterName = "id"
|
||||||
const val keyParameterName = "key"
|
const val keyParameterName = "key"
|
||||||
const val valueParameterName = "value"
|
const val valueParameterName = "value"
|
||||||
const val reversedParameterName = "reversed"
|
const val reversedParameterName = "reversed"
|
@ -3,4 +3,3 @@ package dev.inmo.micro_utils.repos.ktor.common.crud
|
|||||||
const val getByPaginationRouting = "getByPagination"
|
const val getByPaginationRouting = "getByPagination"
|
||||||
const val getByIdRouting = "getById"
|
const val getByIdRouting = "getById"
|
||||||
const val containsRouting = "contains"
|
const val containsRouting = "contains"
|
||||||
const val countRouting = "count"
|
|
||||||
|
@ -3,8 +3,8 @@ package dev.inmo.micro_utils.repos.ktor.common.key_value
|
|||||||
const val getRoute = "get"
|
const val getRoute = "get"
|
||||||
const val valuesRoute = "values"
|
const val valuesRoute = "values"
|
||||||
const val keysRoute = "keys"
|
const val keysRoute = "keys"
|
||||||
const val containsRoute = "contains"
|
const val containsRoute = dev.inmo.micro_utils.repos.ktor.common.containsRoute
|
||||||
const val countRoute = "count"
|
const val countRoute = dev.inmo.micro_utils.repos.ktor.common.countRoute
|
||||||
|
|
||||||
const val onNewValueRoute = "onNewValue"
|
const val onNewValueRoute = "onNewValue"
|
||||||
const val onValueRemovedRoute = "onValueRemoved"
|
const val onValueRemovedRoute = "onValueRemoved"
|
||||||
|
@ -5,7 +5,7 @@ const val keysRoute = "keys"
|
|||||||
const val containsByKeyRoute = "containsByKey"
|
const val containsByKeyRoute = "containsByKey"
|
||||||
const val containsByKeyValueRoute = "containsByKeyValue"
|
const val containsByKeyValueRoute = "containsByKeyValue"
|
||||||
const val countByKeyRoute = "countByKey"
|
const val countByKeyRoute = "countByKey"
|
||||||
const val countRoute = "count"
|
const val countRoute = dev.inmo.micro_utils.repos.ktor.common.countRoute
|
||||||
|
|
||||||
const val onNewValueRoute = "onNewValue"
|
const val onNewValueRoute = "onNewValue"
|
||||||
const val onValueRemovedRoute = "onValueRemoved"
|
const val onValueRemovedRoute = "onValueRemoved"
|
||||||
|
89
repos/ktor/common/src/jvmTest/kotlin/CRUDTests.kt
Normal file
89
repos/ktor/common/src/jvmTest/kotlin/CRUDTests.kt
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
import dev.inmo.micro_utils.repos.*
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.client.crud.KtorCRUDRepoClient
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.server.crud.configureCRUDRepoRoutes
|
||||||
|
import io.ktor.client.HttpClient
|
||||||
|
import io.ktor.client.plugins.logging.Logging
|
||||||
|
import io.ktor.http.ContentType
|
||||||
|
import io.ktor.serialization.kotlinx.KotlinxWebsocketSerializationConverter
|
||||||
|
import io.ktor.serialization.kotlinx.json.json
|
||||||
|
import io.ktor.server.application.install
|
||||||
|
import io.ktor.server.cio.CIO
|
||||||
|
import io.ktor.server.plugins.contentnegotiation.ContentNegotiation
|
||||||
|
import io.ktor.server.routing.routing
|
||||||
|
import io.ktor.server.websocket.WebSockets
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class CRUDTests {
|
||||||
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
@Test
|
||||||
|
fun testCRUDFunctions() {
|
||||||
|
runTest {
|
||||||
|
val map = mutableMapOf<Int, ComplexData>()
|
||||||
|
val repo = MapCRUDRepo<ComplexData, Int, SimpleData>(
|
||||||
|
map,
|
||||||
|
{ newValue, id, oldValue ->
|
||||||
|
oldValue.copy(title = newValue.title)
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
size to ComplexData(size, title = it.title)
|
||||||
|
}
|
||||||
|
val server = io.ktor.server.engine.embeddedServer(
|
||||||
|
CIO,
|
||||||
|
23456,
|
||||||
|
"127.0.0.1"
|
||||||
|
) {
|
||||||
|
install(ContentNegotiation) {
|
||||||
|
json()
|
||||||
|
}
|
||||||
|
install(WebSockets) {
|
||||||
|
contentConverter = KotlinxWebsocketSerializationConverter(Json)
|
||||||
|
}
|
||||||
|
routing {
|
||||||
|
configureCRUDRepoRoutes(
|
||||||
|
repo
|
||||||
|
) {
|
||||||
|
it.toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.start(false)
|
||||||
|
val client = HttpClient {
|
||||||
|
install(io.ktor.client.plugins.contentnegotiation.ContentNegotiation) {
|
||||||
|
json()
|
||||||
|
}
|
||||||
|
install(Logging)
|
||||||
|
install(io.ktor.client.plugins.websocket.WebSockets) {
|
||||||
|
contentConverter = KotlinxWebsocketSerializationConverter(Json)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val crudClient = KtorCRUDRepoClient<ComplexData, Int, SimpleData>(
|
||||||
|
"http://127.0.0.1:23456",
|
||||||
|
client,
|
||||||
|
ContentType.Application.Json
|
||||||
|
) {
|
||||||
|
it.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
val created = crudClient.create(SimpleData("Example")).single()
|
||||||
|
assertEquals(map.size, 1)
|
||||||
|
assertEquals(map.size.toLong(), crudClient.count())
|
||||||
|
assertEquals(1, crudClient.count())
|
||||||
|
assertEquals(map.getValue(map.keys.first()), created)
|
||||||
|
|
||||||
|
val updated = crudClient.update(created.id, SimpleData("Example2"))
|
||||||
|
assertEquals(map.size, 1)
|
||||||
|
assertEquals(map.size.toLong(), crudClient.count())
|
||||||
|
assertEquals(1, crudClient.count())
|
||||||
|
assertEquals(map.getValue(map.keys.first()), updated)
|
||||||
|
|
||||||
|
crudClient.deleteById(created.id)
|
||||||
|
assertEquals(map.size, 0)
|
||||||
|
assertEquals(map.size.toLong(), crudClient.count())
|
||||||
|
assertEquals(0, crudClient.count())
|
||||||
|
server.stop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10
repos/ktor/common/src/jvmTest/kotlin/ComplexData.kt
Normal file
10
repos/ktor/common/src/jvmTest/kotlin/ComplexData.kt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import com.benasher44.uuid.uuid4
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class ComplexData(
|
||||||
|
val id: Int,
|
||||||
|
val simple: SimpleData = SimpleData(),
|
||||||
|
val simples: List<SimpleData> = (0 until 100).map { SimpleData(("$it")) },
|
||||||
|
val title: String = uuid4().toString()
|
||||||
|
)
|
139
repos/ktor/common/src/jvmTest/kotlin/KVTests.kt
Normal file
139
repos/ktor/common/src/jvmTest/kotlin/KVTests.kt
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
import dev.inmo.micro_utils.pagination.firstPageWithOneElementPagination
|
||||||
|
import dev.inmo.micro_utils.pagination.utils.getAllWithNextPaging
|
||||||
|
import dev.inmo.micro_utils.repos.*
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.client.key.value.KtorKeyValueRepoClient
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.server.key.value.configureKeyValueRepoRoutes
|
||||||
|
import io.ktor.client.HttpClient
|
||||||
|
import io.ktor.client.plugins.logging.Logging
|
||||||
|
import io.ktor.http.ContentType
|
||||||
|
import io.ktor.serialization.kotlinx.KotlinxWebsocketSerializationConverter
|
||||||
|
import io.ktor.serialization.kotlinx.json.json
|
||||||
|
import io.ktor.server.application.install
|
||||||
|
import io.ktor.server.cio.CIO
|
||||||
|
import io.ktor.server.plugins.contentnegotiation.ContentNegotiation
|
||||||
|
import io.ktor.server.routing.routing
|
||||||
|
import io.ktor.server.websocket.WebSockets
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlin.test.*
|
||||||
|
|
||||||
|
class KVTests {
|
||||||
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
@Test
|
||||||
|
fun testKVFunctions() {
|
||||||
|
runTest {
|
||||||
|
val map = mutableMapOf<Int, ComplexData>()
|
||||||
|
val repo = MapKeyValueRepo<Int, ComplexData>(map)
|
||||||
|
val server = io.ktor.server.engine.embeddedServer(
|
||||||
|
CIO,
|
||||||
|
23456,
|
||||||
|
"127.0.0.1"
|
||||||
|
) {
|
||||||
|
install(ContentNegotiation) {
|
||||||
|
json()
|
||||||
|
}
|
||||||
|
install(WebSockets) {
|
||||||
|
contentConverter = KotlinxWebsocketSerializationConverter(Json)
|
||||||
|
}
|
||||||
|
routing {
|
||||||
|
configureKeyValueRepoRoutes(
|
||||||
|
repo,
|
||||||
|
Int.serializer(),
|
||||||
|
ComplexData.serializer(),
|
||||||
|
Json {}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}.start(false)
|
||||||
|
val client = HttpClient {
|
||||||
|
install(io.ktor.client.plugins.contentnegotiation.ContentNegotiation) {
|
||||||
|
json()
|
||||||
|
}
|
||||||
|
install(Logging)
|
||||||
|
install(io.ktor.client.plugins.websocket.WebSockets) {
|
||||||
|
contentConverter = KotlinxWebsocketSerializationConverter(Json)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val crudClient = KtorKeyValueRepoClient<Int, ComplexData>(
|
||||||
|
"http://127.0.0.1:23456",
|
||||||
|
client,
|
||||||
|
ContentType.Application.Json,
|
||||||
|
Int.serializer(),
|
||||||
|
ComplexData.serializer(),
|
||||||
|
Json
|
||||||
|
)
|
||||||
|
|
||||||
|
val dataInOneKey = ComplexData(1, title = "Example1")
|
||||||
|
val dataInMultipleKeys = ComplexData(2, title = "Example2")
|
||||||
|
val repeatCount = 3
|
||||||
|
|
||||||
|
val dataList = listOf(
|
||||||
|
1 to dataInOneKey
|
||||||
|
) + (0 until repeatCount).map {
|
||||||
|
(it + 2) to dataInMultipleKeys
|
||||||
|
}
|
||||||
|
|
||||||
|
dataList.forEachIndexed { i, (id, data) ->
|
||||||
|
crudClient.set(id, data)
|
||||||
|
assertEquals(map.size, i + 1)
|
||||||
|
assertEquals(map.size.toLong(), crudClient.count())
|
||||||
|
assertEquals(i + 1L, crudClient.count())
|
||||||
|
dataList.take(i + 1).forEach { (id, data) ->
|
||||||
|
assertEquals(data, map[id])
|
||||||
|
assertEquals(data, crudClient.get(id))
|
||||||
|
assertEquals(map[id], crudClient.get(id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dataList.forEach { (id, data) ->
|
||||||
|
assertTrue(crudClient.contains(id))
|
||||||
|
assertEquals(data, crudClient.get(id))
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
dataList.mapNotNull { if (it.second == dataInMultipleKeys) it.first else null },
|
||||||
|
getAllWithNextPaging(firstPageWithOneElementPagination) {
|
||||||
|
crudClient.keys(dataInMultipleKeys, it)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
dataList.mapNotNull { if (it.second == dataInOneKey) it.first else null },
|
||||||
|
getAllWithNextPaging(firstPageWithOneElementPagination) {
|
||||||
|
crudClient.keys(dataInOneKey, it)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
dataList.map { it.first },
|
||||||
|
getAllWithNextPaging(firstPageWithOneElementPagination) {
|
||||||
|
crudClient.keys(it)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
dataList.map { it.second },
|
||||||
|
getAllWithNextPaging(firstPageWithOneElementPagination) {
|
||||||
|
crudClient.values(it)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
assertEquals(dataList.size.toLong(), crudClient.count())
|
||||||
|
|
||||||
|
crudClient.unsetWithValues(dataInMultipleKeys)
|
||||||
|
assertEquals(
|
||||||
|
dataList.filter { it.second == dataInOneKey }.size.toLong(),
|
||||||
|
crudClient.count()
|
||||||
|
)
|
||||||
|
|
||||||
|
crudClient.unset(dataList.first { it.second == dataInOneKey }.first)
|
||||||
|
assertEquals(
|
||||||
|
0,
|
||||||
|
crudClient.count()
|
||||||
|
)
|
||||||
|
|
||||||
|
server.stop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
140
repos/ktor/common/src/jvmTest/kotlin/KVsTests.kt
Normal file
140
repos/ktor/common/src/jvmTest/kotlin/KVsTests.kt
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
import dev.inmo.micro_utils.pagination.firstPageWithOneElementPagination
|
||||||
|
import dev.inmo.micro_utils.pagination.utils.getAllWithNextPaging
|
||||||
|
import dev.inmo.micro_utils.repos.*
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.client.key.values.KtorKeyValuesRepoClient
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.server.key.values.configureKeyValuesRepoRoutes
|
||||||
|
import io.ktor.client.HttpClient
|
||||||
|
import io.ktor.client.plugins.logging.Logging
|
||||||
|
import io.ktor.http.ContentType
|
||||||
|
import io.ktor.serialization.kotlinx.KotlinxWebsocketSerializationConverter
|
||||||
|
import io.ktor.serialization.kotlinx.json.json
|
||||||
|
import io.ktor.server.application.install
|
||||||
|
import io.ktor.server.cio.CIO
|
||||||
|
import io.ktor.server.plugins.contentnegotiation.ContentNegotiation
|
||||||
|
import io.ktor.server.routing.routing
|
||||||
|
import io.ktor.server.websocket.WebSockets
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlin.test.*
|
||||||
|
|
||||||
|
class KVsTests {
|
||||||
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
@Test
|
||||||
|
fun testKVsFunctions() {
|
||||||
|
runTest {
|
||||||
|
val map = mutableMapOf<Int, MutableList<ComplexData>>()
|
||||||
|
val repo = MapKeyValuesRepo(map)
|
||||||
|
val server = io.ktor.server.engine.embeddedServer(
|
||||||
|
CIO,
|
||||||
|
23456,
|
||||||
|
"127.0.0.1"
|
||||||
|
) {
|
||||||
|
install(ContentNegotiation) {
|
||||||
|
json()
|
||||||
|
}
|
||||||
|
install(WebSockets) {
|
||||||
|
contentConverter = KotlinxWebsocketSerializationConverter(Json)
|
||||||
|
}
|
||||||
|
routing {
|
||||||
|
configureKeyValuesRepoRoutes(
|
||||||
|
repo,
|
||||||
|
Int.serializer(),
|
||||||
|
ComplexData.serializer(),
|
||||||
|
Json {}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}.start(false)
|
||||||
|
val client = HttpClient {
|
||||||
|
install(io.ktor.client.plugins.contentnegotiation.ContentNegotiation) {
|
||||||
|
json()
|
||||||
|
}
|
||||||
|
install(Logging)
|
||||||
|
install(io.ktor.client.plugins.websocket.WebSockets) {
|
||||||
|
contentConverter = KotlinxWebsocketSerializationConverter(Json)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val crudClient = KtorKeyValuesRepoClient(
|
||||||
|
"http://127.0.0.1:23456",
|
||||||
|
client,
|
||||||
|
ContentType.Application.Json,
|
||||||
|
Int.serializer(),
|
||||||
|
ComplexData.serializer(),
|
||||||
|
Json
|
||||||
|
)
|
||||||
|
|
||||||
|
val dataInOneKey = ComplexData(1, title = "Example1")
|
||||||
|
val dataInMultipleKeys = ComplexData(2, title = "Example2")
|
||||||
|
val repeatCount = 3
|
||||||
|
|
||||||
|
val dataList = listOf(
|
||||||
|
1 to listOf(dataInOneKey)
|
||||||
|
) + (0 until repeatCount).map {
|
||||||
|
(it + 2) to listOf(dataInMultipleKeys)
|
||||||
|
}
|
||||||
|
|
||||||
|
dataList.forEachIndexed { i, (id, data) ->
|
||||||
|
crudClient.set(id, data)
|
||||||
|
assertEquals(i + 1, map.size)
|
||||||
|
assertEquals(map.size.toLong(), crudClient.count())
|
||||||
|
assertEquals(i + 1L, crudClient.count())
|
||||||
|
dataList.take(i + 1).forEach { (id, data) ->
|
||||||
|
assertContentEquals(data, map[id])
|
||||||
|
assertContentEquals(data, crudClient.getAll(id))
|
||||||
|
assertContentEquals(map[id], crudClient.getAll(id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dataList.forEach { (key, data) ->
|
||||||
|
assertTrue(crudClient.contains(key))
|
||||||
|
assertContentEquals(data, crudClient.getAll(key))
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
dataList.mapNotNull { if (it.second.contains(dataInMultipleKeys)) it.first else null },
|
||||||
|
getAllWithNextPaging(firstPageWithOneElementPagination) {
|
||||||
|
crudClient.keys(dataInMultipleKeys, it)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
dataList.mapNotNull { if (it.second.contains(dataInOneKey)) it.first else null },
|
||||||
|
getAllWithNextPaging(firstPageWithOneElementPagination) {
|
||||||
|
crudClient.keys(dataInOneKey, it)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
dataList.map { it.first },
|
||||||
|
getAllWithNextPaging(firstPageWithOneElementPagination) {
|
||||||
|
crudClient.keys(it)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
dataList.map { it.first },
|
||||||
|
getAllWithNextPaging(firstPageWithOneElementPagination) {
|
||||||
|
crudClient.keys(it)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
assertEquals(dataList.size.toLong(), crudClient.count())
|
||||||
|
|
||||||
|
crudClient.remove(dataList.filter { it.second.contains(dataInMultipleKeys) })
|
||||||
|
println(map)
|
||||||
|
assertEquals(
|
||||||
|
dataList.filter { it.second.contains(dataInOneKey) }.size.toLong(),
|
||||||
|
crudClient.count()
|
||||||
|
)
|
||||||
|
|
||||||
|
crudClient.remove(dataList.filter { it.second.contains(dataInOneKey) })
|
||||||
|
assertEquals(
|
||||||
|
0,
|
||||||
|
crudClient.count()
|
||||||
|
)
|
||||||
|
|
||||||
|
server.stop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
repos/ktor/common/src/jvmTest/kotlin/SimpleData.kt
Normal file
7
repos/ktor/common/src/jvmTest/kotlin/SimpleData.kt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import com.benasher44.uuid.uuid4
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class SimpleData(
|
||||||
|
val title: String = uuid4().toString()
|
||||||
|
)
|
187
repos/ktor/crud.yml
Normal file
187
repos/ktor/crud.yml
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
swagger: "2.0"
|
||||||
|
info:
|
||||||
|
description: "This is a template for the CRUD repositories from [microutils](https://github.com/InsanusMokrassar/MicroUtils/tree/master/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/crud)"
|
||||||
|
version: "0.11.0"
|
||||||
|
title: "CRUD Repo"
|
||||||
|
contact:
|
||||||
|
email: "ovsyannikov.alexey95@gmail.com"
|
||||||
|
tags:
|
||||||
|
- name: "Read"
|
||||||
|
description: "Operations with `get` request in most cases"
|
||||||
|
- name: "Write"
|
||||||
|
description: "Operations with `post` request in most cases"
|
||||||
|
|
||||||
|
parameters:
|
||||||
|
IdInQuery:
|
||||||
|
in: "query"
|
||||||
|
name: "id"
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/definitions/Key"
|
||||||
|
IdsInBody:
|
||||||
|
in: "body"
|
||||||
|
name: "body"
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/definitions/Key"
|
||||||
|
NewValuesInBody:
|
||||||
|
in: "body"
|
||||||
|
name: "body"
|
||||||
|
type: array
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/definitions/NewValues"
|
||||||
|
NewValuesWithIdsInBody:
|
||||||
|
in: "body"
|
||||||
|
name: "body"
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/definitions/Pair"
|
||||||
|
- properties:
|
||||||
|
first:
|
||||||
|
$ref: "#/definitions/Key"
|
||||||
|
second:
|
||||||
|
$ref: "#/definitions/NewValue"
|
||||||
|
PaginationInQueryPage:
|
||||||
|
in: "query"
|
||||||
|
type: integer
|
||||||
|
name: "ppage"
|
||||||
|
description: "Page of pagination"
|
||||||
|
required: false
|
||||||
|
PaginationInQuerySize:
|
||||||
|
in: "query"
|
||||||
|
type: integer
|
||||||
|
name: "psize"
|
||||||
|
description: "Size of each page in pagination"
|
||||||
|
required: false
|
||||||
|
|
||||||
|
|
||||||
|
definitions:
|
||||||
|
Key:
|
||||||
|
type: integer
|
||||||
|
description: "REWRITE THIS TYPE AS KEY IN SWAGGER FILE"
|
||||||
|
Value:
|
||||||
|
type: integer
|
||||||
|
description: "REWRITE THIS TYPE AS VALUE IN SWAGGER FILE"
|
||||||
|
Values:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/definitions/Value"
|
||||||
|
NewValue:
|
||||||
|
type: integer
|
||||||
|
description: "REWRITE THIS TYPE AS NEW VALUE IN SWAGGER FILE"
|
||||||
|
Pair:
|
||||||
|
type: object
|
||||||
|
description: "Pair of objects"
|
||||||
|
properties:
|
||||||
|
first:
|
||||||
|
second:
|
||||||
|
NewValues:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/definitions/NewValue"
|
||||||
|
PaginationResult:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
page:
|
||||||
|
type: integer
|
||||||
|
description: "Page of pagination"
|
||||||
|
pagesNumber:
|
||||||
|
type: integer
|
||||||
|
description: "Count of pages with the size from this pagination"
|
||||||
|
size:
|
||||||
|
type: integer
|
||||||
|
description: "Size of each page in pagination"
|
||||||
|
results:
|
||||||
|
type: array
|
||||||
|
description: "Array of all elements on that page. Size of pagination and size of array can be different and it can be interpreted like current page is the last one"
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
|
||||||
|
paths:
|
||||||
|
/getByPagination:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- "Read"
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/parameters/PaginationInQueryPage"
|
||||||
|
- $ref: "#/parameters/PaginationInQuerySize"
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: "Pagination with elements"
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/definitions/PaginationResult"
|
||||||
|
- properties:
|
||||||
|
results:
|
||||||
|
items:
|
||||||
|
$ref: "#/definitions/Value"
|
||||||
|
/getById:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- "Read"
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/parameters/IdInQuery"
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: "Result object"
|
||||||
|
schema:
|
||||||
|
$ref: "#/definitions/Value"
|
||||||
|
"204":
|
||||||
|
description: "No value by id"
|
||||||
|
/contains:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- "Read"
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/parameters/IdInQuery"
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: "Object with id availability in repo"
|
||||||
|
schema:
|
||||||
|
type: boolean
|
||||||
|
/count:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- "Read"
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: "Amount of objects in repo"
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
|
||||||
|
|
||||||
|
/create:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- "Write"
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/parameters/NewValuesInBody"
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: "Objects has been created and saved"
|
||||||
|
schema:
|
||||||
|
$ref: "#/definitions/Values"
|
||||||
|
/update:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- "Write"
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/parameters/NewValuesWithIdsInBody"
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: "Objects has been updated"
|
||||||
|
schema:
|
||||||
|
$ref: "#/definitions/Values"
|
||||||
|
/deleteById:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- "Write"
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/parameters/IdsInBody"
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: "Objects has been updated"
|
||||||
|
schema:
|
||||||
|
$ref: "#/definitions/Values"
|
196
repos/ktor/kv.yml
Normal file
196
repos/ktor/kv.yml
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
swagger: "2.0"
|
||||||
|
info:
|
||||||
|
description: "This is a template for the KeyValue repositories from [microutils](https://github.com/InsanusMokrassar/MicroUtils/tree/master/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/key/value)"
|
||||||
|
version: "0.11.0"
|
||||||
|
title: "KeyValue Repo"
|
||||||
|
contact:
|
||||||
|
email: "ovsyannikov.alexey95@gmail.com"
|
||||||
|
tags:
|
||||||
|
- name: "Read"
|
||||||
|
description: "Operations with `get` request in most cases"
|
||||||
|
- name: "Write"
|
||||||
|
description: "Operations with `post` request in most cases"
|
||||||
|
|
||||||
|
parameters:
|
||||||
|
KeyInQuery:
|
||||||
|
in: "query"
|
||||||
|
name: "key"
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/definitions/Key"
|
||||||
|
KeysInBody:
|
||||||
|
in: "body"
|
||||||
|
name: "body"
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/definitions/Key"
|
||||||
|
ValuesInBody:
|
||||||
|
in: "body"
|
||||||
|
name: "body"
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/definitions/Value"
|
||||||
|
PaginationInQueryPage:
|
||||||
|
in: "query"
|
||||||
|
type: integer
|
||||||
|
name: "ppage"
|
||||||
|
description: "Page of pagination"
|
||||||
|
required: false
|
||||||
|
PaginationInQuerySize:
|
||||||
|
in: "query"
|
||||||
|
type: integer
|
||||||
|
name: "psize"
|
||||||
|
description: "Size of each page in pagination"
|
||||||
|
required: false
|
||||||
|
ReversedInQuery:
|
||||||
|
in: "query"
|
||||||
|
type: boolean
|
||||||
|
name: "reversed"
|
||||||
|
description: "If passed, will tell to reverse the result pages"
|
||||||
|
required: false
|
||||||
|
ValueInQuery:
|
||||||
|
in: "query"
|
||||||
|
name: "value"
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/definitions/Value"
|
||||||
|
MapInBody:
|
||||||
|
in: "body"
|
||||||
|
name: "body"
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/definitions/Map"
|
||||||
|
|
||||||
|
|
||||||
|
definitions:
|
||||||
|
Key:
|
||||||
|
type: integer
|
||||||
|
description: "REWRITE THIS TYPE AS KEY IN SWAGGER FILE"
|
||||||
|
Value:
|
||||||
|
type: integer
|
||||||
|
description: "REWRITE THIS TYPE AS VALUE IN SWAGGER FILE"
|
||||||
|
Map:
|
||||||
|
type: object
|
||||||
|
description: "Map of objects"
|
||||||
|
PaginationResult:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
page:
|
||||||
|
type: integer
|
||||||
|
description: "Page of pagination"
|
||||||
|
pagesNumber:
|
||||||
|
type: integer
|
||||||
|
description: "Count of pages with the size from this pagination"
|
||||||
|
size:
|
||||||
|
type: integer
|
||||||
|
description: "Size of each page in pagination"
|
||||||
|
results:
|
||||||
|
type: array
|
||||||
|
description: "Array of all elements on that page. Size of pagination and size of array can be different and it can be interpreted like current page is the last one"
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
|
||||||
|
paths:
|
||||||
|
/get:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- "Read"
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/parameters/KeyInQuery"
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: "Element by key"
|
||||||
|
schema:
|
||||||
|
$ref: "#/definitions/Value"
|
||||||
|
"204":
|
||||||
|
description: "No value by id"
|
||||||
|
/values:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- "Read"
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/parameters/PaginationInQueryPage"
|
||||||
|
- $ref: "#/parameters/PaginationInQuerySize"
|
||||||
|
- $ref: "#/parameters/ReversedInQuery"
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: "Pagination with elements"
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/definitions/PaginationResult"
|
||||||
|
- properties:
|
||||||
|
results:
|
||||||
|
items:
|
||||||
|
$ref: "#/definitions/Value"
|
||||||
|
/keys:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- "Read"
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/parameters/PaginationInQueryPage"
|
||||||
|
- $ref: "#/parameters/PaginationInQuerySize"
|
||||||
|
- $ref: "#/parameters/ReversedInQuery"
|
||||||
|
- $ref: "#/parameters/ValueInQuery"
|
||||||
|
required: false
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: "Pagination with elements"
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/definitions/PaginationResult"
|
||||||
|
- properties:
|
||||||
|
results:
|
||||||
|
items:
|
||||||
|
$ref: "#/definitions/Key"
|
||||||
|
/contains:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- "Read"
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/parameters/KeyInQuery"
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: "Object with id availability in repo"
|
||||||
|
schema:
|
||||||
|
type: boolean
|
||||||
|
/count:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- "Read"
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: "Amount of objects in repo"
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
|
||||||
|
|
||||||
|
/set:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- "Write"
|
||||||
|
parameters:
|
||||||
|
- allOf:
|
||||||
|
- $ref: "#/parameters/MapInBody"
|
||||||
|
- additionalProperties:
|
||||||
|
$ref: "#/definitions/Value"
|
||||||
|
description: "Map with new elements to set. Use keys as a keys of this map"
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: "Will return 200 if everything has been completed ok"
|
||||||
|
/unset:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- "Write"
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/parameters/KeysInBody"
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: "Objects with keys from body has been unset"
|
||||||
|
/unsetWithValues:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- "Write"
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/parameters/ValuesInBody"
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: "Objects with values from body has been unset"
|
222
repos/ktor/kvs.yml
Normal file
222
repos/ktor/kvs.yml
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
swagger: "2.0"
|
||||||
|
info:
|
||||||
|
description: "This is a template for the KeyValues repositories from [microutils](https://github.com/InsanusMokrassar/MicroUtils/tree/master/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/key/values)"
|
||||||
|
version: "0.11.0"
|
||||||
|
title: "KeyValues Repo"
|
||||||
|
contact:
|
||||||
|
email: "ovsyannikov.alexey95@gmail.com"
|
||||||
|
tags:
|
||||||
|
- name: "Read"
|
||||||
|
description: "Operations with `get` request in most cases"
|
||||||
|
- name: "Write"
|
||||||
|
description: "Operations with `post` request in most cases"
|
||||||
|
|
||||||
|
parameters:
|
||||||
|
KeyInQuery:
|
||||||
|
in: "query"
|
||||||
|
name: "key"
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/definitions/Key"
|
||||||
|
KeyInBody:
|
||||||
|
in: "body"
|
||||||
|
name: "body"
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/definitions/Key"
|
||||||
|
KeysInBody:
|
||||||
|
in: "body"
|
||||||
|
name: "body"
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/definitions/Key"
|
||||||
|
ValuesInBody:
|
||||||
|
in: "body"
|
||||||
|
name: "body"
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/definitions/Value"
|
||||||
|
PaginationInQueryPage:
|
||||||
|
in: "query"
|
||||||
|
type: integer
|
||||||
|
name: "ppage"
|
||||||
|
description: "Page of pagination"
|
||||||
|
required: false
|
||||||
|
PaginationInQuerySize:
|
||||||
|
in: "query"
|
||||||
|
type: integer
|
||||||
|
name: "psize"
|
||||||
|
description: "Size of each page in pagination"
|
||||||
|
required: false
|
||||||
|
ReversedInQuery:
|
||||||
|
in: "query"
|
||||||
|
type: boolean
|
||||||
|
name: "reversed"
|
||||||
|
description: "If passed, will tell to reverse the result pages"
|
||||||
|
required: false
|
||||||
|
ValueInQuery:
|
||||||
|
in: "query"
|
||||||
|
name: "value"
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/definitions/Value"
|
||||||
|
ValueInBody:
|
||||||
|
in: "body"
|
||||||
|
name: "body"
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/definitions/Value"
|
||||||
|
MapInBody:
|
||||||
|
in: "body"
|
||||||
|
name: "body"
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/definitions/Map"
|
||||||
|
|
||||||
|
|
||||||
|
definitions:
|
||||||
|
Key:
|
||||||
|
type: integer
|
||||||
|
description: "REWRITE THIS TYPE AS KEY IN SWAGGER FILE"
|
||||||
|
Value:
|
||||||
|
type: integer
|
||||||
|
description: "REWRITE THIS TYPE AS VALUE IN SWAGGER FILE"
|
||||||
|
Map:
|
||||||
|
type: object
|
||||||
|
description: "Map of objects"
|
||||||
|
PaginationResult:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
page:
|
||||||
|
type: integer
|
||||||
|
description: "Page of pagination"
|
||||||
|
pagesNumber:
|
||||||
|
type: integer
|
||||||
|
description: "Count of pages with the size from this pagination"
|
||||||
|
size:
|
||||||
|
type: integer
|
||||||
|
description: "Size of each page in pagination"
|
||||||
|
results:
|
||||||
|
type: array
|
||||||
|
description: "Array of all elements on that page. Size of pagination and size of array can be different and it can be interpreted like current page is the last one"
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
|
||||||
|
paths:
|
||||||
|
/get:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- "Read"
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/parameters/KeyInQuery"
|
||||||
|
required: true
|
||||||
|
- $ref: "#/parameters/PaginationInQueryPage"
|
||||||
|
- $ref: "#/parameters/PaginationInQuerySize"
|
||||||
|
- $ref: "#/parameters/ReversedInQuery"
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: "Elements by query"
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/definitions/PaginationResult"
|
||||||
|
- properties:
|
||||||
|
results:
|
||||||
|
items:
|
||||||
|
$ref: "#/definitions/Value"
|
||||||
|
/keys:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- "Read"
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/parameters/PaginationInQueryPage"
|
||||||
|
- $ref: "#/parameters/PaginationInQuerySize"
|
||||||
|
- $ref: "#/parameters/ReversedInQuery"
|
||||||
|
- $ref: "#/parameters/ValueInQuery"
|
||||||
|
required: false
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: "Pagination with elements"
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/definitions/PaginationResult"
|
||||||
|
- properties:
|
||||||
|
results:
|
||||||
|
items:
|
||||||
|
$ref: "#/definitions/Key"
|
||||||
|
/contains:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- "Read"
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/parameters/KeyInQuery"
|
||||||
|
required: true
|
||||||
|
- $ref: "#/parameters/ValueInQuery"
|
||||||
|
required: false
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: "Object with key and optionally availability in repo"
|
||||||
|
schema:
|
||||||
|
type: boolean
|
||||||
|
/count:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- "Read"
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: "Amount of objects in repo"
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
|
||||||
|
|
||||||
|
/add:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- "Write"
|
||||||
|
parameters:
|
||||||
|
- allOf:
|
||||||
|
- $ref: "#/parameters/MapInBody"
|
||||||
|
- additionalProperties:
|
||||||
|
$ref: "#/definitions/Value"
|
||||||
|
description: "Map with new elements to add. Use keys as a keys of this map. That values will be added to the end of current data by their keys"
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: "Will return 200 if everything has been completed ok"
|
||||||
|
/set:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- "Write"
|
||||||
|
parameters:
|
||||||
|
- allOf:
|
||||||
|
- $ref: "#/parameters/MapInBody"
|
||||||
|
- additionalProperties:
|
||||||
|
$ref: "#/definitions/Value"
|
||||||
|
description: "Map with new elements to set. Use keys as a keys of this map. That values will overwrite all exists data by their keys"
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: "Will return 200 if everything has been completed ok"
|
||||||
|
/remove:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- "Write"
|
||||||
|
parameters:
|
||||||
|
- allOf:
|
||||||
|
- $ref: "#/parameters/MapInBody"
|
||||||
|
- additionalProperties:
|
||||||
|
$ref: "#/definitions/Value"
|
||||||
|
description: "Map with data to remove. Removing will be processed by each value for its key"
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: "Objects with keys and values from body has been unset"
|
||||||
|
/clear:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- "Write"
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/parameters/KeyInBody"
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: "Data with corresponding key has been removed"
|
||||||
|
/clearWithValues:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- "Write"
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/parameters/ValueInBody"
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: "Will remove value from all keys data"
|
@ -0,0 +1,30 @@
|
|||||||
|
package dev.inmo.micro_utils.repos.ktor.server.crud
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.ktor.common.*
|
||||||
|
import dev.inmo.micro_utils.repos.CRUDRepo
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
|
inline fun <reified ObjectType : Any, reified IdType : Any, reified InputValue : Any> Route.configureCRUDRepoRoutes(
|
||||||
|
originalRepo: CRUDRepo<ObjectType, IdType, InputValue>,
|
||||||
|
noinline idDeserializer: suspend (String) -> IdType
|
||||||
|
) {
|
||||||
|
configureReadCRUDRepoRoutes(originalRepo, idDeserializer)
|
||||||
|
configureWriteCRUDRepoRoutes(originalRepo)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified ObjectType : Any, reified IdType : Any, reified InputValue : Any> Route.configureCRUDRepoRoutes(
|
||||||
|
originalRepo: CRUDRepo<ObjectType, IdType, InputValue>,
|
||||||
|
idsSerializer: KSerializer<IdType>,
|
||||||
|
serialFormat: StringFormat
|
||||||
|
) = configureCRUDRepoRoutes(originalRepo) {
|
||||||
|
serialFormat.decodeFromString(idsSerializer, it)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified ObjectType : Any, reified IdType : Any, reified InputValue : Any> Route.configureCRUDRepoRoutes(
|
||||||
|
originalRepo: CRUDRepo<ObjectType, IdType, InputValue>,
|
||||||
|
idsSerializer: KSerializer<IdType>,
|
||||||
|
serialFormat: BinaryFormat
|
||||||
|
) = configureCRUDRepoRoutes(originalRepo) {
|
||||||
|
serialFormat.decodeHex(idsSerializer, it)
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
package dev.inmo.micro_utils.repos.ktor.server.crud
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.ktor.common.decodeHex
|
||||||
|
import dev.inmo.micro_utils.ktor.server.*
|
||||||
|
import dev.inmo.micro_utils.pagination.extractPagination
|
||||||
|
import dev.inmo.micro_utils.repos.ReadCRUDRepo
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.countRouting
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.crud.*
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.idParameterName
|
||||||
|
import io.ktor.http.HttpStatusCode
|
||||||
|
import io.ktor.server.application.call
|
||||||
|
import io.ktor.server.response.respond
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
import io.ktor.server.routing.get
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
|
inline fun <reified ObjectType, reified IdType> Route.configureReadCRUDRepoRoutes(
|
||||||
|
originalRepo: ReadCRUDRepo<ObjectType, IdType>,
|
||||||
|
noinline idDeserializer: suspend (String) -> IdType
|
||||||
|
) {
|
||||||
|
get(getByPaginationRouting) {
|
||||||
|
val pagination = call.request.queryParameters.extractPagination
|
||||||
|
|
||||||
|
call.respond(originalRepo.getByPagination(pagination))
|
||||||
|
}
|
||||||
|
|
||||||
|
get(getByIdRouting) {
|
||||||
|
val id = idDeserializer(
|
||||||
|
call.getQueryParameterOrSendError(idParameterName) ?: return@get
|
||||||
|
)
|
||||||
|
|
||||||
|
val result = originalRepo.getById(id)
|
||||||
|
|
||||||
|
if (result == null) {
|
||||||
|
call.respond(HttpStatusCode.NoContent)
|
||||||
|
} else {
|
||||||
|
call.respond(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get(containsRouting) {
|
||||||
|
val id = idDeserializer(
|
||||||
|
call.getQueryParameterOrSendError(idParameterName) ?: return@get
|
||||||
|
)
|
||||||
|
|
||||||
|
call.respond(
|
||||||
|
originalRepo.contains(id)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
get(countRouting) {
|
||||||
|
call.respond(
|
||||||
|
originalRepo.count()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified ObjectType, reified IdType> Route.configureReadCRUDRepoRoutes(
|
||||||
|
originalRepo: ReadCRUDRepo<ObjectType, IdType>,
|
||||||
|
idsSerializer: KSerializer<IdType>,
|
||||||
|
serialFormat: StringFormat
|
||||||
|
) = configureReadCRUDRepoRoutes(originalRepo) {
|
||||||
|
serialFormat.decodeFromString(idsSerializer, it)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified ObjectType, reified IdType> Route.configureReadCRUDRepoRoutes(
|
||||||
|
originalRepo: ReadCRUDRepo<ObjectType, IdType>,
|
||||||
|
idsSerializer: KSerializer<IdType>,
|
||||||
|
serialFormat: BinaryFormat
|
||||||
|
) = configureReadCRUDRepoRoutes(originalRepo) {
|
||||||
|
serialFormat.decodeHex(idsSerializer, it)
|
||||||
|
}
|
@ -5,7 +5,8 @@ import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
|
|||||||
import dev.inmo.micro_utils.ktor.server.*
|
import dev.inmo.micro_utils.ktor.server.*
|
||||||
import dev.inmo.micro_utils.pagination.PaginationResult
|
import dev.inmo.micro_utils.pagination.PaginationResult
|
||||||
import dev.inmo.micro_utils.pagination.extractPagination
|
import dev.inmo.micro_utils.pagination.extractPagination
|
||||||
import dev.inmo.micro_utils.repos.ReadStandardCRUDRepo
|
import dev.inmo.micro_utils.repos.ReadCRUDRepo
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.countRouting
|
||||||
import dev.inmo.micro_utils.repos.ktor.common.crud.*
|
import dev.inmo.micro_utils.repos.ktor.common.crud.*
|
||||||
import io.ktor.http.ContentType
|
import io.ktor.http.ContentType
|
||||||
import io.ktor.server.application.call
|
import io.ktor.server.application.call
|
||||||
@ -14,8 +15,8 @@ import io.ktor.server.routing.get
|
|||||||
import kotlinx.serialization.KSerializer
|
import kotlinx.serialization.KSerializer
|
||||||
import kotlinx.serialization.builtins.serializer
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
|
||||||
fun <ObjectType, IdType> Route.configureReadStandardCrudRepoRoutes(
|
fun <ObjectType, IdType> Route.configureReadCRUDRepoRoutes(
|
||||||
originalRepo: ReadStandardCRUDRepo<ObjectType, IdType>,
|
originalRepo: ReadCRUDRepo<ObjectType, IdType>,
|
||||||
objectsSerializer: KSerializer<ObjectType>,
|
objectsSerializer: KSerializer<ObjectType>,
|
||||||
objectsNullableSerializer: KSerializer<ObjectType?>,
|
objectsNullableSerializer: KSerializer<ObjectType?>,
|
||||||
idsSerializer: KSerializer<IdType>,
|
idsSerializer: KSerializer<IdType>,
|
||||||
@ -72,11 +73,11 @@ fun <ObjectType, IdType> Route.configureReadStandardCrudRepoRoutes(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <ObjectType, IdType> Route.configureReadStandardCrudRepoRoutes(
|
inline fun <ObjectType, IdType> Route.configureReadCRUDRepoRoutes(
|
||||||
originalRepo: ReadStandardCRUDRepo<ObjectType, IdType>,
|
originalRepo: ReadCRUDRepo<ObjectType, IdType>,
|
||||||
objectsSerializer: KSerializer<ObjectType>,
|
objectsSerializer: KSerializer<ObjectType>,
|
||||||
objectsNullableSerializer: KSerializer<ObjectType?>,
|
objectsNullableSerializer: KSerializer<ObjectType?>,
|
||||||
idsSerializer: KSerializer<IdType>,
|
idsSerializer: KSerializer<IdType>,
|
||||||
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
|
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
|
||||||
serialFormatContentType: ContentType = standardKtorSerialFormatContentType
|
serialFormatContentType: ContentType = standardKtorSerialFormatContentType
|
||||||
) = configureReadStandardCrudRepoRoutes(originalRepo, objectsSerializer, objectsNullableSerializer, idsSerializer, UnifiedRouter(serialFormat, serialFormatContentType))
|
) = configureReadCRUDRepoRoutes(originalRepo, objectsSerializer, objectsNullableSerializer, idsSerializer, UnifiedRouter(serialFormat, serialFormatContentType))
|
||||||
|
@ -4,15 +4,15 @@ import dev.inmo.micro_utils.ktor.common.StandardKtorSerialFormat
|
|||||||
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
|
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
|
||||||
import dev.inmo.micro_utils.ktor.server.UnifiedRouter
|
import dev.inmo.micro_utils.ktor.server.UnifiedRouter
|
||||||
import dev.inmo.micro_utils.ktor.server.standardKtorSerialFormatContentType
|
import dev.inmo.micro_utils.ktor.server.standardKtorSerialFormatContentType
|
||||||
import dev.inmo.micro_utils.repos.StandardCRUDRepo
|
import dev.inmo.micro_utils.repos.CRUDRepo
|
||||||
import io.ktor.http.ContentType
|
import io.ktor.http.ContentType
|
||||||
import io.ktor.server.routing.Route
|
import io.ktor.server.routing.Route
|
||||||
import io.ktor.server.routing.route
|
import io.ktor.server.routing.route
|
||||||
import kotlinx.serialization.KSerializer
|
import kotlinx.serialization.KSerializer
|
||||||
|
|
||||||
fun <ObjectType, IdType, InputValue> Route.configureStandardCrudRepoRoutes(
|
fun <ObjectType, IdType, InputValue> Route.configureCRUDRepoRoutes(
|
||||||
baseSubpart: String,
|
baseSubpart: String,
|
||||||
originalRepo: StandardCRUDRepo<ObjectType, IdType, InputValue>,
|
originalRepo: CRUDRepo<ObjectType, IdType, InputValue>,
|
||||||
objectsSerializer: KSerializer<ObjectType>,
|
objectsSerializer: KSerializer<ObjectType>,
|
||||||
objectsNullableSerializer: KSerializer<ObjectType?>,
|
objectsNullableSerializer: KSerializer<ObjectType?>,
|
||||||
inputsSerializer: KSerializer<InputValue>,
|
inputsSerializer: KSerializer<InputValue>,
|
||||||
@ -20,20 +20,20 @@ fun <ObjectType, IdType, InputValue> Route.configureStandardCrudRepoRoutes(
|
|||||||
unifiedRouter: UnifiedRouter
|
unifiedRouter: UnifiedRouter
|
||||||
) {
|
) {
|
||||||
route(baseSubpart) {
|
route(baseSubpart) {
|
||||||
configureReadStandardCrudRepoRoutes(originalRepo, objectsSerializer, objectsNullableSerializer, idsSerializer, unifiedRouter)
|
configureReadCRUDRepoRoutes(originalRepo, objectsSerializer, objectsNullableSerializer, idsSerializer, unifiedRouter)
|
||||||
configureWriteStandardCrudRepoRoutes(originalRepo, objectsSerializer, objectsNullableSerializer, inputsSerializer, idsSerializer, unifiedRouter)
|
configureWriteCRUDRepoRoutes(originalRepo, objectsSerializer, objectsNullableSerializer, inputsSerializer, idsSerializer, unifiedRouter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <ObjectType, IdType, InputValue> Route.configureStandardCrudRepoRoutes(
|
fun <ObjectType, IdType, InputValue> Route.configureCRUDRepoRoutes(
|
||||||
baseSubpart: String,
|
baseSubpart: String,
|
||||||
originalRepo: StandardCRUDRepo<ObjectType, IdType, InputValue>,
|
originalRepo: CRUDRepo<ObjectType, IdType, InputValue>,
|
||||||
objectsSerializer: KSerializer<ObjectType>,
|
objectsSerializer: KSerializer<ObjectType>,
|
||||||
objectsNullableSerializer: KSerializer<ObjectType?>,
|
objectsNullableSerializer: KSerializer<ObjectType?>,
|
||||||
inputsSerializer: KSerializer<InputValue>,
|
inputsSerializer: KSerializer<InputValue>,
|
||||||
idsSerializer: KSerializer<IdType>,
|
idsSerializer: KSerializer<IdType>,
|
||||||
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
|
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
|
||||||
serialFormatContentType: ContentType = standardKtorSerialFormatContentType
|
serialFormatContentType: ContentType = standardKtorSerialFormatContentType
|
||||||
) = configureStandardCrudRepoRoutes(
|
) = configureCRUDRepoRoutes(
|
||||||
baseSubpart, originalRepo, objectsSerializer, objectsNullableSerializer, inputsSerializer, idsSerializer, UnifiedRouter(serialFormat, serialFormatContentType)
|
baseSubpart, originalRepo, objectsSerializer, objectsNullableSerializer, inputsSerializer, idsSerializer, UnifiedRouter(serialFormat, serialFormatContentType)
|
||||||
)
|
)
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
package dev.inmo.micro_utils.repos.ktor.server.crud
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.ktor.server.*
|
||||||
|
import dev.inmo.micro_utils.repos.WriteCRUDRepo
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.crud.*
|
||||||
|
import io.ktor.http.HttpStatusCode
|
||||||
|
import io.ktor.server.application.call
|
||||||
|
import io.ktor.server.request.receive
|
||||||
|
import io.ktor.server.response.respond
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
import io.ktor.server.routing.post
|
||||||
|
|
||||||
|
inline fun <reified ObjectType : Any, reified IdType : Any, reified InputValue : Any> Route.configureWriteCRUDRepoRoutes(
|
||||||
|
originalRepo: WriteCRUDRepo<ObjectType, IdType, InputValue>
|
||||||
|
) {
|
||||||
|
includeWebsocketHandling(
|
||||||
|
newObjectsFlowRouting,
|
||||||
|
originalRepo.newObjectsFlow,
|
||||||
|
)
|
||||||
|
includeWebsocketHandling(
|
||||||
|
updatedObjectsFlowRouting,
|
||||||
|
originalRepo.updatedObjectsFlow
|
||||||
|
)
|
||||||
|
includeWebsocketHandling(
|
||||||
|
deletedObjectsIdsFlowRouting,
|
||||||
|
originalRepo.deletedObjectsIdsFlow
|
||||||
|
)
|
||||||
|
|
||||||
|
post(createRouting) {
|
||||||
|
call.respond(originalRepo.create(call.receive()))
|
||||||
|
}
|
||||||
|
|
||||||
|
post(updateRouting) {
|
||||||
|
call.respond(originalRepo.update(call.receive()))
|
||||||
|
}
|
||||||
|
|
||||||
|
post(deleteByIdRouting) {
|
||||||
|
originalRepo.deleteById(call.receive())
|
||||||
|
call.respond(HttpStatusCode.OK)
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,7 @@ package dev.inmo.micro_utils.repos.ktor.server.crud
|
|||||||
import dev.inmo.micro_utils.ktor.common.StandardKtorSerialFormat
|
import dev.inmo.micro_utils.ktor.common.StandardKtorSerialFormat
|
||||||
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
|
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
|
||||||
import dev.inmo.micro_utils.ktor.server.*
|
import dev.inmo.micro_utils.ktor.server.*
|
||||||
import dev.inmo.micro_utils.repos.WriteStandardCRUDRepo
|
import dev.inmo.micro_utils.repos.WriteCRUDRepo
|
||||||
import dev.inmo.micro_utils.repos.ktor.common.crud.*
|
import dev.inmo.micro_utils.repos.ktor.common.crud.*
|
||||||
import io.ktor.http.ContentType
|
import io.ktor.http.ContentType
|
||||||
import io.ktor.server.routing.Route
|
import io.ktor.server.routing.Route
|
||||||
@ -11,8 +11,8 @@ import io.ktor.server.routing.post
|
|||||||
import kotlinx.serialization.KSerializer
|
import kotlinx.serialization.KSerializer
|
||||||
import kotlinx.serialization.builtins.*
|
import kotlinx.serialization.builtins.*
|
||||||
|
|
||||||
fun <ObjectType, IdType, InputValue> Route.configureWriteStandardCrudRepoRoutes(
|
fun <ObjectType, IdType, InputValue> Route.configureWriteCRUDRepoRoutes(
|
||||||
originalRepo: WriteStandardCRUDRepo<ObjectType, IdType, InputValue>,
|
originalRepo: WriteCRUDRepo<ObjectType, IdType, InputValue>,
|
||||||
objectsSerializer: KSerializer<ObjectType>,
|
objectsSerializer: KSerializer<ObjectType>,
|
||||||
objectsNullableSerializer: KSerializer<ObjectType?>,
|
objectsNullableSerializer: KSerializer<ObjectType?>,
|
||||||
inputsSerializer: KSerializer<InputValue>,
|
inputsSerializer: KSerializer<InputValue>,
|
||||||
@ -94,14 +94,14 @@ fun <ObjectType, IdType, InputValue> Route.configureWriteStandardCrudRepoRoutes(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <ObjectType, IdType, InputValue> Route.configureWriteStandardCrudRepoRoutes(
|
fun <ObjectType, IdType, InputValue> Route.configureWriteCRUDRepoRoutes(
|
||||||
originalRepo: WriteStandardCRUDRepo<ObjectType, IdType, InputValue>,
|
originalRepo: WriteCRUDRepo<ObjectType, IdType, InputValue>,
|
||||||
objectsSerializer: KSerializer<ObjectType>,
|
objectsSerializer: KSerializer<ObjectType>,
|
||||||
objectsNullableSerializer: KSerializer<ObjectType?>,
|
objectsNullableSerializer: KSerializer<ObjectType?>,
|
||||||
inputsSerializer: KSerializer<InputValue>,
|
inputsSerializer: KSerializer<InputValue>,
|
||||||
idsSerializer: KSerializer<IdType>,
|
idsSerializer: KSerializer<IdType>,
|
||||||
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
|
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
|
||||||
serialFormatContentType: ContentType = standardKtorSerialFormatContentType
|
serialFormatContentType: ContentType = standardKtorSerialFormatContentType
|
||||||
) = configureWriteStandardCrudRepoRoutes(
|
) = configureWriteCRUDRepoRoutes(
|
||||||
originalRepo, objectsSerializer, objectsNullableSerializer, inputsSerializer, idsSerializer, UnifiedRouter(serialFormat, serialFormatContentType)
|
originalRepo, objectsSerializer, objectsNullableSerializer, inputsSerializer, idsSerializer, UnifiedRouter(serialFormat, serialFormatContentType)
|
||||||
)
|
)
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
package dev.inmo.micro_utils.repos.ktor.server.key.value
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.ktor.common.*
|
||||||
|
import dev.inmo.micro_utils.repos.KeyValueRepo
|
||||||
|
import io.ktor.http.*
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
|
inline fun <reified Key : Any, reified Value : Any> Route.configureKeyValueRepoRoutes (
|
||||||
|
originalRepo: KeyValueRepo<Key, Value>,
|
||||||
|
noinline idDeserializer: suspend (String) -> Key,
|
||||||
|
noinline valueDeserializer: suspend (String) -> Value
|
||||||
|
) {
|
||||||
|
configureReadKeyValueRepoRoutes(originalRepo, idDeserializer, valueDeserializer)
|
||||||
|
configureWriteKeyValueRepoRoutes(originalRepo)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified Key : Any, reified Value : Any> Route.configureKeyValueRepoRoutes(
|
||||||
|
originalRepo: KeyValueRepo<Key, Value>,
|
||||||
|
idsSerializer: DeserializationStrategy<Key>,
|
||||||
|
valueSerializer: DeserializationStrategy<Value>,
|
||||||
|
serialFormat: StringFormat
|
||||||
|
) = configureKeyValueRepoRoutes(
|
||||||
|
originalRepo,
|
||||||
|
{
|
||||||
|
serialFormat.decodeFromString(idsSerializer, it.decodeURLQueryComponent())
|
||||||
|
},
|
||||||
|
{
|
||||||
|
serialFormat.decodeFromString(valueSerializer, it.decodeURLQueryComponent())
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
inline fun <reified Key : Any, reified Value : Any> Route.configureKeyValueRepoRoutes(
|
||||||
|
originalRepo: KeyValueRepo<Key, Value>,
|
||||||
|
idsSerializer: DeserializationStrategy<Key>,
|
||||||
|
valueSerializer: DeserializationStrategy<Value>,
|
||||||
|
serialFormat: BinaryFormat
|
||||||
|
) = configureKeyValueRepoRoutes(
|
||||||
|
originalRepo,
|
||||||
|
{
|
||||||
|
serialFormat.decodeHex(idsSerializer, it)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
serialFormat.decodeHex(valueSerializer, it)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,107 @@
|
|||||||
|
package dev.inmo.micro_utils.repos.ktor.server.key.value
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.ktor.common.*
|
||||||
|
import dev.inmo.micro_utils.ktor.server.*
|
||||||
|
import dev.inmo.micro_utils.pagination.PaginationResult
|
||||||
|
import dev.inmo.micro_utils.pagination.extractPagination
|
||||||
|
import dev.inmo.micro_utils.repos.ReadKeyValueRepo
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.*
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.containsRoute
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.countRoute
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.keyParameterName
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.key_value.*
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.reversedParameterName
|
||||||
|
import io.ktor.http.*
|
||||||
|
import io.ktor.server.application.call
|
||||||
|
import io.ktor.server.response.respond
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
import io.ktor.server.routing.get
|
||||||
|
import io.ktor.util.InternalAPI
|
||||||
|
import io.ktor.util.reflect.typeInfo
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
|
@OptIn(InternalAPI::class)
|
||||||
|
inline fun <reified Key, reified Value> Route.configureReadKeyValueRepoRoutes (
|
||||||
|
originalRepo: ReadKeyValueRepo<Key, Value>,
|
||||||
|
noinline idDeserializer: suspend (String) -> Key,
|
||||||
|
noinline valueDeserializer: suspend (String) -> Value
|
||||||
|
) {
|
||||||
|
val paginationWithValuesTypeInfo = typeInfo<PaginationResult<Value>>()
|
||||||
|
val paginationWithKeysTypeInfo = typeInfo<PaginationResult<Key>>()
|
||||||
|
|
||||||
|
get(getRoute) {
|
||||||
|
val key = idDeserializer(
|
||||||
|
call.getQueryParameterOrSendError(keyParameterName) ?: return@get
|
||||||
|
)
|
||||||
|
|
||||||
|
originalRepo.get(key) ?.let {
|
||||||
|
call.respond(it)
|
||||||
|
} ?: call.respond(HttpStatusCode.NoContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
get(valuesRoute) {
|
||||||
|
val pagination = call.request.queryParameters.extractPagination
|
||||||
|
val reversed = call.getQueryParameter(reversedParameterName) ?.toBoolean() ?: false
|
||||||
|
|
||||||
|
call.respond(
|
||||||
|
originalRepo.values(pagination, reversed),
|
||||||
|
paginationWithValuesTypeInfo
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
get(keysRoute) {
|
||||||
|
val pagination = call.request.queryParameters.extractPagination
|
||||||
|
val reversed = call.getQueryParameterOrSendError(reversedParameterName) ?.toBoolean() ?: false
|
||||||
|
val value = call.getQueryParameter(valueParameterName) ?.let {
|
||||||
|
valueDeserializer(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
call.respond(
|
||||||
|
value ?.let { originalRepo.keys(value, pagination, reversed) } ?: originalRepo.keys(pagination, reversed),
|
||||||
|
paginationWithKeysTypeInfo
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
get(containsRoute) {
|
||||||
|
val key = idDeserializer(
|
||||||
|
call.getQueryParameterOrSendError(keyParameterName) ?: return@get
|
||||||
|
)
|
||||||
|
|
||||||
|
call.respond(originalRepo.contains(key))
|
||||||
|
}
|
||||||
|
|
||||||
|
get(countRoute) {
|
||||||
|
call.respond(originalRepo.count())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified Key, reified Value> Route.configureReadKeyValueRepoRoutes(
|
||||||
|
originalRepo: ReadKeyValueRepo<Key, Value>,
|
||||||
|
idsSerializer: DeserializationStrategy<Key>,
|
||||||
|
valueSerializer: DeserializationStrategy<Value>,
|
||||||
|
serialFormat: StringFormat
|
||||||
|
) = configureReadKeyValueRepoRoutes(
|
||||||
|
originalRepo,
|
||||||
|
{
|
||||||
|
serialFormat.decodeFromString(idsSerializer, it.decodeURLQueryComponent())
|
||||||
|
},
|
||||||
|
{
|
||||||
|
serialFormat.decodeFromString(valueSerializer, it.decodeURLQueryComponent())
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
inline fun <reified Key, reified Value> Route.configureReadKeyValueRepoRoutes(
|
||||||
|
originalRepo: ReadKeyValueRepo<Key, Value>,
|
||||||
|
idsSerializer: DeserializationStrategy<Key>,
|
||||||
|
valueSerializer: DeserializationStrategy<Value>,
|
||||||
|
serialFormat: BinaryFormat
|
||||||
|
) = configureReadKeyValueRepoRoutes(
|
||||||
|
originalRepo,
|
||||||
|
{
|
||||||
|
serialFormat.decodeHex(idsSerializer, it)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
serialFormat.decodeHex(valueSerializer, it)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,45 @@
|
|||||||
|
package dev.inmo.micro_utils.repos.ktor.server.key.value
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.ktor.server.*
|
||||||
|
import dev.inmo.micro_utils.repos.WriteKeyValueRepo
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.key_value.*
|
||||||
|
import io.ktor.http.HttpStatusCode
|
||||||
|
import io.ktor.server.application.call
|
||||||
|
import io.ktor.server.request.receive
|
||||||
|
import io.ktor.server.response.respond
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
import io.ktor.server.routing.post
|
||||||
|
import io.ktor.util.reflect.typeInfo
|
||||||
|
|
||||||
|
inline fun <reified Key : Any, reified Value : Any> Route.configureWriteKeyValueRepoRoutes (
|
||||||
|
originalRepo: WriteKeyValueRepo<Key, Value>
|
||||||
|
) {
|
||||||
|
includeWebsocketHandling(
|
||||||
|
onNewValueRoute,
|
||||||
|
originalRepo.onNewValue
|
||||||
|
)
|
||||||
|
|
||||||
|
includeWebsocketHandling(
|
||||||
|
onValueRemovedRoute,
|
||||||
|
originalRepo.onValueRemoved
|
||||||
|
)
|
||||||
|
|
||||||
|
val mapType = typeInfo<Map<Key, Value>>()
|
||||||
|
val listKeysType = typeInfo<List<Key>>()
|
||||||
|
val listValuesType = typeInfo<List<Value>>()
|
||||||
|
|
||||||
|
post(setRoute) {
|
||||||
|
originalRepo.set(call.receive(mapType))
|
||||||
|
call.respond(HttpStatusCode.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
post(unsetRoute) {
|
||||||
|
originalRepo.unset(call.receive(listKeysType))
|
||||||
|
call.respond(HttpStatusCode.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
post(unsetWithValuesRoute) {
|
||||||
|
originalRepo.unsetWithValues(call.receive(listValuesType))
|
||||||
|
call.respond(HttpStatusCode.OK)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package dev.inmo.micro_utils.repos.ktor.server.key.values
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.ktor.common.*
|
||||||
|
import dev.inmo.micro_utils.repos.*
|
||||||
|
import io.ktor.http.*
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
|
inline fun <reified Key : Any, reified Value : Any> Route.configureKeyValuesRepoRoutes (
|
||||||
|
originalRepo: KeyValuesRepo<Key, Value>,
|
||||||
|
noinline keyDeserializer: suspend (String) -> Key,
|
||||||
|
noinline valueDeserializer: suspend (String) -> Value
|
||||||
|
) {
|
||||||
|
configureReadKeyValuesRepoRoutes(originalRepo, keyDeserializer, valueDeserializer)
|
||||||
|
configureWriteKeyValuesRepoRoutes(originalRepo)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified Key : Any, reified Value : Any> Route.configureKeyValuesRepoRoutes(
|
||||||
|
originalRepo: KeyValuesRepo<Key, Value>,
|
||||||
|
keySerializer: DeserializationStrategy<Key>,
|
||||||
|
valueSerializer: DeserializationStrategy<Value>,
|
||||||
|
serialFormat: StringFormat
|
||||||
|
) = configureKeyValuesRepoRoutes(
|
||||||
|
originalRepo,
|
||||||
|
{
|
||||||
|
serialFormat.decodeFromString(keySerializer, it.decodeURLQueryComponent())
|
||||||
|
},
|
||||||
|
{
|
||||||
|
serialFormat.decodeFromString(valueSerializer, it.decodeURLQueryComponent())
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
inline fun <reified Key : Any, reified Value : Any> Route.configureKeyValuesRepoRoutes(
|
||||||
|
originalRepo: KeyValuesRepo<Key, Value>,
|
||||||
|
keySerializer: DeserializationStrategy<Key>,
|
||||||
|
valueSerializer: DeserializationStrategy<Value>,
|
||||||
|
serialFormat: BinaryFormat
|
||||||
|
) = configureKeyValuesRepoRoutes(
|
||||||
|
originalRepo,
|
||||||
|
{
|
||||||
|
serialFormat.decodeHex(keySerializer, it)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
serialFormat.decodeHex(valueSerializer, it)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,108 @@
|
|||||||
|
package dev.inmo.micro_utils.repos.ktor.server.key.values
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.ktor.common.*
|
||||||
|
import dev.inmo.micro_utils.ktor.server.*
|
||||||
|
import dev.inmo.micro_utils.pagination.PaginationResult
|
||||||
|
import dev.inmo.micro_utils.pagination.extractPagination
|
||||||
|
import dev.inmo.micro_utils.repos.ReadKeyValuesRepo
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.*
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.containsRoute
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.countRoute
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.one_to_many.*
|
||||||
|
import io.ktor.http.*
|
||||||
|
import io.ktor.server.application.call
|
||||||
|
import io.ktor.server.response.respond
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
import io.ktor.server.routing.get
|
||||||
|
import io.ktor.util.InternalAPI
|
||||||
|
import io.ktor.util.reflect.typeInfo
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
|
@OptIn(InternalAPI::class)
|
||||||
|
inline fun <reified Key, reified Value> Route.configureReadKeyValuesRepoRoutes (
|
||||||
|
originalRepo: ReadKeyValuesRepo<Key, Value>,
|
||||||
|
noinline keyDeserializer: suspend (String) -> Key,
|
||||||
|
noinline valueDeserializer: suspend (String) -> Value
|
||||||
|
) {
|
||||||
|
val paginationWithValuesTypeInfo = typeInfo<PaginationResult<Value>>()
|
||||||
|
val paginationWithKeysTypeInfo = typeInfo<PaginationResult<Key>>()
|
||||||
|
|
||||||
|
get(getRoute) {
|
||||||
|
val key = keyDeserializer(
|
||||||
|
call.getQueryParameterOrSendError(keyParameterName) ?: return@get
|
||||||
|
)
|
||||||
|
val pagination = call.request.queryParameters.extractPagination
|
||||||
|
val reversed = call.getQueryParameter(reversedParameterName) ?.toBoolean() ?: false
|
||||||
|
|
||||||
|
call.respond(
|
||||||
|
originalRepo.get(key, pagination, reversed),
|
||||||
|
paginationWithValuesTypeInfo
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
get(keysRoute) {
|
||||||
|
val pagination = call.request.queryParameters.extractPagination
|
||||||
|
val reversed = call.getQueryParameterOrSendError(reversedParameterName) ?.toBoolean() ?: false
|
||||||
|
val value = call.getQueryParameter(valueParameterName) ?.let {
|
||||||
|
valueDeserializer(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
call.respond(
|
||||||
|
value ?.let { originalRepo.keys(value, pagination, reversed) } ?: originalRepo.keys(pagination, reversed),
|
||||||
|
paginationWithKeysTypeInfo
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
get(containsRoute) {
|
||||||
|
val key = keyDeserializer(
|
||||||
|
call.getQueryParameterOrSendError(keyParameterName) ?: return@get
|
||||||
|
)
|
||||||
|
val value = call.getQueryParameter(valueParameterName) ?.let {
|
||||||
|
valueDeserializer(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
call.respond(
|
||||||
|
value ?.let { originalRepo.contains(key, value) } ?: originalRepo.contains(key)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
get(countRoute) {
|
||||||
|
val id = call.getQueryParameter(keyParameterName) ?.let {
|
||||||
|
keyDeserializer(it)
|
||||||
|
}
|
||||||
|
call.respond(
|
||||||
|
id ?.let { originalRepo.count(it) } ?: originalRepo.count()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified Key, reified Value> Route.configureReadKeyValuesRepoRoutes(
|
||||||
|
originalRepo: ReadKeyValuesRepo<Key, Value>,
|
||||||
|
keySerializer: DeserializationStrategy<Key>,
|
||||||
|
valueSerializer: DeserializationStrategy<Value>,
|
||||||
|
serialFormat: StringFormat
|
||||||
|
) = configureReadKeyValuesRepoRoutes(
|
||||||
|
originalRepo,
|
||||||
|
{
|
||||||
|
serialFormat.decodeFromString(keySerializer, it.decodeURLQueryComponent())
|
||||||
|
},
|
||||||
|
{
|
||||||
|
serialFormat.decodeFromString(valueSerializer, it.decodeURLQueryComponent())
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
inline fun <reified Key, reified Value> Route.configureReadKeyValuesRepoRoutes(
|
||||||
|
originalRepo: ReadKeyValuesRepo<Key, Value>,
|
||||||
|
keySerializer: DeserializationStrategy<Key>,
|
||||||
|
valueSerializer: DeserializationStrategy<Value>,
|
||||||
|
serialFormat: BinaryFormat
|
||||||
|
) = configureReadKeyValuesRepoRoutes(
|
||||||
|
originalRepo,
|
||||||
|
{
|
||||||
|
serialFormat.decodeHex(keySerializer, it)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
serialFormat.decodeHex(valueSerializer, it)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,58 @@
|
|||||||
|
package dev.inmo.micro_utils.repos.ktor.server.key.values
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.ktor.server.*
|
||||||
|
import dev.inmo.micro_utils.repos.WriteKeyValuesRepo
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.one_to_many.*
|
||||||
|
import io.ktor.http.HttpStatusCode
|
||||||
|
import io.ktor.server.application.call
|
||||||
|
import io.ktor.server.request.receive
|
||||||
|
import io.ktor.server.response.respond
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
import io.ktor.server.routing.post
|
||||||
|
import io.ktor.util.reflect.typeInfo
|
||||||
|
|
||||||
|
inline fun <reified Key : Any, reified Value : Any> Route.configureWriteKeyValuesRepoRoutes (
|
||||||
|
originalRepo: WriteKeyValuesRepo<Key, Value>
|
||||||
|
) {
|
||||||
|
includeWebsocketHandling(
|
||||||
|
onNewValueRoute,
|
||||||
|
originalRepo.onNewValue
|
||||||
|
)
|
||||||
|
|
||||||
|
includeWebsocketHandling(
|
||||||
|
onValueRemovedRoute,
|
||||||
|
originalRepo.onValueRemoved
|
||||||
|
)
|
||||||
|
|
||||||
|
includeWebsocketHandling(
|
||||||
|
onDataClearedRoute,
|
||||||
|
originalRepo.onDataCleared
|
||||||
|
)
|
||||||
|
|
||||||
|
val mapType = typeInfo<Map<Key, List<Value>>>()
|
||||||
|
|
||||||
|
post(addRoute) {
|
||||||
|
originalRepo.add(call.receive(mapType))
|
||||||
|
call.respond(HttpStatusCode.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
post(setRoute) {
|
||||||
|
originalRepo.set(call.receive(mapType))
|
||||||
|
call.respond(HttpStatusCode.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
post(removeRoute) {
|
||||||
|
originalRepo.remove(call.receive(mapType))
|
||||||
|
call.respond(HttpStatusCode.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
post(clearRoute) {
|
||||||
|
originalRepo.clear(call.receive())
|
||||||
|
call.respond(HttpStatusCode.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
post(clearWithValueRoute) {
|
||||||
|
originalRepo.clearWithValue(call.receive())
|
||||||
|
call.respond(HttpStatusCode.OK)
|
||||||
|
}
|
||||||
|
}
|
@ -4,15 +4,15 @@ import dev.inmo.micro_utils.ktor.common.StandardKtorSerialFormat
|
|||||||
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
|
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
|
||||||
import dev.inmo.micro_utils.ktor.server.UnifiedRouter
|
import dev.inmo.micro_utils.ktor.server.UnifiedRouter
|
||||||
import dev.inmo.micro_utils.ktor.server.standardKtorSerialFormatContentType
|
import dev.inmo.micro_utils.ktor.server.standardKtorSerialFormatContentType
|
||||||
import dev.inmo.micro_utils.repos.StandardKeyValueRepo
|
import dev.inmo.micro_utils.repos.KeyValueRepo
|
||||||
import io.ktor.http.ContentType
|
import io.ktor.http.ContentType
|
||||||
import io.ktor.server.routing.Route
|
import io.ktor.server.routing.Route
|
||||||
import io.ktor.server.routing.route
|
import io.ktor.server.routing.route
|
||||||
import kotlinx.serialization.KSerializer
|
import kotlinx.serialization.KSerializer
|
||||||
|
|
||||||
fun <K, V> Route.configureStandardKeyValueRepoRoutes(
|
fun <K, V> Route.configureKeyValueRepoRoutes(
|
||||||
baseSubpart: String,
|
baseSubpart: String,
|
||||||
originalRepo: StandardKeyValueRepo<K, V>,
|
originalRepo: KeyValueRepo<K, V>,
|
||||||
keySerializer: KSerializer<K>,
|
keySerializer: KSerializer<K>,
|
||||||
valueSerializer: KSerializer<V>,
|
valueSerializer: KSerializer<V>,
|
||||||
valueNullableSerializer: KSerializer<V?>,
|
valueNullableSerializer: KSerializer<V?>,
|
||||||
@ -26,7 +26,7 @@ fun <K, V> Route.configureStandardKeyValueRepoRoutes(
|
|||||||
valueNullableSerializer,
|
valueNullableSerializer,
|
||||||
unifiedRouter
|
unifiedRouter
|
||||||
)
|
)
|
||||||
configureWriteStandardKeyValueRepoRoutes(
|
configureWriteKeyValueRepoRoutes(
|
||||||
originalRepo,
|
originalRepo,
|
||||||
keySerializer,
|
keySerializer,
|
||||||
valueSerializer,
|
valueSerializer,
|
||||||
@ -37,10 +37,10 @@ fun <K, V> Route.configureStandardKeyValueRepoRoutes(
|
|||||||
|
|
||||||
fun <K, V> Route.configureStandartKeyValueRepoRoutes(
|
fun <K, V> Route.configureStandartKeyValueRepoRoutes(
|
||||||
baseSubpart: String,
|
baseSubpart: String,
|
||||||
originalRepo: StandardKeyValueRepo<K, V>,
|
originalRepo: KeyValueRepo<K, V>,
|
||||||
keySerializer: KSerializer<K>,
|
keySerializer: KSerializer<K>,
|
||||||
valueSerializer: KSerializer<V>,
|
valueSerializer: KSerializer<V>,
|
||||||
valueNullableSerializer: KSerializer<V?>,
|
valueNullableSerializer: KSerializer<V?>,
|
||||||
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
|
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
|
||||||
serialFormatContentType: ContentType = standardKtorSerialFormatContentType
|
serialFormatContentType: ContentType = standardKtorSerialFormatContentType
|
||||||
) = configureStandardKeyValueRepoRoutes(baseSubpart, originalRepo, keySerializer, valueSerializer, valueNullableSerializer, UnifiedRouter(serialFormat, serialFormatContentType))
|
) = configureKeyValueRepoRoutes(baseSubpart, originalRepo, keySerializer, valueSerializer, valueNullableSerializer, UnifiedRouter(serialFormat, serialFormatContentType))
|
||||||
|
@ -5,9 +5,13 @@ import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
|
|||||||
import dev.inmo.micro_utils.ktor.server.*
|
import dev.inmo.micro_utils.ktor.server.*
|
||||||
import dev.inmo.micro_utils.pagination.PaginationResult
|
import dev.inmo.micro_utils.pagination.PaginationResult
|
||||||
import dev.inmo.micro_utils.pagination.extractPagination
|
import dev.inmo.micro_utils.pagination.extractPagination
|
||||||
import dev.inmo.micro_utils.repos.ReadStandardKeyValueRepo
|
import dev.inmo.micro_utils.repos.ReadKeyValueRepo
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.*
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.containsRoute
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.countRoute
|
||||||
import dev.inmo.micro_utils.repos.ktor.common.key_value.*
|
import dev.inmo.micro_utils.repos.ktor.common.key_value.*
|
||||||
import dev.inmo.micro_utils.repos.ktor.common.valueParameterName
|
import dev.inmo.micro_utils.repos.ktor.common.key_value.keyParameterName
|
||||||
|
import dev.inmo.micro_utils.repos.ktor.common.key_value.reversedParameterName
|
||||||
import io.ktor.http.ContentType
|
import io.ktor.http.ContentType
|
||||||
import io.ktor.server.application.call
|
import io.ktor.server.application.call
|
||||||
import io.ktor.server.routing.Route
|
import io.ktor.server.routing.Route
|
||||||
@ -16,7 +20,7 @@ import kotlinx.serialization.KSerializer
|
|||||||
import kotlinx.serialization.builtins.serializer
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
|
||||||
fun <K, V> Route.configureReadStandartKeyValueRepoRoutes (
|
fun <K, V> Route.configureReadStandartKeyValueRepoRoutes (
|
||||||
originalRepo: ReadStandardKeyValueRepo<K, V>,
|
originalRepo: ReadKeyValueRepo<K, V>,
|
||||||
keySerializer: KSerializer<K>,
|
keySerializer: KSerializer<K>,
|
||||||
valueSerializer: KSerializer<V>,
|
valueSerializer: KSerializer<V>,
|
||||||
valueNullableSerializer: KSerializer<V?>,
|
valueNullableSerializer: KSerializer<V?>,
|
||||||
@ -92,7 +96,7 @@ fun <K, V> Route.configureReadStandartKeyValueRepoRoutes (
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline fun <K, V> Route.configureReadStandartKeyValueRepoRoutes (
|
inline fun <K, V> Route.configureReadStandartKeyValueRepoRoutes (
|
||||||
originalRepo: ReadStandardKeyValueRepo<K, V>,
|
originalRepo: ReadKeyValueRepo<K, V>,
|
||||||
keySerializer: KSerializer<K>,
|
keySerializer: KSerializer<K>,
|
||||||
valueSerializer: KSerializer<V>,
|
valueSerializer: KSerializer<V>,
|
||||||
valueNullableSerializer: KSerializer<V?>,
|
valueNullableSerializer: KSerializer<V?>,
|
||||||
|
@ -3,7 +3,7 @@ package dev.inmo.micro_utils.repos.ktor.server.key_value
|
|||||||
import dev.inmo.micro_utils.ktor.common.StandardKtorSerialFormat
|
import dev.inmo.micro_utils.ktor.common.StandardKtorSerialFormat
|
||||||
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
|
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
|
||||||
import dev.inmo.micro_utils.ktor.server.*
|
import dev.inmo.micro_utils.ktor.server.*
|
||||||
import dev.inmo.micro_utils.repos.WriteStandardKeyValueRepo
|
import dev.inmo.micro_utils.repos.WriteKeyValueRepo
|
||||||
import dev.inmo.micro_utils.repos.ktor.common.key_value.*
|
import dev.inmo.micro_utils.repos.ktor.common.key_value.*
|
||||||
import io.ktor.http.ContentType
|
import io.ktor.http.ContentType
|
||||||
import io.ktor.server.routing.Route
|
import io.ktor.server.routing.Route
|
||||||
@ -11,8 +11,8 @@ import io.ktor.server.routing.post
|
|||||||
import kotlinx.serialization.KSerializer
|
import kotlinx.serialization.KSerializer
|
||||||
import kotlinx.serialization.builtins.*
|
import kotlinx.serialization.builtins.*
|
||||||
|
|
||||||
fun <K, V> Route.configureWriteStandardKeyValueRepoRoutes (
|
fun <K, V> Route.configureWriteKeyValueRepoRoutes (
|
||||||
originalRepo: WriteStandardKeyValueRepo<K, V>,
|
originalRepo: WriteKeyValueRepo<K, V>,
|
||||||
keySerializer: KSerializer<K>,
|
keySerializer: KSerializer<K>,
|
||||||
valueSerializer: KSerializer<V>,
|
valueSerializer: KSerializer<V>,
|
||||||
unifiedRouter: UnifiedRouter
|
unifiedRouter: UnifiedRouter
|
||||||
@ -62,9 +62,9 @@ fun <K, V> Route.configureWriteStandardKeyValueRepoRoutes (
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun <K, V> Route.configureWriteStandartKeyValueRepoRoutes (
|
fun <K, V> Route.configureWriteStandartKeyValueRepoRoutes (
|
||||||
originalRepo: WriteStandardKeyValueRepo<K, V>,
|
originalRepo: WriteKeyValueRepo<K, V>,
|
||||||
keySerializer: KSerializer<K>,
|
keySerializer: KSerializer<K>,
|
||||||
valueSerializer: KSerializer<V>,
|
valueSerializer: KSerializer<V>,
|
||||||
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
|
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
|
||||||
serialFormatContentType: ContentType = standardKtorSerialFormatContentType
|
serialFormatContentType: ContentType = standardKtorSerialFormatContentType
|
||||||
) = configureWriteStandardKeyValueRepoRoutes(originalRepo, keySerializer, valueSerializer, UnifiedRouter(serialFormat, serialFormatContentType))
|
) = configureWriteKeyValueRepoRoutes(originalRepo, keySerializer, valueSerializer, UnifiedRouter(serialFormat, serialFormatContentType))
|
||||||
|
@ -4,7 +4,7 @@ import dev.inmo.micro_utils.ktor.common.StandardKtorSerialFormat
|
|||||||
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
|
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
|
||||||
import dev.inmo.micro_utils.ktor.server.UnifiedRouter
|
import dev.inmo.micro_utils.ktor.server.UnifiedRouter
|
||||||
import dev.inmo.micro_utils.ktor.server.standardKtorSerialFormatContentType
|
import dev.inmo.micro_utils.ktor.server.standardKtorSerialFormatContentType
|
||||||
import dev.inmo.micro_utils.repos.OneToManyKeyValueRepo
|
import dev.inmo.micro_utils.repos.KeyValuesRepo
|
||||||
import io.ktor.http.ContentType
|
import io.ktor.http.ContentType
|
||||||
import io.ktor.server.routing.Route
|
import io.ktor.server.routing.Route
|
||||||
import io.ktor.server.routing.route
|
import io.ktor.server.routing.route
|
||||||
@ -12,7 +12,7 @@ import kotlinx.serialization.KSerializer
|
|||||||
|
|
||||||
fun <Key, Value> Route.configureOneToManyKeyValueRepoRoutes(
|
fun <Key, Value> Route.configureOneToManyKeyValueRepoRoutes(
|
||||||
baseSubpart: String,
|
baseSubpart: String,
|
||||||
originalRepo: OneToManyKeyValueRepo<Key, Value>,
|
originalRepo: KeyValuesRepo<Key, Value>,
|
||||||
keySerializer: KSerializer<Key>,
|
keySerializer: KSerializer<Key>,
|
||||||
valueSerializer: KSerializer<Value>,
|
valueSerializer: KSerializer<Value>,
|
||||||
unifiedRouter: UnifiedRouter
|
unifiedRouter: UnifiedRouter
|
||||||
@ -25,7 +25,7 @@ fun <Key, Value> Route.configureOneToManyKeyValueRepoRoutes(
|
|||||||
|
|
||||||
fun <Key, Value> Route.configureOneToManyKeyValueRepoRoutes(
|
fun <Key, Value> Route.configureOneToManyKeyValueRepoRoutes(
|
||||||
baseSubpart: String,
|
baseSubpart: String,
|
||||||
originalRepo: OneToManyKeyValueRepo<Key, Value>,
|
originalRepo: KeyValuesRepo<Key, Value>,
|
||||||
keySerializer: KSerializer<Key>,
|
keySerializer: KSerializer<Key>,
|
||||||
valueSerializer: KSerializer<Value>,
|
valueSerializer: KSerializer<Value>,
|
||||||
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
|
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
|
||||||
|
@ -5,7 +5,7 @@ import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
|
|||||||
import dev.inmo.micro_utils.ktor.server.*
|
import dev.inmo.micro_utils.ktor.server.*
|
||||||
import dev.inmo.micro_utils.pagination.PaginationResult
|
import dev.inmo.micro_utils.pagination.PaginationResult
|
||||||
import dev.inmo.micro_utils.pagination.extractPagination
|
import dev.inmo.micro_utils.pagination.extractPagination
|
||||||
import dev.inmo.micro_utils.repos.ReadOneToManyKeyValueRepo
|
import dev.inmo.micro_utils.repos.ReadKeyValuesRepo
|
||||||
import dev.inmo.micro_utils.repos.ktor.common.keyParameterName
|
import dev.inmo.micro_utils.repos.ktor.common.keyParameterName
|
||||||
import dev.inmo.micro_utils.repos.ktor.common.one_to_many.*
|
import dev.inmo.micro_utils.repos.ktor.common.one_to_many.*
|
||||||
import dev.inmo.micro_utils.repos.ktor.common.valueParameterName
|
import dev.inmo.micro_utils.repos.ktor.common.valueParameterName
|
||||||
@ -18,7 +18,7 @@ import kotlinx.serialization.KSerializer
|
|||||||
import kotlinx.serialization.builtins.serializer
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
|
||||||
fun <Key, Value> Route.configureOneToManyReadKeyValueRepoRoutes(
|
fun <Key, Value> Route.configureOneToManyReadKeyValueRepoRoutes(
|
||||||
originalRepo: ReadOneToManyKeyValueRepo<Key, Value>,
|
originalRepo: ReadKeyValuesRepo<Key, Value>,
|
||||||
keySerializer: KSerializer<Key>,
|
keySerializer: KSerializer<Key>,
|
||||||
valueSerializer: KSerializer<Value>,
|
valueSerializer: KSerializer<Value>,
|
||||||
unifiedRouter: UnifiedRouter
|
unifiedRouter: UnifiedRouter
|
||||||
@ -121,7 +121,7 @@ fun <Key, Value> Route.configureOneToManyReadKeyValueRepoRoutes(
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline fun <Key, Value> Route.configureOneToManyReadKeyValueRepoRoutes(
|
inline fun <Key, Value> Route.configureOneToManyReadKeyValueRepoRoutes(
|
||||||
originalRepo: ReadOneToManyKeyValueRepo<Key, Value>,
|
originalRepo: ReadKeyValuesRepo<Key, Value>,
|
||||||
keySerializer: KSerializer<Key>,
|
keySerializer: KSerializer<Key>,
|
||||||
valueSerializer: KSerializer<Value>,
|
valueSerializer: KSerializer<Value>,
|
||||||
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
|
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
|
||||||
|
@ -3,7 +3,7 @@ package dev.inmo.micro_utils.repos.ktor.server.one_to_many
|
|||||||
import dev.inmo.micro_utils.ktor.common.StandardKtorSerialFormat
|
import dev.inmo.micro_utils.ktor.common.StandardKtorSerialFormat
|
||||||
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
|
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
|
||||||
import dev.inmo.micro_utils.ktor.server.*
|
import dev.inmo.micro_utils.ktor.server.*
|
||||||
import dev.inmo.micro_utils.repos.WriteOneToManyKeyValueRepo
|
import dev.inmo.micro_utils.repos.WriteKeyValuesRepo
|
||||||
import dev.inmo.micro_utils.repos.ktor.common.one_to_many.*
|
import dev.inmo.micro_utils.repos.ktor.common.one_to_many.*
|
||||||
import io.ktor.http.ContentType
|
import io.ktor.http.ContentType
|
||||||
import io.ktor.server.routing.Route
|
import io.ktor.server.routing.Route
|
||||||
@ -12,7 +12,7 @@ import kotlinx.serialization.KSerializer
|
|||||||
import kotlinx.serialization.builtins.*
|
import kotlinx.serialization.builtins.*
|
||||||
|
|
||||||
fun <Key, Value> Route.configureOneToManyWriteKeyValueRepoRoutes(
|
fun <Key, Value> Route.configureOneToManyWriteKeyValueRepoRoutes(
|
||||||
originalRepo: WriteOneToManyKeyValueRepo<Key, Value>,
|
originalRepo: WriteKeyValuesRepo<Key, Value>,
|
||||||
keySerializer: KSerializer<Key>,
|
keySerializer: KSerializer<Key>,
|
||||||
valueSerializer: KSerializer<Value>,
|
valueSerializer: KSerializer<Value>,
|
||||||
unifiedRouter: UnifiedRouter
|
unifiedRouter: UnifiedRouter
|
||||||
@ -95,7 +95,7 @@ fun <Key, Value> Route.configureOneToManyWriteKeyValueRepoRoutes(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun <Key, Value> Route.configureOneToManyWriteKeyValueRepoRoutes(
|
fun <Key, Value> Route.configureOneToManyWriteKeyValueRepoRoutes(
|
||||||
originalRepo: WriteOneToManyKeyValueRepo<Key, Value>,
|
originalRepo: WriteKeyValuesRepo<Key, Value>,
|
||||||
keySerializer: KSerializer<Key>,
|
keySerializer: KSerializer<Key>,
|
||||||
valueSerializer: KSerializer<Value>,
|
valueSerializer: KSerializer<Value>,
|
||||||
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
|
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
|
||||||
|
Loading…
Reference in New Issue
Block a user