Merge pull request #24 from InsanusMokrassar/0.4.7

0.4.7
This commit is contained in:
InsanusMokrassar 2020-11-27 19:30:40 +06:00 committed by GitHub
commit 2b6ef8b4ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 766 additions and 358 deletions

View File

@ -1,5 +1,19 @@
# Changelog
## 0.4.7
* `Ktor`
* `Client`
* New class `UnifiedRequester`
* `Server`
* New class `UnifiedRouter`
* `Repos`
* `Ktor`
* `Client`
* Rewriting of all clients on new `UnifiedRequester`
* `Server`
* Rewriting of all clients on new `UnifiedRouter`
## 0.4.6
* `Common`

View File

@ -41,5 +41,5 @@ dokka_version=1.4.0
# Project data
group=dev.inmo
version=0.4.6
android_code_version=10
version=0.4.7
android_code_version=11

View File

@ -64,10 +64,11 @@ inline fun <T> HttpClient.createStandardWebsocketFlow(
inline fun <T> HttpClient.createStandardWebsocketFlow(
url: String,
crossinline checkReconnection: (Throwable?) -> Boolean = { true },
deserializer: DeserializationStrategy<T>
deserializer: DeserializationStrategy<T>,
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat
) = createStandardWebsocketFlow(
url,
checkReconnection
) {
standardKtorSerialFormat.decodeDefault(deserializer, it)
serialFormat.decodeDefault(deserializer, it)
}

View File

@ -4,32 +4,61 @@ import dev.inmo.micro_utils.ktor.common.*
import io.ktor.client.HttpClient
import io.ktor.client.request.get
import io.ktor.client.request.post
import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.SerializationStrategy
import kotlinx.serialization.*
typealias BodyPair<T> = Pair<SerializationStrategy<T>, T>
class UnifiedRequester(
private val client: HttpClient = HttpClient(),
private val serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat
) {
suspend fun <ResultType> uniget(
url: String,
resultDeserializer: DeserializationStrategy<ResultType>
): ResultType = client.get<StandardKtorSerialInputData>(
url
).let {
serialFormat.decodeDefault(resultDeserializer, it)
}
fun <T> encodeUrlQueryValue(
serializationStrategy: SerializationStrategy<T>,
value: T
) = serialFormat.encodeHex(
serializationStrategy,
value
)
suspend fun <BodyType, ResultType> unipost(
url: String,
bodyInfo: BodyPair<BodyType>,
resultDeserializer: DeserializationStrategy<ResultType>
) = client.post<StandardKtorSerialInputData>(url) {
body = serialFormat.encodeDefault(bodyInfo.first, bodyInfo.second)
}.let {
serialFormat.decodeDefault(resultDeserializer, it)
}
fun <T> createStandardWebsocketFlow(
url: String,
checkReconnection: (Throwable?) -> Boolean = { true },
deserializer: DeserializationStrategy<T>
) = client.createStandardWebsocketFlow(url, checkReconnection, deserializer, serialFormat)
}
val defaultRequester = UnifiedRequester()
suspend fun <ResultType> HttpClient.uniget(
url: String,
resultDeserializer: DeserializationStrategy<ResultType>
) = get<StandardKtorSerialInputData>(
url
).let {
standardKtorSerialFormat.decodeDefault(resultDeserializer, it)
}
) = defaultRequester.uniget(url, resultDeserializer)
fun <T> SerializationStrategy<T>.encodeUrlQueryValue(value: T) = standardKtorSerialFormat.encodeHex(
this,
value
)
fun <T> SerializationStrategy<T>.encodeUrlQueryValue(value: T) = defaultRequester.encodeUrlQueryValue(this, value)
suspend fun <BodyType, ResultType> HttpClient.unipost(
url: String,
bodyInfo: BodyPair<BodyType>,
resultDeserializer: DeserializationStrategy<ResultType>
) = post<StandardKtorSerialInputData>(url) {
body = standardKtorSerialFormat.encodeDefault(bodyInfo.first, bodyInfo.second)
}.let {
standardKtorSerialFormat.decodeDefault(resultDeserializer, it)
}
) = defaultRequester.unipost(url, bodyInfo, resultDeserializer)

View File

@ -33,10 +33,11 @@ fun <T> Route.includeWebsocketHandling(
fun <T> Route.includeWebsocketHandling(
suburl: String,
flow: Flow<T>,
serializer: SerializationStrategy<T>
serializer: SerializationStrategy<T>,
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat
) = includeWebsocketHandling(
suburl,
flow
) {
standardKtorSerialFormat.encodeDefault(serializer, it)
serialFormat.encodeDefault(serializer, it)
}

View File

@ -3,12 +3,87 @@ package dev.inmo.micro_utils.ktor.server
import dev.inmo.micro_utils.coroutines.safely
import dev.inmo.micro_utils.ktor.common.*
import io.ktor.application.ApplicationCall
import io.ktor.application.call
import io.ktor.http.ContentType
import io.ktor.http.HttpStatusCode
import io.ktor.request.receive
import io.ktor.response.respond
import io.ktor.response.respondBytes
import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.SerializationStrategy
import io.ktor.routing.Route
import io.ktor.util.pipeline.PipelineContext
import kotlinx.coroutines.flow.Flow
import kotlinx.serialization.*
class UnifiedRouter(
private val serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
private val serialFormatContentType: ContentType = standardKtorSerialFormatContentType
) {
fun <T> Route.includeWebsocketHandling(
suburl: String,
flow: Flow<T>,
serializer: SerializationStrategy<T>
) = includeWebsocketHandling(suburl, flow, serializer, serialFormat)
suspend fun <T> PipelineContext<*, ApplicationCall>.unianswer(
answerSerializer: SerializationStrategy<T>,
answer: T
) {
call.respondBytes (
serialFormat.encodeDefault(answerSerializer, answer),
serialFormatContentType
)
}
suspend fun <T> PipelineContext<*, ApplicationCall>.uniload(
deserializer: DeserializationStrategy<T>
) = safely {
serialFormat.decodeDefault(
deserializer,
call.receive()
)
}
suspend fun PipelineContext<*, ApplicationCall>.getParameterOrSendError(
field: String
) = call.parameters[field].also {
if (it == null) {
call.respond(HttpStatusCode.BadRequest, "Request must contains $field")
}
}
fun PipelineContext<*, ApplicationCall>.getQueryParameter(
field: String
) = call.request.queryParameters[field]
suspend fun PipelineContext<*, ApplicationCall>.getQueryParameterOrSendError(
field: String
) = getQueryParameter(field).also {
if (it == null) {
call.respond(HttpStatusCode.BadRequest, "Request query parameters must contains $field")
}
}
fun <T> PipelineContext<*, ApplicationCall>.decodeUrlQueryValue(
field: String,
deserializer: DeserializationStrategy<T>
) = getQueryParameter(field) ?.let {
serialFormat.decodeHex(
deserializer,
it
)
}
suspend fun <T> PipelineContext<*, ApplicationCall>.decodeUrlQueryValueOrSendError(
field: String,
deserializer: DeserializationStrategy<T>
) = decodeUrlQueryValue(field, deserializer).also {
if (it == null) {
call.respond(HttpStatusCode.BadRequest, "Request query parameters must contains $field")
}
}
}
val defaultUnifiedRouter = UnifiedRouter()
suspend fun <T> ApplicationCall.unianswer(
answerSerializer: SerializationStrategy<T>,

View File

@ -1,8 +1,7 @@
package dev.inmo.micro_utils.repos.ktor.client.crud
import dev.inmo.micro_utils.ktor.client.encodeUrlQueryValue
import dev.inmo.micro_utils.ktor.client.uniget
import dev.inmo.micro_utils.ktor.common.buildStandardUrl
import dev.inmo.micro_utils.ktor.client.*
import dev.inmo.micro_utils.ktor.common.*
import dev.inmo.micro_utils.pagination.*
import dev.inmo.micro_utils.repos.ReadStandardCRUDRepo
import dev.inmo.micro_utils.repos.ktor.common.crud.*
@ -12,41 +11,52 @@ import kotlinx.serialization.builtins.serializer
class KtorReadStandardCrudRepo<ObjectType, IdType> (
private val baseUrl: String,
private val client: HttpClient = HttpClient(),
private val unifiedRequester: UnifiedRequester,
private val objectsSerializer: KSerializer<ObjectType>,
private val objectsSerializerNullable: KSerializer<ObjectType?>,
private val idsSerializer: KSerializer<IdType>
) : ReadStandardCRUDRepo<ObjectType, IdType> {
private val paginationResultSerializer = PaginationResult.serializer(objectsSerializer)
override suspend fun getByPagination(pagination: Pagination): PaginationResult<ObjectType> = client.uniget(
constructor(
baseUrl: String,
client: HttpClient,
objectsSerializer: KSerializer<ObjectType>,
objectsSerializerNullable: KSerializer<ObjectType?>,
idsSerializer: KSerializer<IdType>,
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat
) : this (
baseUrl, UnifiedRequester(client, serialFormat), objectsSerializer, objectsSerializerNullable, idsSerializer
)
override suspend fun getByPagination(pagination: Pagination): PaginationResult<ObjectType> = unifiedRequester.uniget(
buildStandardUrl(baseUrl, getByPaginationRouting, pagination.asUrlQueryParts),
paginationResultSerializer
)
override suspend fun getById(id: IdType): ObjectType? = client.uniget(
override suspend fun getById(id: IdType): ObjectType? = unifiedRequester.uniget(
buildStandardUrl(
baseUrl,
getByIdRouting,
mapOf(
"id" to idsSerializer.encodeUrlQueryValue(id)
"id" to unifiedRequester.encodeUrlQueryValue(idsSerializer, id)
)
),
objectsSerializerNullable
)
override suspend fun contains(id: IdType): Boolean = client.uniget(
override suspend fun contains(id: IdType): Boolean = unifiedRequester.uniget(
buildStandardUrl(
baseUrl,
containsRouting,
mapOf(
"id" to idsSerializer.encodeUrlQueryValue(id)
"id" to unifiedRequester.encodeUrlQueryValue(idsSerializer, id)
)
),
Boolean.serializer()
)
override suspend fun count(): Long = client.uniget(
override suspend fun count(): Long = unifiedRequester.uniget(
buildStandardUrl(
baseUrl,
countRouting

View File

@ -1,5 +1,8 @@
package dev.inmo.micro_utils.repos.ktor.client.crud
import dev.inmo.micro_utils.ktor.client.UnifiedRequester
import dev.inmo.micro_utils.ktor.common.StandardKtorSerialFormat
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
import dev.inmo.micro_utils.repos.*
import io.ktor.client.HttpClient
import kotlinx.serialization.KSerializer
@ -7,7 +10,7 @@ import kotlinx.serialization.KSerializer
class KtorStandardCrudRepo<ObjectType, IdType, InputValue> (
baseUrl: String,
baseSubpart: String,
client: HttpClient,
unifiedRequester: UnifiedRequester,
objectsSerializer: KSerializer<ObjectType>,
objectsNullableSerializer: KSerializer<ObjectType?>,
inputsSerializer: KSerializer<InputValue>,
@ -15,16 +18,29 @@ class KtorStandardCrudRepo<ObjectType, IdType, InputValue> (
) : StandardCRUDRepo<ObjectType, IdType, InputValue>,
ReadStandardCRUDRepo<ObjectType, IdType> by KtorReadStandardCrudRepo(
"$baseUrl/$baseSubpart",
client,
unifiedRequester,
objectsSerializer,
objectsNullableSerializer,
idsSerializer
),
WriteStandardCRUDRepo<ObjectType, IdType, InputValue> by KtorWriteStandardCrudRepo(
"$baseUrl/$baseSubpart",
client,
unifiedRequester,
objectsSerializer,
objectsNullableSerializer,
inputsSerializer,
idsSerializer
) {
constructor(
baseUrl: String,
baseSubpart: String,
client: HttpClient,
objectsSerializer: KSerializer<ObjectType>,
objectsNullableSerializer: KSerializer<ObjectType?>,
inputsSerializer: KSerializer<InputValue>,
idsSerializer: KSerializer<IdType>,
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat
) : this(
baseUrl, baseSubpart, UnifiedRequester(client, serialFormat), objectsSerializer, objectsNullableSerializer, inputsSerializer, idsSerializer
)
}

View File

@ -1,7 +1,7 @@
package dev.inmo.micro_utils.repos.ktor.client.crud
import dev.inmo.micro_utils.ktor.client.*
import dev.inmo.micro_utils.ktor.common.buildStandardUrl
import dev.inmo.micro_utils.ktor.common.*
import dev.inmo.micro_utils.repos.UpdatedValuePair
import dev.inmo.micro_utils.repos.WriteStandardCRUDRepo
import dev.inmo.micro_utils.repos.ktor.common.crud.*
@ -12,7 +12,7 @@ import kotlinx.serialization.builtins.*
class KtorWriteStandardCrudRepo<ObjectType, IdType, InputValue> (
private val baseUrl: String,
private val client: HttpClient = HttpClient(),
private val unifiedRequester: UnifiedRequester,
private val objectsSerializer: KSerializer<ObjectType>,
private val objectsNullableSerializer: KSerializer<ObjectType?>,
private val inputsSerializer: KSerializer<InputValue>,
@ -27,39 +27,51 @@ class KtorWriteStandardCrudRepo<ObjectType, IdType, InputValue> (
)
private val listInputUpdateSerializer = ListSerializer(inputUpdateSerializer)
override val newObjectsFlow: Flow<ObjectType> = client.createStandardWebsocketFlow(
constructor(
baseUrl: String,
client: HttpClient,
objectsSerializer: KSerializer<ObjectType>,
objectsSerializerNullable: KSerializer<ObjectType?>,
inputsSerializer: KSerializer<InputValue>,
idsSerializer: KSerializer<IdType>,
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat
) : this (
baseUrl, UnifiedRequester(client, serialFormat), objectsSerializer, objectsSerializerNullable, inputsSerializer, idsSerializer
)
override val newObjectsFlow: Flow<ObjectType> = unifiedRequester.createStandardWebsocketFlow(
buildStandardUrl(baseUrl, newObjectsFlowRouting),
deserializer = objectsSerializer
)
override val updatedObjectsFlow: Flow<ObjectType> = client.createStandardWebsocketFlow(
override val updatedObjectsFlow: Flow<ObjectType> = unifiedRequester.createStandardWebsocketFlow(
buildStandardUrl(baseUrl, updatedObjectsFlowRouting),
deserializer = objectsSerializer
)
override val deletedObjectsIdsFlow: Flow<IdType> = client.createStandardWebsocketFlow(
override val deletedObjectsIdsFlow: Flow<IdType> = unifiedRequester.createStandardWebsocketFlow(
buildStandardUrl(baseUrl, deletedObjectsIdsFlowRouting),
deserializer = idsSerializer
)
override suspend fun create(values: List<InputValue>): List<ObjectType> = client.unipost(
override suspend fun create(values: List<InputValue>): List<ObjectType> = unifiedRequester.unipost(
buildStandardUrl(baseUrl, createRouting),
BodyPair(listInputSerializer, values),
listObjectsSerializer
)
override suspend fun update(id: IdType, value: InputValue): ObjectType? = client.unipost(
override suspend fun update(id: IdType, value: InputValue): ObjectType? = unifiedRequester.unipost(
buildStandardUrl(baseUrl, updateRouting),
BodyPair(inputUpdateSerializer, id to value),
objectsNullableSerializer
)
override suspend fun update(values: List<UpdatedValuePair<IdType, InputValue>>): List<ObjectType> = client.unipost(
override suspend fun update(values: List<UpdatedValuePair<IdType, InputValue>>): List<ObjectType> = unifiedRequester.unipost(
buildStandardUrl(baseUrl, updateManyRouting),
BodyPair(listInputUpdateSerializer, values),
listObjectsSerializer
)
override suspend fun deleteById(ids: List<IdType>) = client.unipost(
override suspend fun deleteById(ids: List<IdType>) = unifiedRequester.unipost(
buildStandardUrl(baseUrl, deleteByIdRouting),
BodyPair(listIdsSerializer, ids),
Unit.serializer()

View File

@ -1,80 +1,90 @@
package dev.inmo.micro_utils.repos.ktor.client.key_value
import dev.inmo.micro_utils.ktor.client.encodeUrlQueryValue
import dev.inmo.micro_utils.ktor.client.uniget
import dev.inmo.micro_utils.ktor.common.buildStandardUrl
import dev.inmo.micro_utils.ktor.client.*
import dev.inmo.micro_utils.ktor.common.*
import dev.inmo.micro_utils.pagination.*
import dev.inmo.micro_utils.repos.ReadStandardKeyValueRepo
import dev.inmo.micro_utils.repos.ktor.common.key_value.*
import dev.inmo.micro_utils.repos.ktor.common.valueParameterName
import io.ktor.client.HttpClient
import kotlinx.serialization.KSerializer
import kotlinx.serialization.*
import kotlinx.serialization.builtins.serializer
class KtorReadStandardKeyValueRepo<Key, Value> (
private var baseUrl: String,
private var client: HttpClient = HttpClient(),
private var keySerializer: KSerializer<Key>,
private var valueSerializer: KSerializer<Value>,
private var valueNullableSerializer: KSerializer<Value?>,
private val baseUrl: String,
private val unifiedRequester: UnifiedRequester,
private val keySerializer: KSerializer<Key>,
private val valueSerializer: KSerializer<Value>,
private val valueNullableSerializer: KSerializer<Value?>
) : ReadStandardKeyValueRepo<Key, Value> {
override suspend fun get(k: Key): Value? = client.uniget(
constructor(
baseUrl: String,
client: HttpClient,
keySerializer: KSerializer<Key>,
valueSerializer: KSerializer<Value>,
valueNullableSerializer: KSerializer<Value?>,
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat
) : this (
baseUrl, UnifiedRequester(client, serialFormat), keySerializer, valueSerializer, valueNullableSerializer
)
override suspend fun get(k: Key): Value? = unifiedRequester.uniget(
buildStandardUrl(
baseUrl,
getRoute,
mapOf(
keyParameterName to keySerializer.encodeUrlQueryValue(k)
keyParameterName to unifiedRequester.encodeUrlQueryValue(keySerializer, k)
)
),
valueNullableSerializer
)
override suspend fun values(pagination: Pagination, reversed: Boolean): PaginationResult<Value> = client.uniget(
override suspend fun values(pagination: Pagination, reversed: Boolean): PaginationResult<Value> = unifiedRequester.uniget(
buildStandardUrl(
baseUrl,
valuesRoute,
mapOf(
reversedParameterName to Boolean.serializer().encodeUrlQueryValue(reversed)
reversedParameterName to unifiedRequester.encodeUrlQueryValue(Boolean.serializer(), reversed)
) + pagination.asUrlQueryParts
),
PaginationResult.serializer(valueSerializer)
)
override suspend fun keys(pagination: Pagination, reversed: Boolean): PaginationResult<Key> = client.uniget(
override suspend fun keys(pagination: Pagination, reversed: Boolean): PaginationResult<Key> = unifiedRequester.uniget(
buildStandardUrl(
baseUrl,
keysRoute,
mapOf(
reversedParameterName to Boolean.serializer().encodeUrlQueryValue(reversed)
reversedParameterName to unifiedRequester.encodeUrlQueryValue(Boolean.serializer(), reversed)
) + pagination.asUrlQueryParts
),
PaginationResult.serializer(keySerializer)
)
override suspend fun keys(v: Value, pagination: Pagination, reversed: Boolean): PaginationResult<Key> = client.uniget(
override suspend fun keys(v: Value, pagination: Pagination, reversed: Boolean): PaginationResult<Key> = unifiedRequester.uniget(
buildStandardUrl(
baseUrl,
keysRoute,
mapOf(
valueParameterName to valueSerializer.encodeUrlQueryValue(v),
reversedParameterName to Boolean.serializer().encodeUrlQueryValue(reversed)
valueParameterName to unifiedRequester.encodeUrlQueryValue(valueSerializer, v),
reversedParameterName to unifiedRequester.encodeUrlQueryValue(Boolean.serializer(), reversed)
) + pagination.asUrlQueryParts
),
PaginationResult.serializer(keySerializer)
)
override suspend fun contains(key: Key): Boolean = client.uniget(
override suspend fun contains(key: Key): Boolean = unifiedRequester.uniget(
buildStandardUrl(
baseUrl,
containsRoute,
mapOf(
keyParameterName to keySerializer.encodeUrlQueryValue(key)
keyParameterName to unifiedRequester.encodeUrlQueryValue(keySerializer, key)
),
),
Boolean.serializer(),
)
override suspend fun count(): Long = client.uniget(
override suspend fun count(): Long = unifiedRequester.uniget(
buildStandardUrl(
baseUrl,
countRoute,

View File

@ -1,27 +1,40 @@
package dev.inmo.micro_utils.repos.ktor.client.key_value
import dev.inmo.micro_utils.ktor.client.UnifiedRequester
import dev.inmo.micro_utils.ktor.common.StandardKtorSerialFormat
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
import dev.inmo.micro_utils.repos.*
import io.ktor.client.HttpClient
import kotlinx.serialization.KSerializer
import kotlinx.serialization.*
class KtorStandartKeyValueRepo<K, V> (
baseUrl: String,
baseSubpart: String,
client: HttpClient = HttpClient(),
unifiedRequester: UnifiedRequester,
keySerializer: KSerializer<K>,
valueSerializer: KSerializer<V>,
valueNullableSerializer: KSerializer<V?>
) : StandardKeyValueRepo<K, V>,
ReadStandardKeyValueRepo<K, V> by KtorReadStandardKeyValueRepo(
"$baseUrl/$baseSubpart",
client,
unifiedRequester,
keySerializer,
valueSerializer,
valueNullableSerializer
),
WriteStandardKeyValueRepo<K, V> by KtorWriteStandardKeyValueRepo(
"$baseUrl/$baseSubpart",
client,
unifiedRequester,
keySerializer,
valueSerializer
)
) {
constructor(
baseUrl: String,
baseSubpart: String,
client: HttpClient = HttpClient(),
keySerializer: KSerializer<K>,
valueSerializer: KSerializer<V>,
valueNullableSerializer: KSerializer<V?>,
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat
) : this(baseUrl, baseSubpart, UnifiedRequester(client, serialFormat), keySerializer, valueSerializer, valueNullableSerializer)
}

View File

@ -1,7 +1,7 @@
package dev.inmo.micro_utils.repos.ktor.client.key_value
import dev.inmo.micro_utils.ktor.client.*
import dev.inmo.micro_utils.ktor.common.buildStandardUrl
import dev.inmo.micro_utils.ktor.common.*
import dev.inmo.micro_utils.repos.WriteStandardKeyValueRepo
import dev.inmo.micro_utils.repos.ktor.common.key_value.*
import io.ktor.client.HttpClient
@ -11,23 +11,34 @@ import kotlinx.serialization.builtins.*
class KtorWriteStandardKeyValueRepo<K, V> (
private var baseUrl: String,
private var client: HttpClient = HttpClient(),
private var unifiedRequester: UnifiedRequester,
private var keySerializer: KSerializer<K>,
private var valueSerializer: KSerializer<V>,
) : WriteStandardKeyValueRepo<K, V> {
private val keyValueMapSerializer = MapSerializer(keySerializer, valueSerializer)
private val keysListSerializer = ListSerializer(keySerializer)
override val onNewValue: Flow<Pair<K, V>> = client.createStandardWebsocketFlow(
constructor(
baseUrl: String,
client: HttpClient,
keySerializer: KSerializer<K>,
valueSerializer: KSerializer<V>,
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat
) : this (
baseUrl, UnifiedRequester(client, serialFormat), keySerializer, valueSerializer
)
override val onNewValue: Flow<Pair<K, V>> = unifiedRequester.createStandardWebsocketFlow(
buildStandardUrl(baseUrl, onNewValueRoute),
deserializer = PairSerializer(keySerializer, valueSerializer)
)
override val onValueRemoved: Flow<K> = client.createStandardWebsocketFlow(
override val onValueRemoved: Flow<K> = unifiedRequester.createStandardWebsocketFlow(
buildStandardUrl(baseUrl, onValueRemovedRoute),
deserializer = keySerializer
)
override suspend fun set(toSet: Map<K, V>) = client.unipost(
override suspend fun set(toSet: Map<K, V>) = unifiedRequester.unipost(
buildStandardUrl(
baseUrl,
setRoute
@ -36,7 +47,7 @@ class KtorWriteStandardKeyValueRepo<K, V> (
Unit.serializer()
)
override suspend fun unset(toUnset: List<K>) = client.unipost(
override suspend fun unset(toUnset: List<K>) = unifiedRequester.unipost(
buildStandardUrl(
baseUrl,
unsetRoute,

View File

@ -1,5 +1,8 @@
package dev.inmo.micro_utils.repos.ktor.client.one_to_many
import dev.inmo.micro_utils.ktor.client.UnifiedRequester
import dev.inmo.micro_utils.ktor.common.StandardKtorSerialFormat
import dev.inmo.micro_utils.ktor.common.standardKtorSerialFormat
import dev.inmo.micro_utils.repos.*
import io.ktor.client.HttpClient
import kotlinx.serialization.KSerializer
@ -7,19 +10,28 @@ import kotlinx.serialization.KSerializer
class KtorOneToManyKeyValueRepo<Key, Value>(
baseUrl: String,
baseSubpart: String,
client: HttpClient,
unifiedRequester: UnifiedRequester,
keySerializer: KSerializer<Key>,
valueSerializer: KSerializer<Value>,
) : OneToManyKeyValueRepo<Key, Value>,
ReadOneToManyKeyValueRepo<Key, Value> by KtorReadOneToManyKeyValueRepo<Key, Value> (
"$baseUrl/$baseSubpart",
client,
unifiedRequester,
keySerializer,
valueSerializer,
),
WriteOneToManyKeyValueRepo<Key, Value> by KtorWriteOneToManyKeyValueRepo<Key, Value> (
"$baseUrl/$baseSubpart",
client,
unifiedRequester,
keySerializer,
valueSerializer,
)
) {
constructor(
baseUrl: String,
baseSubpart: String,
client: HttpClient,
keySerializer: KSerializer<Key>,
valueSerializer: KSerializer<Value>,
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat
) : this (baseUrl, baseSubpart, UnifiedRequester(client, serialFormat), keySerializer, valueSerializer)
}

View File

@ -1,8 +1,7 @@
package dev.inmo.micro_utils.repos.ktor.client.one_to_many
import dev.inmo.micro_utils.ktor.client.encodeUrlQueryValue
import dev.inmo.micro_utils.ktor.client.uniget
import dev.inmo.micro_utils.ktor.common.buildStandardUrl
import dev.inmo.micro_utils.ktor.client.*
import dev.inmo.micro_utils.ktor.common.*
import dev.inmo.micro_utils.pagination.*
import dev.inmo.micro_utils.repos.ReadOneToManyKeyValueRepo
import dev.inmo.micro_utils.repos.ktor.common.keyParameterName
@ -15,81 +14,89 @@ import kotlinx.serialization.builtins.serializer
class KtorReadOneToManyKeyValueRepo<Key, Value> (
private val baseUrl: String,
private val client: HttpClient = HttpClient(),
private val unifiedRequester: UnifiedRequester,
private val keySerializer: KSerializer<Key>,
private val valueSerializer: KSerializer<Value>,
private val valueSerializer: KSerializer<Value>
) : ReadOneToManyKeyValueRepo<Key, Value> {
private val paginationValueResultSerializer = PaginationResult.serializer(valueSerializer)
private val paginationKeyResultSerializer = PaginationResult.serializer(keySerializer)
override suspend fun get(k: Key, pagination: Pagination, reversed: Boolean): PaginationResult<Value> = client.uniget(
constructor(
baseUrl: String,
client: HttpClient,
keySerializer: KSerializer<Key>,
valueSerializer: KSerializer<Value>,
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat
) : this (baseUrl, UnifiedRequester(client, serialFormat), keySerializer, valueSerializer)
override suspend fun get(k: Key, pagination: Pagination, reversed: Boolean): PaginationResult<Value> = unifiedRequester.uniget(
buildStandardUrl(
baseUrl,
getRoute,
mapOf(
keyParameterName to keySerializer.encodeUrlQueryValue(k),
reversedParameterName to Boolean.serializer().encodeUrlQueryValue(reversed)
keyParameterName to unifiedRequester.encodeUrlQueryValue(keySerializer, k),
reversedParameterName to unifiedRequester.encodeUrlQueryValue(Boolean.serializer(), reversed)
) + pagination.asUrlQueryParts
),
paginationValueResultSerializer
)
override suspend fun keys(pagination: Pagination, reversed: Boolean): PaginationResult<Key> = client.uniget(
override suspend fun keys(pagination: Pagination, reversed: Boolean): PaginationResult<Key> = unifiedRequester.uniget(
buildStandardUrl(
baseUrl,
keysRoute,
mapOf(
reversedParameterName to Boolean.serializer().encodeUrlQueryValue(reversed)
reversedParameterName to unifiedRequester.encodeUrlQueryValue(Boolean.serializer(), reversed)
) + pagination.asUrlQueryParts
),
paginationKeyResultSerializer
)
override suspend fun keys(v: Value, pagination: Pagination, reversed: Boolean): PaginationResult<Key> = client.uniget(
override suspend fun keys(v: Value, pagination: Pagination, reversed: Boolean): PaginationResult<Key> = unifiedRequester.uniget(
buildStandardUrl(
baseUrl,
keysRoute,
mapOf(
valueParameterName to valueSerializer.encodeUrlQueryValue(v),
reversedParameterName to Boolean.serializer().encodeUrlQueryValue(reversed)
valueParameterName to unifiedRequester.encodeUrlQueryValue(valueSerializer, v),
reversedParameterName to unifiedRequester.encodeUrlQueryValue(Boolean.serializer(), reversed)
) + pagination.asUrlQueryParts
),
paginationKeyResultSerializer
)
override suspend fun contains(k: Key): Boolean = client.uniget(
override suspend fun contains(k: Key): Boolean = unifiedRequester.uniget(
buildStandardUrl(
baseUrl,
containsByKeyRoute,
mapOf(keyParameterName to keySerializer.encodeUrlQueryValue(k))
mapOf(keyParameterName to unifiedRequester.encodeUrlQueryValue(keySerializer, k))
),
Boolean.serializer()
)
override suspend fun contains(k: Key, v: Value): Boolean = client.uniget(
override suspend fun contains(k: Key, v: Value): Boolean = unifiedRequester.uniget(
buildStandardUrl(
baseUrl,
containsByKeyValueRoute,
mapOf(
keyParameterName to keySerializer.encodeUrlQueryValue(k),
valueParameterName to valueSerializer.encodeUrlQueryValue(v),
keyParameterName to unifiedRequester.encodeUrlQueryValue(keySerializer, k),
valueParameterName to unifiedRequester.encodeUrlQueryValue(valueSerializer, v),
)
),
Boolean.serializer()
)
override suspend fun count(k: Key): Long = client.uniget(
override suspend fun count(k: Key): Long = unifiedRequester.uniget(
buildStandardUrl(
baseUrl,
countByKeyRoute,
mapOf(
keyParameterName to keySerializer.encodeUrlQueryValue(k)
keyParameterName to unifiedRequester.encodeUrlQueryValue(keySerializer, k)
)
),
Long.serializer()
)
override suspend fun count(): Long = client.uniget(
override suspend fun count(): Long = unifiedRequester.uniget(
buildStandardUrl(
baseUrl,
countRoute,

View File

@ -1,7 +1,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.common.buildStandardUrl
import dev.inmo.micro_utils.ktor.common.*
import dev.inmo.micro_utils.repos.WriteOneToManyKeyValueRepo
import dev.inmo.micro_utils.repos.ktor.common.one_to_many.*
import io.ktor.client.HttpClient
@ -11,26 +11,37 @@ import kotlinx.serialization.builtins.*
class KtorWriteOneToManyKeyValueRepo<Key, Value> (
private val baseUrl: String,
private val client: HttpClient = HttpClient(),
private val unifiedRequester: UnifiedRequester,
private val keySerializer: KSerializer<Key>,
private val valueSerializer: KSerializer<Value>
) : WriteOneToManyKeyValueRepo<Key, Value> {
private val keyValueSerializer = PairSerializer(keySerializer, valueSerializer)
private val keyValueMapSerializer = MapSerializer(keySerializer, ListSerializer(valueSerializer))
override val onNewValue: Flow<Pair<Key, Value>> = client.createStandardWebsocketFlow(
constructor(
baseUrl: String,
client: HttpClient,
keySerializer: KSerializer<Key>,
valueSerializer: KSerializer<Value>,
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat
) : this (
baseUrl, UnifiedRequester(client, serialFormat), keySerializer, valueSerializer
)
override val onNewValue: Flow<Pair<Key, Value>> = unifiedRequester.createStandardWebsocketFlow(
buildStandardUrl(baseUrl, onNewValueRoute),
deserializer = keyValueSerializer
)
override val onValueRemoved: Flow<Pair<Key, Value>> = client.createStandardWebsocketFlow(
override val onValueRemoved: Flow<Pair<Key, Value>> = unifiedRequester.createStandardWebsocketFlow(
buildStandardUrl(baseUrl, onValueRemovedRoute),
deserializer = keyValueSerializer
)
override val onDataCleared: Flow<Key> = client.createStandardWebsocketFlow(
override val onDataCleared: Flow<Key> = unifiedRequester.createStandardWebsocketFlow(
buildStandardUrl(baseUrl, onDataClearedRoute),
deserializer = keySerializer
)
override suspend fun remove(toRemove: Map<Key, List<Value>>) = client.unipost(
override suspend fun remove(toRemove: Map<Key, List<Value>>) = unifiedRequester.unipost(
buildStandardUrl(
baseUrl,
removeRoute,
@ -39,7 +50,7 @@ class KtorWriteOneToManyKeyValueRepo<Key, Value> (
Unit.serializer(),
)
override suspend fun add(toAdd: Map<Key, List<Value>>) = client.unipost(
override suspend fun add(toAdd: Map<Key, List<Value>>) = unifiedRequester.unipost(
buildStandardUrl(
baseUrl,
addRoute,
@ -47,7 +58,7 @@ class KtorWriteOneToManyKeyValueRepo<Key, Value> (
BodyPair(keyValueMapSerializer, toAdd),
Unit.serializer(),
)
override suspend fun clear(k: Key) = client.unipost(
override suspend fun clear(k: Key) = unifiedRequester.unipost(
buildStandardUrl(
baseUrl,
clearRoute,
@ -56,7 +67,7 @@ class KtorWriteOneToManyKeyValueRepo<Key, Value> (
Unit.serializer(),
)
override suspend fun set(toSet: Map<Key, List<Value>>) = client.unipost(
override suspend fun set(toSet: Map<Key, List<Value>>) = unifiedRequester.unipost(
buildStandardUrl(
baseUrl,
setRoute,

View File

@ -1,12 +1,14 @@
package dev.inmo.micro_utils.repos.ktor.server.crud
import dev.inmo.micro_utils.ktor.server.decodeUrlQueryValueOrSendError
import dev.inmo.micro_utils.ktor.server.unianswer
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.pagination.PaginationResult
import dev.inmo.micro_utils.pagination.extractPagination
import dev.inmo.micro_utils.repos.ReadStandardCRUDRepo
import dev.inmo.micro_utils.repos.ktor.common.crud.*
import io.ktor.application.call
import io.ktor.http.ContentType
import io.ktor.routing.Route
import io.ktor.routing.get
import kotlinx.serialization.KSerializer
@ -16,47 +18,65 @@ fun <ObjectType, IdType> Route.configureReadStandardCrudRepoRoutes(
originalRepo: ReadStandardCRUDRepo<ObjectType, IdType>,
objectsSerializer: KSerializer<ObjectType>,
objectsNullableSerializer: KSerializer<ObjectType?>,
idsSerializer: KSerializer<IdType>
idsSerializer: KSerializer<IdType>,
unifiedRouter: UnifiedRouter
) {
val paginationResultSerializer = PaginationResult.serializer(objectsSerializer)
get(getByPaginationRouting) {
val pagination = call.request.queryParameters.extractPagination
unifiedRouter.apply {
val pagination = call.request.queryParameters.extractPagination
call.unianswer(
paginationResultSerializer,
originalRepo.getByPagination(pagination)
)
unianswer(
paginationResultSerializer,
originalRepo.getByPagination(pagination)
)
}
}
get(getByIdRouting) {
val id = call.decodeUrlQueryValueOrSendError(
"id",
idsSerializer
) ?: return@get
unifiedRouter.apply {
val id = decodeUrlQueryValueOrSendError(
"id",
idsSerializer
) ?: return@get
call.unianswer(
objectsNullableSerializer,
originalRepo.getById(id)
)
unianswer(
objectsNullableSerializer,
originalRepo.getById(id)
)
}
}
get(containsRouting) {
val id = call.decodeUrlQueryValueOrSendError(
"id",
idsSerializer
) ?: return@get
unifiedRouter.apply {
val id = decodeUrlQueryValueOrSendError(
"id",
idsSerializer
) ?: return@get
call.unianswer(
Boolean.serializer(),
originalRepo.contains(id)
)
unianswer(
Boolean.serializer(),
originalRepo.contains(id)
)
}
}
get(countRouting) {
call.unianswer(
Long.serializer(),
originalRepo.count()
)
unifiedRouter.apply {
unianswer(
Long.serializer(),
originalRepo.count()
)
}
}
}
inline fun <ObjectType, IdType> Route.configureReadStandardCrudRepoRoutes(
originalRepo: ReadStandardCRUDRepo<ObjectType, IdType>,
objectsSerializer: KSerializer<ObjectType>,
objectsNullableSerializer: KSerializer<ObjectType?>,
idsSerializer: KSerializer<IdType>,
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
serialFormatContentType: ContentType = standardKtorSerialFormatContentType
) = configureReadStandardCrudRepoRoutes(originalRepo, objectsSerializer, objectsNullableSerializer, idsSerializer, UnifiedRouter(serialFormat, serialFormatContentType))

View File

@ -1,6 +1,11 @@
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.server.UnifiedRouter
import dev.inmo.micro_utils.ktor.server.standardKtorSerialFormatContentType
import dev.inmo.micro_utils.repos.StandardCRUDRepo
import io.ktor.http.ContentType
import io.ktor.routing.Route
import io.ktor.routing.route
import kotlinx.serialization.KSerializer
@ -11,10 +16,24 @@ fun <ObjectType, IdType, InputValue> Route.configureStandardCrudRepoRoutes(
objectsSerializer: KSerializer<ObjectType>,
objectsNullableSerializer: KSerializer<ObjectType?>,
inputsSerializer: KSerializer<InputValue>,
idsSerializer: KSerializer<IdType>
idsSerializer: KSerializer<IdType>,
unifiedRouter: UnifiedRouter
) {
route(baseSubpart) {
configureReadStandardCrudRepoRoutes(originalRepo, objectsSerializer, objectsNullableSerializer, idsSerializer)
configureWriteStandardCrudRepoRoutes(originalRepo, objectsSerializer, objectsNullableSerializer, inputsSerializer, idsSerializer)
configureReadStandardCrudRepoRoutes(originalRepo, objectsSerializer, objectsNullableSerializer, idsSerializer, unifiedRouter)
configureWriteStandardCrudRepoRoutes(originalRepo, objectsSerializer, objectsNullableSerializer, inputsSerializer, idsSerializer, unifiedRouter)
}
}
fun <ObjectType, IdType, InputValue> Route.configureStandardCrudRepoRoutes(
baseSubpart: String,
originalRepo: StandardCRUDRepo<ObjectType, IdType, InputValue>,
objectsSerializer: KSerializer<ObjectType>,
objectsNullableSerializer: KSerializer<ObjectType?>,
inputsSerializer: KSerializer<InputValue>,
idsSerializer: KSerializer<IdType>,
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
serialFormatContentType: ContentType = standardKtorSerialFormatContentType
) = configureStandardCrudRepoRoutes(
baseSubpart, originalRepo, objectsSerializer, objectsNullableSerializer, inputsSerializer, idsSerializer, UnifiedRouter(serialFormat, serialFormatContentType)
)

View File

@ -1,9 +1,12 @@
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.server.*
import dev.inmo.micro_utils.repos.WriteStandardCRUDRepo
import dev.inmo.micro_utils.repos.ktor.common.crud.*
import io.ktor.application.call
import io.ktor.http.ContentType
import io.ktor.routing.Route
import io.ktor.routing.post
import kotlinx.serialization.KSerializer
@ -14,7 +17,8 @@ fun <ObjectType, IdType, InputValue> Route.configureWriteStandardCrudRepoRoutes(
objectsSerializer: KSerializer<ObjectType>,
objectsNullableSerializer: KSerializer<ObjectType?>,
inputsSerializer: KSerializer<InputValue>,
idsSerializer: KSerializer<IdType>
idsSerializer: KSerializer<IdType>,
unifiedRouter: UnifiedRouter
) {
val listObjectsSerializer = ListSerializer(objectsSerializer)
val listInputSerializer = ListSerializer(inputsSerializer)
@ -25,58 +29,80 @@ fun <ObjectType, IdType, InputValue> Route.configureWriteStandardCrudRepoRoutes(
)
val listInputUpdateSerializer = ListSerializer(inputUpdateSerializer)
includeWebsocketHandling(
newObjectsFlowRouting,
originalRepo.newObjectsFlow,
objectsSerializer
)
includeWebsocketHandling(
updatedObjectsFlowRouting,
originalRepo.updatedObjectsFlow,
objectsSerializer
)
includeWebsocketHandling(
deletedObjectsIdsFlowRouting,
originalRepo.deletedObjectsIdsFlow,
idsSerializer
)
unifiedRouter.apply {
includeWebsocketHandling(
newObjectsFlowRouting,
originalRepo.newObjectsFlow,
objectsSerializer
)
includeWebsocketHandling(
updatedObjectsFlowRouting,
originalRepo.updatedObjectsFlow,
objectsSerializer
)
includeWebsocketHandling(
deletedObjectsIdsFlowRouting,
originalRepo.deletedObjectsIdsFlow,
idsSerializer
)
}
post(createRouting) {
call.unianswer(
listObjectsSerializer,
originalRepo.create(
call.uniload(listInputSerializer)
unifiedRouter.apply {
unianswer(
listObjectsSerializer,
originalRepo.create(
uniload(listInputSerializer)
)
)
)
}
}
post(updateRouting) {
val (id, input) = call.uniload(inputUpdateSerializer)
call.unianswer(
objectsNullableSerializer,
originalRepo.update(
id, input
unifiedRouter.apply {
val (id, input) = uniload(inputUpdateSerializer)
unianswer(
objectsNullableSerializer,
originalRepo.update(
id, input
)
)
)
}
}
post(updateManyRouting) {
val updates = call.uniload(listInputUpdateSerializer)
call.unianswer(
listObjectsSerializer,
originalRepo.update(
updates
unifiedRouter.apply {
val updates = uniload(listInputUpdateSerializer)
unianswer(
listObjectsSerializer,
originalRepo.update(
updates
)
)
)
}
}
post(deleteByIdRouting) {
val ids = call.uniload(listIdsSerializer)
call.unianswer(
Unit.serializer(),
originalRepo.deleteById(
ids
unifiedRouter.apply {
val ids = uniload(listIdsSerializer)
unianswer(
Unit.serializer(),
originalRepo.deleteById(
ids
)
)
)
}
}
}
fun <ObjectType, IdType, InputValue> Route.configureWriteStandardCrudRepoRoutes(
originalRepo: WriteStandardCRUDRepo<ObjectType, IdType, InputValue>,
objectsSerializer: KSerializer<ObjectType>,
objectsNullableSerializer: KSerializer<ObjectType?>,
inputsSerializer: KSerializer<InputValue>,
idsSerializer: KSerializer<IdType>,
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
serialFormatContentType: ContentType = standardKtorSerialFormatContentType
) = configureWriteStandardCrudRepoRoutes(
originalRepo, objectsSerializer, objectsNullableSerializer, inputsSerializer, idsSerializer, UnifiedRouter(serialFormat, serialFormatContentType)
)

View File

@ -1,16 +1,22 @@
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.server.UnifiedRouter
import dev.inmo.micro_utils.ktor.server.standardKtorSerialFormatContentType
import dev.inmo.micro_utils.repos.StandardKeyValueRepo
import io.ktor.http.ContentType
import io.ktor.routing.Route
import io.ktor.routing.route
import kotlinx.serialization.KSerializer
fun <K, V> Route.configureStandartKeyValueRepoRoutes(
fun <K, V> Route.configureStandardKeyValueRepoRoutes(
baseSubpart: String,
originalRepo: StandardKeyValueRepo<K, V>,
keySerializer: KSerializer<K>,
valueSerializer: KSerializer<V>,
valueNullableSerializer: KSerializer<V?>,
unifiedRouter: UnifiedRouter
) {
route(baseSubpart) {
configureReadStandartKeyValueRepoRoutes(
@ -18,11 +24,23 @@ fun <K, V> Route.configureStandartKeyValueRepoRoutes(
keySerializer,
valueSerializer,
valueNullableSerializer,
unifiedRouter
)
configureWriteStandartKeyValueRepoRoutes(
configureWriteStandardKeyValueRepoRoutes(
originalRepo,
keySerializer,
valueSerializer,
unifiedRouter
)
}
}
}
fun <K, V> Route.configureStandartKeyValueRepoRoutes(
baseSubpart: String,
originalRepo: StandardKeyValueRepo<K, V>,
keySerializer: KSerializer<K>,
valueSerializer: KSerializer<V>,
valueNullableSerializer: KSerializer<V?>,
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
serialFormatContentType: ContentType = standardKtorSerialFormatContentType
) = configureStandardKeyValueRepoRoutes(baseSubpart, originalRepo, keySerializer, valueSerializer, valueNullableSerializer, UnifiedRouter(serialFormat, serialFormatContentType))

View File

@ -1,5 +1,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.server.*
import dev.inmo.micro_utils.pagination.PaginationResult
import dev.inmo.micro_utils.pagination.extractPagination
@ -7,6 +9,7 @@ import dev.inmo.micro_utils.repos.ReadStandardKeyValueRepo
import dev.inmo.micro_utils.repos.ktor.common.key_value.*
import dev.inmo.micro_utils.repos.ktor.common.valueParameterName
import io.ktor.application.call
import io.ktor.http.ContentType
import io.ktor.routing.Route
import io.ktor.routing.get
import kotlinx.serialization.KSerializer
@ -17,62 +20,84 @@ fun <K, V> Route.configureReadStandartKeyValueRepoRoutes (
keySerializer: KSerializer<K>,
valueSerializer: KSerializer<V>,
valueNullableSerializer: KSerializer<V?>,
unifiedRouter: UnifiedRouter
) {
get(getRoute) {
val key = call.decodeUrlQueryValueOrSendError(
keyParameterName,
keySerializer
) ?: return@get
unifiedRouter.apply {
val key = decodeUrlQueryValueOrSendError(
keyParameterName,
keySerializer
) ?: return@get
call.unianswer(
valueNullableSerializer,
originalRepo.get(key)
)
unianswer(
valueNullableSerializer,
originalRepo.get(key)
)
}
}
get(valuesRoute) {
val parination = call.request.queryParameters.extractPagination;
val reversed = call.decodeUrlQueryValueOrSendError(
reversedParameterName,
Boolean.serializer()
) ?: return@get
unifiedRouter.apply {
val parination = call.request.queryParameters.extractPagination;
val reversed = decodeUrlQueryValueOrSendError(
reversedParameterName,
Boolean.serializer()
) ?: return@get
call.unianswer(
PaginationResult.serializer(valueSerializer),
originalRepo.values(parination, reversed)
)
unianswer(
PaginationResult.serializer(valueSerializer),
originalRepo.values(parination, reversed)
)
}
}
get(keysRoute) {
val parination = call.request.queryParameters.extractPagination;
val reversed = call.decodeUrlQueryValueOrSendError(
reversedParameterName,
Boolean.serializer()
) ?: return@get
val value = call.decodeUrlQueryValue(valueParameterName, valueSerializer)
unifiedRouter.apply {
val parination = call.request.queryParameters.extractPagination;
val reversed = decodeUrlQueryValueOrSendError(
reversedParameterName,
Boolean.serializer()
) ?: return@get
val value = decodeUrlQueryValue(valueParameterName, valueSerializer)
call.unianswer(
PaginationResult.serializer(keySerializer),
value ?.let { originalRepo.keys(value, parination, reversed) } ?: originalRepo.keys(parination, reversed)
)
unianswer(
PaginationResult.serializer(keySerializer),
value?.let { originalRepo.keys(value, parination, reversed) } ?: originalRepo.keys(parination, reversed)
)
}
}
get(containsRoute) {
val key = call.decodeUrlQueryValueOrSendError(
keyParameterName,
keySerializer
) ?: return@get
unifiedRouter.apply {
val key = decodeUrlQueryValueOrSendError(
keyParameterName,
keySerializer
) ?: return@get
call.unianswer(
Boolean.serializer(),
originalRepo.contains(key)
)
unianswer(
Boolean.serializer(),
originalRepo.contains(key)
)
}
}
get(countRoute) {
call.unianswer(
Long.serializer(),
originalRepo.count()
)
unifiedRouter.apply {
unianswer(
Long.serializer(),
originalRepo.count()
)
}
}
}
}
inline fun <K, V> Route.configureReadStandartKeyValueRepoRoutes (
originalRepo: ReadStandardKeyValueRepo<K, V>,
keySerializer: KSerializer<K>,
valueSerializer: KSerializer<V>,
valueNullableSerializer: KSerializer<V?>,
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
serialFormatContentType: ContentType = standardKtorSerialFormatContentType
) = configureReadStandartKeyValueRepoRoutes(
originalRepo, keySerializer, valueSerializer, valueNullableSerializer, UnifiedRouter(serialFormat, serialFormatContentType)
)

View File

@ -1,44 +1,61 @@
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.server.*
import dev.inmo.micro_utils.repos.WriteStandardKeyValueRepo
import dev.inmo.micro_utils.repos.ktor.common.key_value.*
import io.ktor.application.call
import io.ktor.http.ContentType
import io.ktor.routing.Route
import io.ktor.routing.post
import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.*
fun <K, V> Route.configureWriteStandardKeyValueRepoRoutes (
originalRepo: WriteStandardKeyValueRepo<K, V>,
keySerializer: KSerializer<K>,
valueSerializer: KSerializer<V>,
unifiedRouter: UnifiedRouter
) {
val keyValueMapSerializer = MapSerializer(keySerializer, valueSerializer)
val keysListSerializer = ListSerializer(keySerializer)
unifiedRouter.apply {
includeWebsocketHandling(
onNewValueRoute,
originalRepo.onNewValue,
PairSerializer(keySerializer, valueSerializer)
)
includeWebsocketHandling(
onValueRemovedRoute,
originalRepo.onValueRemoved,
keySerializer
)
}
post(setRoute) {
unifiedRouter.apply {
val toSet = uniload(
keyValueMapSerializer
)
unianswer(Unit.serializer(), originalRepo.set(toSet))
}
}
post(unsetRoute) {
unifiedRouter.apply {
val toUnset = uniload(keysListSerializer)
unianswer(Unit.serializer(), originalRepo.unset(toUnset))
}
}
}
fun <K, V> Route.configureWriteStandartKeyValueRepoRoutes (
originalRepo: WriteStandardKeyValueRepo<K, V>,
keySerializer: KSerializer<K>,
valueSerializer: KSerializer<V>,
) {
val keyValueMapSerializer = MapSerializer(keySerializer, valueSerializer)
val keysListSerializer = ListSerializer(keySerializer)
includeWebsocketHandling(
onNewValueRoute,
originalRepo.onNewValue,
PairSerializer(keySerializer, valueSerializer)
)
includeWebsocketHandling(
onValueRemovedRoute,
originalRepo.onValueRemoved,
keySerializer
)
post(setRoute) {
val toSet = call.uniload(
keyValueMapSerializer
)
call.unianswer(Unit.serializer(), originalRepo.set(toSet))
}
post(unsetRoute) {
val toUnset = call.uniload(keysListSerializer)
call.unianswer(Unit.serializer(), originalRepo.unset(toUnset))
}
}
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
serialFormatContentType: ContentType = standardKtorSerialFormatContentType
) = configureWriteStandardKeyValueRepoRoutes(originalRepo, keySerializer, valueSerializer, UnifiedRouter(serialFormat, serialFormatContentType))

View File

@ -1,6 +1,11 @@
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.server.UnifiedRouter
import dev.inmo.micro_utils.ktor.server.standardKtorSerialFormatContentType
import dev.inmo.micro_utils.repos.OneToManyKeyValueRepo
import io.ktor.http.ContentType
import io.ktor.routing.Route
import io.ktor.routing.route
import kotlinx.serialization.KSerializer
@ -9,10 +14,22 @@ fun <Key, Value> Route.configureOneToManyKeyValueRepoRoutes(
baseSubpart: String,
originalRepo: OneToManyKeyValueRepo<Key, Value>,
keySerializer: KSerializer<Key>,
valueSealizer: KSerializer<Value>,
valueSerializer: KSerializer<Value>,
unifiedRouter: UnifiedRouter
) {
route(baseSubpart) {
configureOneToManyReadKeyValueRepoRoutes(originalRepo, keySerializer, valueSealizer)
configureOneToManyWriteKeyValueRepoRoutes(originalRepo, keySerializer, valueSealizer)
configureOneToManyReadKeyValueRepoRoutes(originalRepo, keySerializer, valueSerializer, unifiedRouter)
configureOneToManyWriteKeyValueRepoRoutes(originalRepo, keySerializer, valueSerializer, unifiedRouter)
}
}
}
fun <Key, Value> Route.configureOneToManyKeyValueRepoRoutes(
baseSubpart: String,
originalRepo: OneToManyKeyValueRepo<Key, Value>,
keySerializer: KSerializer<Key>,
valueSerializer: KSerializer<Value>,
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
serialFormatContentType: ContentType = standardKtorSerialFormatContentType
) = configureOneToManyKeyValueRepoRoutes(
baseSubpart, originalRepo, keySerializer, valueSerializer, UnifiedRouter(serialFormat, serialFormatContentType)
)

View File

@ -1,5 +1,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.server.*
import dev.inmo.micro_utils.pagination.PaginationResult
import dev.inmo.micro_utils.pagination.extractPagination
@ -10,6 +12,7 @@ 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.reversedParameterName
import io.ktor.application.call
import io.ktor.http.ContentType
import io.ktor.routing.Route
import io.ktor.routing.get
import kotlinx.serialization.KSerializer
@ -18,89 +21,110 @@ import kotlinx.serialization.builtins.serializer
fun <Key, Value> Route.configureOneToManyReadKeyValueRepoRoutes(
originalRepo: ReadOneToManyKeyValueRepo<Key, Value>,
keySerializer: KSerializer<Key>,
valueSealizer: KSerializer<Value>,
valueSerializer: KSerializer<Value>,
unifiedRouter: UnifiedRouter
) {
val paginationKeyResult = PaginationResult.serializer(keySerializer)
val paginationValueResult = PaginationResult.serializer(valueSealizer)
val paginationValueResult = PaginationResult.serializer(valueSerializer)
get(getRoute) {
val pagination = call.request.queryParameters.extractPagination
val key = call.decodeUrlQueryValueOrSendError(
keyParameterName,
keySerializer
) ?: return@get
val reversed = call.decodeUrlQueryValue(
reversedParameterName,
Boolean.serializer()
) ?: false
unifiedRouter.apply {
val pagination = call.request.queryParameters.extractPagination
val key = decodeUrlQueryValueOrSendError(
keyParameterName,
keySerializer
) ?: return@get
val reversed = decodeUrlQueryValue(
reversedParameterName,
Boolean.serializer()
) ?: false
call.unianswer(
paginationValueResult,
originalRepo.get(key, pagination, reversed)
)
unianswer(
paginationValueResult,
originalRepo.get(key, pagination, reversed)
)
}
}
get(keysRoute) {
val pagination = call.request.queryParameters.extractPagination
val reversed = call.decodeUrlQueryValue(
reversedParameterName,
Boolean.serializer()
) ?: false
val value: Value? = call.decodeUrlQueryValue(
valueParameterName,
valueSealizer
)
unifiedRouter.apply {
val pagination = call.request.queryParameters.extractPagination
val reversed = decodeUrlQueryValue(
reversedParameterName,
Boolean.serializer()
) ?: false
val value: Value? = decodeUrlQueryValue(
valueParameterName,
valueSerializer
)
call.unianswer(
paginationKeyResult,
value ?.let { originalRepo.keys(value, pagination, reversed) } ?: originalRepo.keys(pagination, reversed)
)
unianswer(
paginationKeyResult,
value?.let { originalRepo.keys(value, pagination, reversed) } ?: originalRepo.keys(pagination, reversed)
)
}
}
get(containsByKeyRoute) {
val key = call.decodeUrlQueryValueOrSendError(
keyParameterName,
keySerializer
) ?: return@get
unifiedRouter.apply {
val key = decodeUrlQueryValueOrSendError(
keyParameterName,
keySerializer
) ?: return@get
call.unianswer(
Boolean.serializer(),
originalRepo.contains(key)
)
unianswer(
Boolean.serializer(),
originalRepo.contains(key)
)
}
}
get(containsByKeyValueRoute) {
val key = call.decodeUrlQueryValueOrSendError(
keyParameterName,
keySerializer
) ?: return@get
val value = call.decodeUrlQueryValueOrSendError(
valueParameterName,
valueSealizer
) ?: return@get
unifiedRouter.apply {
val key = decodeUrlQueryValueOrSendError(
keyParameterName,
keySerializer
) ?: return@get
val value = decodeUrlQueryValueOrSendError(
valueParameterName,
valueSerializer
) ?: return@get
call.unianswer(
Boolean.serializer(),
originalRepo.contains(key, value)
)
unianswer(
Boolean.serializer(),
originalRepo.contains(key, value)
)
}
}
get(countByKeyRoute) {
val key = call.decodeUrlQueryValueOrSendError(
keyParameterName,
keySerializer
) ?: return@get
unifiedRouter.apply {
val key = decodeUrlQueryValueOrSendError(
keyParameterName,
keySerializer
) ?: return@get
call.unianswer(
Long.serializer(),
originalRepo.count(key)
)
unianswer(
Long.serializer(),
originalRepo.count(key)
)
}
}
get(countRoute) {
call.unianswer(
Long.serializer(),
originalRepo.count()
)
unifiedRouter.apply {
unianswer(
Long.serializer(),
originalRepo.count()
)
}
}
}
}
inline fun <Key, Value> Route.configureOneToManyReadKeyValueRepoRoutes(
originalRepo: ReadOneToManyKeyValueRepo<Key, Value>,
keySerializer: KSerializer<Key>,
valueSerializer: KSerializer<Value>,
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
serialFormatContentType: ContentType = standardKtorSerialFormatContentType
) = configureOneToManyReadKeyValueRepoRoutes(originalRepo, keySerializer, valueSerializer, UnifiedRouter(serialFormat, serialFormatContentType))

View File

@ -1,9 +1,12 @@
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.server.*
import dev.inmo.micro_utils.repos.WriteOneToManyKeyValueRepo
import dev.inmo.micro_utils.repos.ktor.common.one_to_many.*
import io.ktor.application.call
import io.ktor.http.ContentType
import io.ktor.routing.Route
import io.ktor.routing.post
import kotlinx.serialization.KSerializer
@ -13,61 +16,78 @@ fun <Key, Value> Route.configureOneToManyWriteKeyValueRepoRoutes(
originalRepo: WriteOneToManyKeyValueRepo<Key, Value>,
keySerializer: KSerializer<Key>,
valueSerializer: KSerializer<Value>,
unifiedRouter: UnifiedRouter
) {
val keyValueSerializer = PairSerializer(keySerializer, valueSerializer)
val keyValueMapSerializer = MapSerializer(keySerializer, ListSerializer(valueSerializer))
includeWebsocketHandling(
onNewValueRoute,
originalRepo.onNewValue,
keyValueSerializer
)
includeWebsocketHandling(
onValueRemovedRoute,
originalRepo.onValueRemoved,
keyValueSerializer
)
includeWebsocketHandling(
onDataClearedRoute,
originalRepo.onDataCleared,
keySerializer
)
unifiedRouter.apply {
includeWebsocketHandling(
onNewValueRoute,
originalRepo.onNewValue,
keyValueSerializer
)
includeWebsocketHandling(
onValueRemovedRoute,
originalRepo.onValueRemoved,
keyValueSerializer
)
includeWebsocketHandling(
onDataClearedRoute,
originalRepo.onDataCleared,
keySerializer
)
}
post(addRoute) {
val obj = call.uniload(keyValueMapSerializer)
unifiedRouter.apply {
val obj = uniload(keyValueMapSerializer)
call.unianswer(
Unit.serializer(),
originalRepo.add(obj)
)
unianswer(
Unit.serializer(),
originalRepo.add(obj)
)
}
}
post(removeRoute) {
val obj = call.uniload(
keyValueMapSerializer
)
unifiedRouter.apply {
val obj = uniload(keyValueMapSerializer)
call.unianswer(
Unit.serializer(),
originalRepo.remove(obj),
)
unianswer(
Unit.serializer(),
originalRepo.remove(obj),
)
}
}
post(clearRoute) {
val key = call.uniload(keySerializer)
unifiedRouter.apply {
val key = uniload(keySerializer)
call.unianswer(
Unit.serializer(),
originalRepo.clear(key),
)
unianswer(
Unit.serializer(),
originalRepo.clear(key),
)
}
}
post(setRoute) {
val obj = call.uniload(keyValueMapSerializer)
unifiedRouter.apply {
val obj = uniload(keyValueMapSerializer)
call.unianswer(
Unit.serializer(),
originalRepo.set(obj)
)
unianswer(
Unit.serializer(),
originalRepo.set(obj)
)
}
}
}
}
fun <Key, Value> Route.configureOneToManyWriteKeyValueRepoRoutes(
originalRepo: WriteOneToManyKeyValueRepo<Key, Value>,
keySerializer: KSerializer<Key>,
valueSerializer: KSerializer<Value>,
serialFormat: StandardKtorSerialFormat = standardKtorSerialFormat,
serialFormatContentType: ContentType = standardKtorSerialFormatContentType
) = configureOneToManyWriteKeyValueRepoRoutes(originalRepo, keySerializer, valueSerializer, UnifiedRouter(serialFormat, serialFormatContentType))