From cb6fedfb52bc639e8624da8cef2bff864f35b27b Mon Sep 17 00:00:00 2001 From: 000Sanya <000sanya.000sanya@gmail.com> Date: Sat, 29 Aug 2020 12:33:13 +1000 Subject: [PATCH] impl client and server for KeyValueRepo --- .../key_value/KtorStandartKeyValueRepo.kt | 30 ++++++++ .../key_value/KtorStandartReadKeyValueRepo.kt | 73 ++++++++++++++++++ .../KtorStandartWriteKeyValueRepo.kt | 49 ++++++++++++ .../key_value/KeyValueParameterNames.kt | 4 + .../common/key_value/KeyValuePostObject.kt | 9 +++ .../ktor/common/key_value/KeyValueRoutes.kt | 12 +++ .../key_value/KtorStandartKeyValueRepo.kt | 27 +++++++ .../key_value/KtorStandartReadKeyValueRepo.kt | 76 +++++++++++++++++++ .../KtorStandartWriteKeyValueRepo.kt | 44 +++++++++++ 9 files changed, 324 insertions(+) create mode 100644 utils/repos/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/client/key_value/KtorStandartKeyValueRepo.kt create mode 100644 utils/repos/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/client/key_value/KtorStandartReadKeyValueRepo.kt create mode 100644 utils/repos/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/client/key_value/KtorStandartWriteKeyValueRepo.kt create mode 100644 utils/repos/ktor/common/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/common/key_value/KeyValueParameterNames.kt create mode 100644 utils/repos/ktor/common/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/common/key_value/KeyValuePostObject.kt create mode 100644 utils/repos/ktor/common/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/common/key_value/KeyValueRoutes.kt create mode 100644 utils/repos/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/server/key_value/KtorStandartKeyValueRepo.kt create mode 100644 utils/repos/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/server/key_value/KtorStandartReadKeyValueRepo.kt create mode 100644 utils/repos/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/server/key_value/KtorStandartWriteKeyValueRepo.kt diff --git a/utils/repos/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/client/key_value/KtorStandartKeyValueRepo.kt b/utils/repos/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/client/key_value/KtorStandartKeyValueRepo.kt new file mode 100644 index 00000000..aea0e77f --- /dev/null +++ b/utils/repos/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/client/key_value/KtorStandartKeyValueRepo.kt @@ -0,0 +1,30 @@ +package com.insanusmokrassar.postssystem.utils.repos.ktor.client.key_value + +import com.insanusmokrassar.postssystem.utils.repos.StandardKeyValueRepo +import com.insanusmokrassar.postssystem.utils.repos.StandardReadKeyValueRepo +import com.insanusmokrassar.postssystem.utils.repos.StandardWriteKeyValueRepo +import io.ktor.client.* +import kotlinx.serialization.ContextualSerializer +import kotlinx.serialization.KSerializer + +class KtorStandartKeyValueRepo ( + baseUrl: String, + baseSubpart: String, + client: HttpClient = HttpClient(), + keySerializer: KSerializer, + valueSerializer: KSerializer, + valueNullableSerializer: KSerializer +) : StandardKeyValueRepo, + StandardReadKeyValueRepo by KtorStandartReadKeyValueRepo( + "$baseUrl/$baseSubpart", + client, + keySerializer, + valueSerializer, + valueNullableSerializer + ), + StandardWriteKeyValueRepo by KtorStandartWriteKeyValueRepo( + "$baseUrl/$baseSubpart", + client, + keySerializer, + valueSerializer + ) \ No newline at end of file diff --git a/utils/repos/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/client/key_value/KtorStandartReadKeyValueRepo.kt b/utils/repos/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/client/key_value/KtorStandartReadKeyValueRepo.kt new file mode 100644 index 00000000..0cab8c9b --- /dev/null +++ b/utils/repos/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/client/key_value/KtorStandartReadKeyValueRepo.kt @@ -0,0 +1,73 @@ +package com.insanusmokrassar.postssystem.utils.repos.ktor.client.key_value + +import com.insanusmokrassar.postssystem.ktor.asUrlQueryParts +import com.insanusmokrassar.postssystem.ktor.buildStandardUrl +import com.insanusmokrassar.postssystem.ktor.client.uniget +import com.insanusmokrassar.postssystem.ktor.toHex +import com.insanusmokrassar.postssystem.utils.common.pagination.Pagination +import com.insanusmokrassar.postssystem.utils.common.pagination.PaginationResult +import com.insanusmokrassar.postssystem.utils.repos.StandardReadKeyValueRepo +import com.insanusmokrassar.postssystem.utils.repos.ktor.common.key_value.* +import io.ktor.client.* +import kotlinx.serialization.KSerializer +import kotlinx.serialization.builtins.serializer + +class KtorStandartReadKeyValueRepo ( + private var baseUrl: String, + private var client: HttpClient = HttpClient(), + private var keySerializer: KSerializer, + private var valueSerializer: KSerializer, + private var valueNullableSerializer: KSerializer, +) : StandardReadKeyValueRepo { + override suspend fun get(k: Key): Value? = client.uniget( + buildStandardUrl( + baseUrl, + getRoute, + mapOf( + keyParameterName to k.toHex(keySerializer) + ) + ), + valueNullableSerializer + ) + + override suspend fun values(pagination: Pagination, reversed: Boolean): PaginationResult = client.uniget( + buildStandardUrl( + baseUrl, + valuesRoute, + mapOf( + reversedParameterName to reversed.toHex(Boolean.serializer()) + ) + pagination.asUrlQueryParts + ), + PaginationResult.serializer(valueSerializer) + ) + + override suspend fun keys(pagination: Pagination, reversed: Boolean): PaginationResult = client.uniget( + buildStandardUrl( + baseUrl, + keysRoute, + mapOf( + reversedParameterName to reversed.toHex(Boolean.serializer()) + ) + pagination.asUrlQueryParts + ), + PaginationResult.serializer(keySerializer) + ) + + override suspend fun contains(key: Key): Boolean = client.uniget( + buildStandardUrl( + baseUrl, + containsRoute, + mapOf( + keyParameterName to key.toHex(keySerializer) + ), + ), + Boolean.serializer(), + ) + + override suspend fun count(): Long = client.uniget( + buildStandardUrl( + baseUrl, + containsRoute, + ), + Long.serializer() + ) +} \ No newline at end of file diff --git a/utils/repos/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/client/key_value/KtorStandartWriteKeyValueRepo.kt b/utils/repos/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/client/key_value/KtorStandartWriteKeyValueRepo.kt new file mode 100644 index 00000000..918d2350 --- /dev/null +++ b/utils/repos/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/client/key_value/KtorStandartWriteKeyValueRepo.kt @@ -0,0 +1,49 @@ +package com.insanusmokrassar.postssystem.utils.repos.ktor.client.key_value + +import com.insanusmokrassar.postssystem.ktor.buildStandardUrl +import com.insanusmokrassar.postssystem.ktor.client.BodyPair +import com.insanusmokrassar.postssystem.ktor.client.createStandardWebsocketFlow +import com.insanusmokrassar.postssystem.ktor.client.uniget +import com.insanusmokrassar.postssystem.ktor.client.unipost +import com.insanusmokrassar.postssystem.utils.repos.StandardWriteKeyValueRepo +import com.insanusmokrassar.postssystem.utils.repos.ktor.common.key_value.* +import io.ktor.client.* +import kotlinx.coroutines.flow.Flow +import kotlinx.serialization.KSerializer +import kotlinx.serialization.builtins.PairSerializer +import kotlinx.serialization.builtins.serializer + +class KtorStandartWriteKeyValueRepo ( + private var baseUrl: String, + private var client: HttpClient = HttpClient(), + private var keySerializer: KSerializer, + private var valueSerializer: KSerializer, +) : StandardWriteKeyValueRepo { + override val onNewValue: Flow> = client.createStandardWebsocketFlow( + buildStandardUrl(baseUrl, onNewValueRoute), + deserializer = PairSerializer(keySerializer, valueSerializer) + ) + + override val onValueRemoved: Flow = client.createStandardWebsocketFlow( + buildStandardUrl(baseUrl, onValueRemovedRoute), + deserializer = keySerializer + ) + + override suspend fun set(k: K, v: V) = client.unipost( + buildStandardUrl( + baseUrl, + setRoute + ), + BodyPair(KeyValuePostObject.serializer(keySerializer, valueSerializer), KeyValuePostObject(k, v)), + Unit.serializer() + ) + + override suspend fun unset(k: K) = client.unipost( + buildStandardUrl( + baseUrl, + unsetRoute, + ), + BodyPair(keySerializer, k), + Unit.serializer() + ) +} \ No newline at end of file diff --git a/utils/repos/ktor/common/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/common/key_value/KeyValueParameterNames.kt b/utils/repos/ktor/common/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/common/key_value/KeyValueParameterNames.kt new file mode 100644 index 00000000..54d557ac --- /dev/null +++ b/utils/repos/ktor/common/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/common/key_value/KeyValueParameterNames.kt @@ -0,0 +1,4 @@ +package com.insanusmokrassar.postssystem.utils.repos.ktor.common.key_value + +const val keyParameterName = "key" +const val reversedParameterName = "reversed" \ No newline at end of file diff --git a/utils/repos/ktor/common/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/common/key_value/KeyValuePostObject.kt b/utils/repos/ktor/common/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/common/key_value/KeyValuePostObject.kt new file mode 100644 index 00000000..720f70b4 --- /dev/null +++ b/utils/repos/ktor/common/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/common/key_value/KeyValuePostObject.kt @@ -0,0 +1,9 @@ +package com.insanusmokrassar.postssystem.utils.repos.ktor.common.key_value + +import kotlinx.serialization.Serializable + +@Serializable +data class KeyValuePostObject ( + val key: K, + val value: V, +) \ No newline at end of file diff --git a/utils/repos/ktor/common/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/common/key_value/KeyValueRoutes.kt b/utils/repos/ktor/common/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/common/key_value/KeyValueRoutes.kt new file mode 100644 index 00000000..e3c724b6 --- /dev/null +++ b/utils/repos/ktor/common/src/commonMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/common/key_value/KeyValueRoutes.kt @@ -0,0 +1,12 @@ +package com.insanusmokrassar.postssystem.utils.repos.ktor.common.key_value + +const val getRoute = "get" +const val valuesRoute = "values" +const val keysRoute = "keys" +const val containsRoute = "contains" +const val countRoute = "count" + +const val onNewValueRoute = "onNewValue" +const val onValueRemovedRoute = "onValueRemoved" +const val setRoute = "set" +const val unsetRoute = "unset" \ No newline at end of file diff --git a/utils/repos/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/server/key_value/KtorStandartKeyValueRepo.kt b/utils/repos/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/server/key_value/KtorStandartKeyValueRepo.kt new file mode 100644 index 00000000..95401505 --- /dev/null +++ b/utils/repos/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/server/key_value/KtorStandartKeyValueRepo.kt @@ -0,0 +1,27 @@ +package com.insanusmokrassar.postssystem.utils.repos.ktor.server.key_value + +import com.insanusmokrassar.postssystem.utils.repos.StandardKeyValueRepo +import io.ktor.routing.* +import kotlinx.serialization.KSerializer + +fun Route.configureStandartKeyValueRepoRoutes( + baseSubpart: String, + originalRepo: StandardKeyValueRepo, + keySerializer: KSerializer, + valueSerializer: KSerializer, + valueNullableSerializer: KSerializer, +) { + route(baseSubpart) { + configureReadStandartKeyValueRepoRoutes( + originalRepo, + keySerializer, + valueSerializer, + valueNullableSerializer, + ) + configureWriteStandartKeyValueRepoRoutes( + originalRepo, + keySerializer, + valueSerializer, + ) + } +} \ No newline at end of file diff --git a/utils/repos/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/server/key_value/KtorStandartReadKeyValueRepo.kt b/utils/repos/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/server/key_value/KtorStandartReadKeyValueRepo.kt new file mode 100644 index 00000000..f2eeafc4 --- /dev/null +++ b/utils/repos/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/server/key_value/KtorStandartReadKeyValueRepo.kt @@ -0,0 +1,76 @@ +package com.insanusmokrassar.postssystem.utils.repos.ktor.server.key_value + +import com.insanusmokrassar.postssystem.ktor.server.extractPagination +import com.insanusmokrassar.postssystem.ktor.server.unianswer +import com.insanusmokrassar.postssystem.ktor.server.uniloadFromQueryOrSendError +import com.insanusmokrassar.postssystem.utils.common.pagination.PaginationResult +import com.insanusmokrassar.postssystem.utils.repos.StandardReadKeyValueRepo +import com.insanusmokrassar.postssystem.utils.repos.ktor.common.key_value.* +import io.ktor.application.* +import io.ktor.routing.* +import kotlinx.serialization.KSerializer +import kotlinx.serialization.builtins.serializer + +fun Route.configureReadStandartKeyValueRepoRoutes ( + originalRepo: StandardReadKeyValueRepo, + keySerializer: KSerializer, + valueSerializer: KSerializer, + valueNullableSerializer: KSerializer, +) { + get(getRoute) { + val key = call.uniloadFromQueryOrSendError( + keyParameterName, + keySerializer + ) ?: return@get + + call.unianswer( + valueNullableSerializer, + originalRepo.get(key) + ) + } + + get(valuesRoute) { + val parination = call.request.queryParameters.extractPagination; + val reversed = call.uniloadFromQueryOrSendError( + reversedParameterName, + Boolean.serializer() + ) ?: return@get + + call.unianswer( + PaginationResult.serializer(valueSerializer), + originalRepo.values(parination, reversed) + ) + } + + get(keysRoute) { + val parination = call.request.queryParameters.extractPagination; + val reversed = call.uniloadFromQueryOrSendError( + reversedParameterName, + Boolean.serializer() + ) ?: return@get + + call.unianswer( + PaginationResult.serializer(keySerializer), + originalRepo.keys(parination, reversed) + ) + } + + get(containsRoute) { + val key = call.uniloadFromQueryOrSendError( + keyParameterName, + keySerializer + ) ?: return@get + + call.unianswer( + Boolean.serializer(), + originalRepo.contains(key) + ) + } + + get(countRoute) { + call.unianswer( + Long.serializer(), + originalRepo.count() + ) + } +} \ No newline at end of file diff --git a/utils/repos/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/server/key_value/KtorStandartWriteKeyValueRepo.kt b/utils/repos/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/server/key_value/KtorStandartWriteKeyValueRepo.kt new file mode 100644 index 00000000..f74a6296 --- /dev/null +++ b/utils/repos/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/server/key_value/KtorStandartWriteKeyValueRepo.kt @@ -0,0 +1,44 @@ +package com.insanusmokrassar.postssystem.utils.repos.ktor.server.key_value + +import com.insanusmokrassar.postssystem.ktor.server.includeWebsocketHandling +import com.insanusmokrassar.postssystem.ktor.server.uniload +import com.insanusmokrassar.postssystem.utils.repos.StandardWriteKeyValueRepo +import com.insanusmokrassar.postssystem.utils.repos.ktor.common.key_value.* +import io.ktor.application.* +import io.ktor.routing.* +import kotlinx.serialization.KSerializer +import kotlinx.serialization.builtins.PairSerializer + +fun Route.configureWriteStandartKeyValueRepoRoutes ( + originalRepo: StandardWriteKeyValueRepo, + keySerializer: KSerializer, + valueSerializer: KSerializer, +) { + includeWebsocketHandling( + onNewValueRoute, + originalRepo.onNewValue, + PairSerializer(keySerializer, valueSerializer) + ) + + includeWebsocketHandling( + onValueRemovedRoute, + originalRepo.onValueRemoved, + keySerializer + ) + + post(setRoute) { + val (key, value) = call.uniload( + KeyValuePostObject.serializer(keySerializer, valueSerializer) + ) + + originalRepo.set(key, value) + } + + post(unsetRoute) { + val key = call.uniload( + keySerializer + ) + + originalRepo.unset(key) + } +} \ No newline at end of file