mirror of
https://github.com/InsanusMokrassar/MicroUtils.git
synced 2024-12-22 16:47:15 +00:00
add repos ktor and exposed
This commit is contained in:
parent
dc9529310c
commit
b84367f47c
16
repos/exposed/build.gradle
Normal file
16
repos/exposed/build.gradle
Normal file
@ -0,0 +1,16 @@
|
||||
plugins {
|
||||
id "org.jetbrains.kotlin.multiplatform"
|
||||
id "org.jetbrains.kotlin.plugin.serialization"
|
||||
}
|
||||
|
||||
apply from: "$mppJavaProjectPresetPath"
|
||||
|
||||
kotlin {
|
||||
sourceSets {
|
||||
commonMain {
|
||||
dependencies {
|
||||
api internalProject("micro_utils.repos.common")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package dev.inmo.micro_utils.repos.exposed
|
||||
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
|
||||
abstract class AbstractExposedCRUDRepo<ObjectType, IdType, InputValueType>(
|
||||
flowsChannelsSize: Int = Channel.BUFFERED,
|
||||
databaseName: String = ""
|
||||
) :
|
||||
AbstractExposedWriteCRUDRepo<ObjectType, IdType, InputValueType>(
|
||||
flowsChannelsSize,
|
||||
databaseName
|
||||
),
|
||||
ExposedCRUDRepo<ObjectType, IdType>
|
@ -0,0 +1,37 @@
|
||||
package dev.inmo.micro_utils.repos.exposed
|
||||
|
||||
import com.insanusmokrassar.postssystem.exposed.commons.paginate
|
||||
import com.insanusmokrassar.postssystem.utils.common.pagination.*
|
||||
import com.insanusmokrassar.postssystem.utils.repos.ReadStandardCRUDRepo
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
|
||||
abstract class AbstractExposedReadCRUDRepo<ObjectType, IdType>(
|
||||
tableName: String
|
||||
) :
|
||||
ReadStandardCRUDRepo<ObjectType, IdType>,
|
||||
ExposedCRUDRepo<ObjectType, IdType>,
|
||||
Table(tableName)
|
||||
{
|
||||
override suspend fun getByPagination(pagination: Pagination): PaginationResult<ObjectType> {
|
||||
return transaction(db = database) {
|
||||
selectAll().paginate(pagination).map {
|
||||
it.asObject
|
||||
}.createPaginationResult(
|
||||
pagination,
|
||||
selectAll().count()
|
||||
)
|
||||
}
|
||||
}
|
||||
override suspend fun getById(id: IdType): ObjectType? {
|
||||
return transaction(db = database) {
|
||||
select {
|
||||
selectById(id)
|
||||
}.limit(1).firstOrNull() ?.asObject
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun contains(id: IdType): Boolean = transaction(db = database) {
|
||||
select { selectById(id) }.limit(1).any()
|
||||
}
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
package dev.inmo.micro_utils.repos.exposed
|
||||
|
||||
import com.insanusmokrassar.postssystem.utils.repos.UpdatedValuePair
|
||||
import com.insanusmokrassar.postssystem.utils.repos.WriteStandardCRUDRepo
|
||||
import kotlinx.coroutines.channels.BroadcastChannel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.asFlow
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.jetbrains.exposed.sql.statements.InsertStatement
|
||||
import org.jetbrains.exposed.sql.statements.UpdateStatement
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
|
||||
abstract class AbstractExposedWriteCRUDRepo<ObjectType, IdType, InputValueType>(
|
||||
flowsChannelsSize: Int = 64,
|
||||
databaseName: String = ""
|
||||
) :
|
||||
AbstractExposedReadCRUDRepo<ObjectType, IdType>(databaseName),
|
||||
ExposedCRUDRepo<ObjectType, IdType>,
|
||||
WriteStandardCRUDRepo<ObjectType, IdType, InputValueType>
|
||||
{
|
||||
protected val newObjectsChannel = BroadcastChannel<ObjectType>(flowsChannelsSize)
|
||||
protected val updateObjectsChannel = BroadcastChannel<ObjectType>(flowsChannelsSize)
|
||||
protected val deleteObjectsIdsChannel = BroadcastChannel<IdType>(flowsChannelsSize)
|
||||
|
||||
override val newObjectsFlow: Flow<ObjectType> = newObjectsChannel.asFlow()
|
||||
override val updatedObjectsFlow: Flow<ObjectType> = updateObjectsChannel.asFlow()
|
||||
override val deletedObjectsIdsFlow: Flow<IdType> = deleteObjectsIdsChannel.asFlow()
|
||||
|
||||
abstract val InsertStatement<Number>.asObject: ObjectType
|
||||
abstract val selectByIds: SqlExpressionBuilder.(List<out IdType>) -> Op<Boolean>
|
||||
|
||||
protected abstract fun insert(value: InputValueType, it: InsertStatement<Number>)
|
||||
protected abstract fun update(id: IdType, value: InputValueType, it: UpdateStatement)
|
||||
|
||||
protected open suspend fun onBeforeCreate(value: List<InputValueType>) {}
|
||||
private fun createWithoutNotification(value: InputValueType): ObjectType {
|
||||
return transaction(database) {
|
||||
insert { insert(value, it) }.asObject
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun create(values: List<InputValueType>): List<ObjectType> {
|
||||
onBeforeCreate(values)
|
||||
return transaction(db = database) {
|
||||
values.map { value -> createWithoutNotification(value) }
|
||||
}.also {
|
||||
it.forEach {
|
||||
newObjectsChannel.send(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected open suspend fun onBeforeUpdate(value: List<UpdatedValuePair<IdType, InputValueType>>) {}
|
||||
private fun updateWithoutNotification(id: IdType, value: InputValueType): ObjectType? {
|
||||
return transaction(db = database) {
|
||||
update(
|
||||
{
|
||||
selectById(this, id)
|
||||
}
|
||||
) {
|
||||
update(id, value, it)
|
||||
}
|
||||
}.let {
|
||||
if (it > 0) {
|
||||
select {
|
||||
selectById(this, id)
|
||||
}.limit(1).firstOrNull() ?.asObject
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun update(id: IdType, value: InputValueType): ObjectType? {
|
||||
onBeforeUpdate(listOf(id to value))
|
||||
return updateWithoutNotification(id, value).also {
|
||||
if (it != null) {
|
||||
updateObjectsChannel.send(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
override suspend fun update(values: List<UpdatedValuePair<IdType, InputValueType>>): List<ObjectType> {
|
||||
onBeforeUpdate(values)
|
||||
return (
|
||||
transaction(db = database) {
|
||||
values.map { (id, value) -> updateWithoutNotification(id, value) }
|
||||
}.filter {
|
||||
it != null
|
||||
} as List<ObjectType>
|
||||
).also {
|
||||
it.forEach {
|
||||
updateObjectsChannel.send(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
protected open suspend fun onBeforeDelete(ids: List<IdType>) {}
|
||||
override suspend fun deleteById(ids: List<IdType>) {
|
||||
onBeforeDelete(ids)
|
||||
transaction(db = database) {
|
||||
deleteWhere(null, null) {
|
||||
selectByIds(ids)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package dev.inmo.micro_utils.repos.exposed
|
||||
|
||||
import org.jetbrains.exposed.sql.*
|
||||
|
||||
interface ExposedCRUDRepo<ObjectType, IdType> {
|
||||
val database: Database
|
||||
|
||||
val ResultRow.asObject: ObjectType
|
||||
val selectById: SqlExpressionBuilder.(IdType) -> Op<Boolean>
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package dev.inmo.micro_utils.repos.exposed
|
||||
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
|
||||
fun Table.initTable(database: Database) {
|
||||
transaction(database) { SchemaUtils.createMissingTablesAndColumns(this@initTable) }
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package dev.inmo.micro_utils.repos.exposed.keyvalue
|
||||
|
||||
import com.insanusmokrassar.postssystem.utils.repos.StandardKeyValueRepo
|
||||
import kotlinx.coroutines.channels.BroadcastChannel
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.asFlow
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
|
||||
abstract class AbstractExposedKeyValueRepo<Key, Value>(
|
||||
database: Database,
|
||||
keyColumn: Column<Key>,
|
||||
valueColumn: Column<Value>
|
||||
) : StandardKeyValueRepo<Key, Value>, AbstractExposedReadKeyValueRepo<Key, Value>(
|
||||
database,
|
||||
keyColumn,
|
||||
valueColumn
|
||||
) {
|
||||
private val onNewValueChannel = BroadcastChannel<Pair<Key, Value>>(Channel.BUFFERED)
|
||||
private val onValueRemovedChannel = BroadcastChannel<Key>(Channel.BUFFERED)
|
||||
|
||||
override val onNewValue: Flow<Pair<Key, Value>> = onNewValueChannel.asFlow()
|
||||
override val onValueRemoved: Flow<Key> = onValueRemovedChannel.asFlow()
|
||||
|
||||
override suspend fun set(k: Key, v: Value) {
|
||||
transaction(db = database) {
|
||||
if (select { keyColumn.eq(k) }.limit(1).any()) {
|
||||
update({ keyColumn.eq(k) }) {
|
||||
it[valueColumn] = v
|
||||
}
|
||||
} else {
|
||||
insert {
|
||||
it[keyColumn] = k
|
||||
it[valueColumn] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
onNewValueChannel.send(k to v)
|
||||
}
|
||||
|
||||
override suspend fun unset(k: Key) {
|
||||
transaction(db = database) {
|
||||
deleteWhere { keyColumn.eq(k) }
|
||||
}
|
||||
onValueRemovedChannel.send(k)
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package dev.inmo.micro_utils.repos.exposed.keyvalue
|
||||
|
||||
import com.insanusmokrassar.postssystem.exposed.commons.paginate
|
||||
import com.insanusmokrassar.postssystem.utils.common.pagination.*
|
||||
import com.insanusmokrassar.postssystem.utils.repos.StandardReadKeyValueRepo
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
|
||||
abstract class AbstractExposedReadKeyValueRepo<Key, Value>(
|
||||
protected val database: Database,
|
||||
protected val keyColumn: Column<Key>,
|
||||
protected val valueColumn: Column<Value>
|
||||
) : StandardReadKeyValueRepo<Key, Value>, Table() {
|
||||
override val primaryKey: PrimaryKey = PrimaryKey(keyColumn, valueColumn)
|
||||
|
||||
override suspend fun get(k: Key): Value? = transaction(db = database) {
|
||||
select { keyColumn.eq(k) }.limit(1).firstOrNull() ?.getOrNull(valueColumn)
|
||||
}
|
||||
|
||||
override suspend fun contains(key: Key): Boolean = transaction(db = database) {
|
||||
select { keyColumn.eq(key) }.limit(1).any()
|
||||
}
|
||||
|
||||
override suspend fun count(): Long = transaction(db = database) { selectAll().count() }
|
||||
|
||||
override suspend fun keys(pagination: Pagination, reversed: Boolean): PaginationResult<Key> = transaction(db = database) {
|
||||
selectAll().paginate(pagination, keyColumn to if (reversed) SortOrder.DESC else SortOrder.ASC).map {
|
||||
it[keyColumn]
|
||||
}
|
||||
}.createPaginationResult(pagination, count())
|
||||
|
||||
override suspend fun values(pagination: Pagination, reversed: Boolean): PaginationResult<Value> = transaction(db = database) {
|
||||
selectAll().paginate(pagination, keyColumn to if (reversed) SortOrder.DESC else SortOrder.ASC).map {
|
||||
it[valueColumn]
|
||||
}
|
||||
}.createPaginationResult(pagination, count())
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package dev.inmo.micro_utils.repos.exposed.onetomany
|
||||
|
||||
import com.insanusmokrassar.budgetmanager.core.utils.repo.onetomany.AbstractOneToManyExposedReadKeyValueRepo
|
||||
import com.insanusmokrassar.budgetmanager.core.utils.repo.onetomany.ColumnAllocator
|
||||
import com.insanusmokrassar.postssystem.utils.repos.OneToManyKeyValueRepo
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
|
||||
abstract class AbstractOneToManyExposedKeyValueRepo<Key, Value>(
|
||||
keyColumnAllocator: ColumnAllocator<Key>,
|
||||
valueColumnAllocator: ColumnAllocator<Value>,
|
||||
database: Database
|
||||
) : OneToManyKeyValueRepo<Key, Value>, AbstractOneToManyExposedReadKeyValueRepo<Key, Value>(
|
||||
keyColumnAllocator,
|
||||
valueColumnAllocator,
|
||||
database
|
||||
) {
|
||||
override suspend fun add(k: Key, v: Value) {
|
||||
transaction(db = database) {
|
||||
insert {
|
||||
it[keyColumn] = k
|
||||
it[valueColumn] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun remove(k: Key, v: Value) {
|
||||
transaction(db = database) { deleteWhere { keyColumn.eq(k).and(valueColumn.eq(v)) } }
|
||||
}
|
||||
|
||||
override suspend fun clear(k: Key) {
|
||||
transaction(db = database) { deleteWhere { keyColumn.eq(k) } }
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package dev.inmo.micro_utils.repos.exposed.onetomany
|
||||
|
||||
import com.insanusmokrassar.postssystem.exposed.commons.paginate
|
||||
import com.insanusmokrassar.postssystem.utils.common.pagination.*
|
||||
import com.insanusmokrassar.postssystem.utils.repos.OneToManyReadKeyValueRepo
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
|
||||
typealias ColumnAllocator<T> = Table.() -> Column<T>
|
||||
|
||||
abstract class AbstractOneToManyExposedReadKeyValueRepo<Key, Value>(
|
||||
keyColumnAllocator: ColumnAllocator<Key>,
|
||||
valueColumnAllocator: ColumnAllocator<Value>,
|
||||
protected val database: Database
|
||||
) : OneToManyReadKeyValueRepo<Key, Value>, Table() {
|
||||
protected val keyColumn: Column<Key> = keyColumnAllocator()
|
||||
protected val valueColumn: Column<Value> = valueColumnAllocator()
|
||||
|
||||
override suspend fun count(k: Key): Long = transaction(db = database) { select { keyColumn.eq(k) }.count() }
|
||||
|
||||
override suspend fun count(): Long = transaction(db = database) { selectAll().count() }
|
||||
|
||||
override suspend fun get(
|
||||
k: Key,
|
||||
pagination: Pagination,
|
||||
reversed: Boolean
|
||||
): PaginationResult<Value> = transaction(db = database) {
|
||||
select { keyColumn.eq(k) }.paginate(pagination, keyColumn, reversed).map { it[valueColumn] }
|
||||
}.createPaginationResult(
|
||||
pagination,
|
||||
count(k)
|
||||
)
|
||||
|
||||
override suspend fun keys(pagination: Pagination, reversed: Boolean): PaginationResult<Key> = transaction(db = database) {
|
||||
selectAll().paginate(pagination, keyColumn, reversed).map { it[keyColumn] }
|
||||
}.createPaginationResult(
|
||||
pagination,
|
||||
count()
|
||||
)
|
||||
|
||||
override suspend fun contains(k: Key): Boolean = transaction(db = database) {
|
||||
select { keyColumn.eq(k) }.limit(1).any()
|
||||
}
|
||||
|
||||
override suspend fun contains(k: Key, v: Value): Boolean = transaction(db = database) {
|
||||
select { keyColumn.eq(k).and(valueColumn.eq(v)) }.limit(1).any()
|
||||
}
|
||||
}
|
17
repos/ktor/client/build.gradle
Normal file
17
repos/ktor/client/build.gradle
Normal file
@ -0,0 +1,17 @@
|
||||
plugins {
|
||||
id "org.jetbrains.kotlin.multiplatform"
|
||||
id "org.jetbrains.kotlin.plugin.serialization"
|
||||
}
|
||||
|
||||
apply from: "$mppProjectWithSerializationPresetPath"
|
||||
|
||||
kotlin {
|
||||
sourceSets {
|
||||
commonMain {
|
||||
dependencies {
|
||||
api internalProject("micro_utils.repos.ktor.common")
|
||||
api "io.ktor:ktor-client:$ktor_version"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package dev.inmo.micro_utils.repos.ktor.client.crud
|
||||
|
||||
import dev.inmo.micro_utils.pagination.Pagination
|
||||
import dev.inmo.micro_utils.pagination.PaginationResult
|
||||
import dev.inmo.micro_utils.repos.ReadStandardCRUDRepo
|
||||
import dev.inmo.micro_utils.repos.ktor.common.crud.*
|
||||
import io.ktor.client.HttpClient
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
|
||||
class KtorReadStandardCrudRepo<ObjectType, IdType> (
|
||||
private val baseUrl: String,
|
||||
private val client: HttpClient = HttpClient(),
|
||||
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(
|
||||
buildStandardUrl(baseUrl, getByPaginationRouting, pagination.asUrlQueryParts),
|
||||
paginationResultSerializer
|
||||
)
|
||||
|
||||
override suspend fun getById(id: IdType): ObjectType? = client.uniget(
|
||||
buildStandardUrl(
|
||||
baseUrl,
|
||||
getByIdRouting,
|
||||
mapOf(
|
||||
"id" to idsSerializer.encodeUrlQueryValue(id)
|
||||
)
|
||||
),
|
||||
objectsSerializerNullable
|
||||
)
|
||||
|
||||
override suspend fun contains(id: IdType): Boolean = client.uniget(
|
||||
buildStandardUrl(
|
||||
baseUrl,
|
||||
containsRouting,
|
||||
mapOf(
|
||||
"id" to idsSerializer.encodeUrlQueryValue(id)
|
||||
)
|
||||
),
|
||||
Boolean.serializer()
|
||||
)
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package dev.inmo.micro_utils.repos.ktor.client.crud
|
||||
|
||||
import dev.inmo.micro_utils.repos.*
|
||||
import io.ktor.client.HttpClient
|
||||
import kotlinx.serialization.KSerializer
|
||||
|
||||
class KtorStandardCrudRepo<ObjectType, IdType, InputValue> (
|
||||
baseUrl: String,
|
||||
baseSubpart: String,
|
||||
client: HttpClient,
|
||||
objectsSerializer: KSerializer<ObjectType>,
|
||||
objectsNullableSerializer: KSerializer<ObjectType?>,
|
||||
inputsSerializer: KSerializer<InputValue>,
|
||||
idsSerializer: KSerializer<IdType>
|
||||
) : StandardCRUDRepo<ObjectType, IdType, InputValue>,
|
||||
ReadStandardCRUDRepo<ObjectType, IdType> by KtorReadStandardCrudRepo(
|
||||
"$baseUrl/$baseSubpart",
|
||||
client,
|
||||
objectsSerializer,
|
||||
objectsNullableSerializer,
|
||||
idsSerializer
|
||||
),
|
||||
WriteStandardCRUDRepo<ObjectType, IdType, InputValue> by KtorWriteStandardCrudRepo(
|
||||
"$baseUrl/$baseSubpart",
|
||||
client,
|
||||
objectsSerializer,
|
||||
objectsNullableSerializer,
|
||||
inputsSerializer,
|
||||
idsSerializer
|
||||
)
|
@ -0,0 +1,65 @@
|
||||
package dev.inmo.micro_utils.repos.ktor.client.crud
|
||||
|
||||
import dev.inmo.micro_utils.repos.UpdatedValuePair
|
||||
import dev.inmo.micro_utils.repos.WriteStandardCRUDRepo
|
||||
import dev.inmo.micro_utils.repos.ktor.common.crud.*
|
||||
import io.ktor.client.HttpClient
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.builtins.*
|
||||
|
||||
class KtorWriteStandardCrudRepo<ObjectType, IdType, InputValue> (
|
||||
private val baseUrl: String,
|
||||
private val client: HttpClient = HttpClient(),
|
||||
private val objectsSerializer: KSerializer<ObjectType>,
|
||||
private val objectsNullableSerializer: KSerializer<ObjectType?>,
|
||||
private val inputsSerializer: KSerializer<InputValue>,
|
||||
private val idsSerializer: KSerializer<IdType>
|
||||
) : WriteStandardCRUDRepo<ObjectType, IdType, InputValue> {
|
||||
private val listObjectsSerializer = ListSerializer(objectsSerializer)
|
||||
private val listInputSerializer = ListSerializer(inputsSerializer)
|
||||
private val listIdsSerializer = ListSerializer(idsSerializer)
|
||||
private val inputUpdateSerializer = PairSerializer(
|
||||
idsSerializer,
|
||||
inputsSerializer
|
||||
)
|
||||
private val listInputUpdateSerializer = ListSerializer(inputUpdateSerializer)
|
||||
|
||||
override val newObjectsFlow: Flow<ObjectType> = client.createStandardWebsocketFlow(
|
||||
buildStandardUrl(baseUrl, newObjectsFlowRouting),
|
||||
deserializer = objectsSerializer
|
||||
)
|
||||
override val updatedObjectsFlow: Flow<ObjectType> = client.createStandardWebsocketFlow(
|
||||
buildStandardUrl(baseUrl, updatedObjectsFlowRouting),
|
||||
deserializer = objectsSerializer
|
||||
)
|
||||
override val deletedObjectsIdsFlow: Flow<IdType> = client.createStandardWebsocketFlow(
|
||||
buildStandardUrl(baseUrl, deletedObjectsIdsFlowRouting),
|
||||
deserializer = idsSerializer
|
||||
)
|
||||
|
||||
|
||||
override suspend fun create(values: List<InputValue>): List<ObjectType> = client.unipost(
|
||||
buildStandardUrl(baseUrl, createRouting),
|
||||
BodyPair(listInputSerializer, values),
|
||||
listObjectsSerializer
|
||||
)
|
||||
|
||||
override suspend fun update(id: IdType, value: InputValue): ObjectType? = client.unipost(
|
||||
buildStandardUrl(baseUrl, updateRouting),
|
||||
BodyPair(inputUpdateSerializer, id to value),
|
||||
objectsNullableSerializer
|
||||
)
|
||||
|
||||
override suspend fun update(values: List<UpdatedValuePair<IdType, InputValue>>): List<ObjectType> = client.unipost(
|
||||
buildStandardUrl(baseUrl, updateManyRouting),
|
||||
BodyPair(listInputUpdateSerializer, values),
|
||||
listObjectsSerializer
|
||||
)
|
||||
|
||||
override suspend fun deleteById(ids: List<IdType>) = client.unipost(
|
||||
buildStandardUrl(baseUrl, deleteByIdRouting),
|
||||
BodyPair(listIdsSerializer, ids),
|
||||
Unit.serializer()
|
||||
)
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package dev.inmo.micro_utils.repos.ktor.client.key_value
|
||||
|
||||
import dev.inmo.micro_utils.repos.StandardKeyValueRepo
|
||||
import dev.inmo.micro_utils.repos.StandardReadKeyValueRepo
|
||||
import dev.inmo.micro_utils.repos.StandardWriteKeyValueRepo
|
||||
import io.ktor.client.*
|
||||
import kotlinx.serialization.KSerializer
|
||||
|
||||
class KtorStandartKeyValueRepo<K, V> (
|
||||
baseUrl: String,
|
||||
baseSubpart: String,
|
||||
client: HttpClient = HttpClient(),
|
||||
keySerializer: KSerializer<K>,
|
||||
valueSerializer: KSerializer<V>,
|
||||
valueNullableSerializer: KSerializer<V?>
|
||||
) : StandardKeyValueRepo<K, V>,
|
||||
StandardReadKeyValueRepo<K, V> by KtorStandartReadKeyValueRepo(
|
||||
"$baseUrl/$baseSubpart",
|
||||
client,
|
||||
keySerializer,
|
||||
valueSerializer,
|
||||
valueNullableSerializer
|
||||
),
|
||||
StandardWriteKeyValueRepo<K, V> by KtorStandartWriteKeyValueRepo(
|
||||
"$baseUrl/$baseSubpart",
|
||||
client,
|
||||
keySerializer,
|
||||
valueSerializer
|
||||
)
|
@ -0,0 +1,69 @@
|
||||
package dev.inmo.micro_utils.repos.ktor.client.key_value
|
||||
|
||||
import dev.inmo.micro_utils.pagination.Pagination
|
||||
import dev.inmo.micro_utils.pagination.PaginationResult
|
||||
import dev.inmo.micro_utils.repos.StandardReadKeyValueRepo
|
||||
import dev.inmo.micro_utils.repos.ktor.common.key_value.*
|
||||
import io.ktor.client.*
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
|
||||
class KtorStandartReadKeyValueRepo<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?>,
|
||||
) : StandardReadKeyValueRepo<Key, Value> {
|
||||
override suspend fun get(k: Key): Value? = client.uniget(
|
||||
buildStandardUrl(
|
||||
baseUrl,
|
||||
getRoute,
|
||||
mapOf(
|
||||
keyParameterName to keySerializer.encodeUrlQueryValue(k)
|
||||
)
|
||||
),
|
||||
valueNullableSerializer
|
||||
)
|
||||
|
||||
override suspend fun values(pagination: Pagination, reversed: Boolean): PaginationResult<Value> = client.uniget(
|
||||
buildStandardUrl(
|
||||
baseUrl,
|
||||
valuesRoute,
|
||||
mapOf(
|
||||
reversedParameterName to Boolean.serializer().encodeUrlQueryValue(reversed)
|
||||
) + pagination.asUrlQueryParts
|
||||
),
|
||||
PaginationResult.serializer(valueSerializer)
|
||||
)
|
||||
|
||||
override suspend fun keys(pagination: Pagination, reversed: Boolean): PaginationResult<Key> = client.uniget(
|
||||
buildStandardUrl(
|
||||
baseUrl,
|
||||
keysRoute,
|
||||
mapOf(
|
||||
reversedParameterName to Boolean.serializer().encodeUrlQueryValue(reversed)
|
||||
) + pagination.asUrlQueryParts
|
||||
),
|
||||
PaginationResult.serializer(keySerializer)
|
||||
)
|
||||
|
||||
override suspend fun contains(key: Key): Boolean = client.uniget(
|
||||
buildStandardUrl(
|
||||
baseUrl,
|
||||
containsRoute,
|
||||
mapOf(
|
||||
keyParameterName to keySerializer.encodeUrlQueryValue(key)
|
||||
),
|
||||
),
|
||||
Boolean.serializer(),
|
||||
)
|
||||
|
||||
override suspend fun count(): Long = client.uniget(
|
||||
buildStandardUrl(
|
||||
baseUrl,
|
||||
countRoute,
|
||||
),
|
||||
Long.serializer()
|
||||
)
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package dev.inmo.micro_utils.repos.ktor.client.key_value
|
||||
|
||||
import dev.inmo.micro_utils.repos.StandardWriteKeyValueRepo
|
||||
import dev.inmo.micro_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<K, V> (
|
||||
private var baseUrl: String,
|
||||
private var client: HttpClient = HttpClient(),
|
||||
private var keySerializer: KSerializer<K>,
|
||||
private var valueSerializer: KSerializer<V>,
|
||||
) : StandardWriteKeyValueRepo<K, V> {
|
||||
override val onNewValue: Flow<Pair<K, V>> = client.createStandardWebsocketFlow(
|
||||
buildStandardUrl(baseUrl, onNewValueRoute),
|
||||
deserializer = PairSerializer(keySerializer, valueSerializer)
|
||||
)
|
||||
|
||||
override val onValueRemoved: Flow<K> = 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()
|
||||
)
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package dev.inmo.micro_utils.repos.ktor.client.one_to_many
|
||||
|
||||
import dev.inmo.micro_utils.repos.OneToManyKeyValueRepo
|
||||
import dev.inmo.micro_utils.repos.OneToManyReadKeyValueRepo
|
||||
import dev.inmo.micro_utils.repos.OneToManyWriteKeyValueRepo
|
||||
import io.ktor.client.HttpClient
|
||||
import kotlinx.serialization.KSerializer
|
||||
|
||||
class KtorOneToManyKeyValueRepo<Key, Value>(
|
||||
baseUrl: String,
|
||||
baseSubpart: String,
|
||||
client: HttpClient,
|
||||
keySerializer: KSerializer<Key>,
|
||||
valueSerializer: KSerializer<Value>,
|
||||
) : OneToManyKeyValueRepo<Key, Value>,
|
||||
OneToManyReadKeyValueRepo<Key, Value> by KtorOneToManyReadKeyValueRepo<Key, Value> (
|
||||
"$baseUrl/$baseSubpart",
|
||||
client,
|
||||
keySerializer,
|
||||
valueSerializer,
|
||||
),
|
||||
OneToManyWriteKeyValueRepo<Key, Value> by KtorOneToManyWriteKeyValueRepo<Key, Value> (
|
||||
"$baseUrl/$baseSubpart",
|
||||
client,
|
||||
keySerializer,
|
||||
valueSerializer,
|
||||
)
|
@ -0,0 +1,83 @@
|
||||
package dev.inmo.micro_utils.repos.ktor.client.one_to_many
|
||||
|
||||
import dev.inmo.micro_utils.pagination.Pagination
|
||||
import dev.inmo.micro_utils.pagination.PaginationResult
|
||||
import dev.inmo.micro_utils.repos.OneToManyReadKeyValueRepo
|
||||
import dev.inmo.micro_utils.repos.ktor.common.one_to_many.*
|
||||
import io.ktor.client.HttpClient
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
|
||||
class KtorOneToManyReadKeyValueRepo<Key, Value> (
|
||||
private val baseUrl: String,
|
||||
private val client: HttpClient = HttpClient(),
|
||||
private val keySerializer: KSerializer<Key>,
|
||||
private val valueSerializer: KSerializer<Value>,
|
||||
) : OneToManyReadKeyValueRepo<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(
|
||||
buildStandardUrl(
|
||||
baseUrl,
|
||||
getRoute,
|
||||
mapOf(
|
||||
keyParameterName to keySerializer.encodeUrlQueryValue(k),
|
||||
reversedParameterName to Boolean.serializer().encodeUrlQueryValue(reversed)
|
||||
) + pagination.asUrlQueryParts
|
||||
),
|
||||
paginationValueResultSerializer
|
||||
)
|
||||
|
||||
override suspend fun keys(pagination: Pagination, reversed: Boolean): PaginationResult<Key> = client.uniget(
|
||||
buildStandardUrl(
|
||||
baseUrl,
|
||||
keysRoute,
|
||||
mapOf(
|
||||
reversedParameterName to Boolean.serializer().encodeUrlQueryValue(reversed)
|
||||
) + pagination.asUrlQueryParts
|
||||
),
|
||||
paginationKeyResultSerializer
|
||||
)
|
||||
|
||||
override suspend fun contains(k: Key): Boolean = client.uniget(
|
||||
buildStandardUrl(
|
||||
baseUrl,
|
||||
containsByKeyRoute,
|
||||
mapOf(keyParameterName to keySerializer.encodeUrlQueryValue(k))
|
||||
),
|
||||
Boolean.serializer()
|
||||
)
|
||||
|
||||
override suspend fun contains(k: Key, v: Value): Boolean = client.uniget(
|
||||
buildStandardUrl(
|
||||
baseUrl,
|
||||
containsByKeyValueRoute,
|
||||
mapOf(
|
||||
keyParameterName to keySerializer.encodeUrlQueryValue(k),
|
||||
valueParameterName to valueSerializer.encodeUrlQueryValue(v),
|
||||
)
|
||||
),
|
||||
Boolean.serializer()
|
||||
)
|
||||
|
||||
override suspend fun count(k: Key): Long = client.uniget(
|
||||
buildStandardUrl(
|
||||
baseUrl,
|
||||
countByKeyRoute,
|
||||
mapOf(
|
||||
keyParameterName to keySerializer.encodeUrlQueryValue(k)
|
||||
)
|
||||
),
|
||||
Long.serializer()
|
||||
)
|
||||
|
||||
override suspend fun count(): Long = client.uniget(
|
||||
buildStandardUrl(
|
||||
baseUrl,
|
||||
countRoute,
|
||||
),
|
||||
Long.serializer()
|
||||
)
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package dev.inmo.micro_utils.repos.ktor.client.one_to_many
|
||||
|
||||
import dev.inmo.micro_utils.repos.OneToManyWriteKeyValueRepo
|
||||
import dev.inmo.micro_utils.repos.ktor.common.one_to_many.*
|
||||
import io.ktor.client.HttpClient
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.builtins.PairSerializer
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
|
||||
class KtorOneToManyWriteKeyValueRepo<Key, Value> (
|
||||
private val baseUrl: String,
|
||||
private val client: HttpClient = HttpClient(),
|
||||
private val keySerializer: KSerializer<Key>,
|
||||
private val valueSerializer: KSerializer<Value>,
|
||||
) : OneToManyWriteKeyValueRepo<Key, Value> {
|
||||
private val keyValueSerializer = PairSerializer(keySerializer, valueSerializer)
|
||||
|
||||
override suspend fun add(k: Key, v: Value) = client.unipost(
|
||||
buildStandardUrl(
|
||||
baseUrl,
|
||||
addRoute,
|
||||
),
|
||||
BodyPair(keyValueSerializer, k to v),
|
||||
Unit.serializer(),
|
||||
)
|
||||
|
||||
override suspend fun remove(k: Key, v: Value) = client.unipost(
|
||||
buildStandardUrl(
|
||||
baseUrl,
|
||||
removeRoute,
|
||||
),
|
||||
BodyPair(keyValueSerializer, k to v),
|
||||
Unit.serializer(),
|
||||
)
|
||||
|
||||
override suspend fun clear(k: Key) = client.unipost(
|
||||
buildStandardUrl(
|
||||
baseUrl,
|
||||
clearRoute,
|
||||
),
|
||||
BodyPair(keySerializer, k),
|
||||
Unit.serializer(),
|
||||
)
|
||||
}
|
16
repos/ktor/common/build.gradle
Normal file
16
repos/ktor/common/build.gradle
Normal file
@ -0,0 +1,16 @@
|
||||
plugins {
|
||||
id "org.jetbrains.kotlin.multiplatform"
|
||||
id "org.jetbrains.kotlin.plugin.serialization"
|
||||
}
|
||||
|
||||
apply from: "$mppProjectWithSerializationPresetPath"
|
||||
|
||||
kotlin {
|
||||
sourceSets {
|
||||
commonMain {
|
||||
dependencies {
|
||||
api internalProject("micro_utils.repos.common")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package dev.inmo.micro_utils.repos.ktor.common.crud
|
||||
|
||||
const val getByPaginationRouting = "getByPagination"
|
||||
const val getByIdRouting = "getById"
|
||||
const val containsRouting = "contains"
|
@ -0,0 +1,10 @@
|
||||
package dev.inmo.micro_utils.repos.ktor.common.crud
|
||||
|
||||
const val newObjectsFlowRouting = "newObjectsFlow"
|
||||
const val updatedObjectsFlowRouting = "updatedObjectsFlow"
|
||||
const val deletedObjectsIdsFlowRouting = "deletedObjectsIdsFlow"
|
||||
|
||||
const val createRouting = "create"
|
||||
const val updateRouting = "update"
|
||||
const val updateManyRouting = "updateMany"
|
||||
const val deleteByIdRouting = "deleteById"
|
@ -0,0 +1,4 @@
|
||||
package dev.inmo.micro_utils.repos.ktor.common.key_value
|
||||
|
||||
const val keyParameterName = "key"
|
||||
const val reversedParameterName = "reversed"
|
@ -0,0 +1,9 @@
|
||||
package dev.inmo.micro_utils.repos.ktor.common.key_value
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class KeyValuePostObject<K, V> (
|
||||
val key: K,
|
||||
val value: V,
|
||||
)
|
@ -0,0 +1,12 @@
|
||||
package dev.inmo.micro_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"
|
@ -0,0 +1,5 @@
|
||||
package dev.inmo.micro_utils.repos.ktor.common.one_to_many
|
||||
|
||||
const val keyParameterName = "key"
|
||||
const val valueParameterName = "value"
|
||||
const val reversedParameterName = "reversed"
|
@ -0,0 +1,12 @@
|
||||
package dev.inmo.micro_utils.repos.ktor.common.one_to_many
|
||||
|
||||
const val getRoute = "get"
|
||||
const val keysRoute = "keys"
|
||||
const val containsByKeyRoute = "containsByKey"
|
||||
const val containsByKeyValueRoute = "containsByKeyValue"
|
||||
const val countByKeyRoute = "countByKey"
|
||||
const val countRoute = "count"
|
||||
|
||||
const val addRoute = "add"
|
||||
const val removeRoute = "remove"
|
||||
const val clearRoute = "clear"
|
23
repos/ktor/server/build.gradle
Normal file
23
repos/ktor/server/build.gradle
Normal file
@ -0,0 +1,23 @@
|
||||
plugins {
|
||||
id "org.jetbrains.kotlin.multiplatform"
|
||||
id "org.jetbrains.kotlin.plugin.serialization"
|
||||
}
|
||||
|
||||
apply from: "$mppJavaProjectPresetPath"
|
||||
|
||||
kotlin {
|
||||
sourceSets {
|
||||
commonMain {
|
||||
dependencies {
|
||||
api internalProject("micro_utils.repos.ktor.common")
|
||||
}
|
||||
}
|
||||
|
||||
jvmMain {
|
||||
dependencies {
|
||||
api "io.ktor:ktor-server:$ktor_version"
|
||||
api "io.ktor:ktor-server-host-common:$ktor_version"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package dev.inmo.micro_utils.repos.ktor.server.crud
|
||||
|
||||
import dev.inmo.micro_utils.repos.ktor.common.crud.containsRouting
|
||||
import dev.inmo.micro_utils.repos.ktor.common.crud.getByIdRouting
|
||||
import dev.inmo.micro_utils.repos.ktor.common.crud.getByPaginationRouting
|
||||
import dev.inmo.micro_utils.pagination.PaginationResult
|
||||
import dev.inmo.micro_utils.repos.ReadStandardCRUDRepo
|
||||
import io.ktor.application.call
|
||||
import io.ktor.routing.Route
|
||||
import io.ktor.routing.get
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
|
||||
fun <ObjectType, IdType> Route.configureReadStandardCrudRepoRoutes(
|
||||
originalRepo: ReadStandardCRUDRepo<ObjectType, IdType>,
|
||||
objectsSerializer: KSerializer<ObjectType>,
|
||||
objectsNullableSerializer: KSerializer<ObjectType?>,
|
||||
idsSerializer: KSerializer<IdType>
|
||||
) {
|
||||
val paginationResultSerializer = PaginationResult.serializer(objectsSerializer)
|
||||
|
||||
get(getByPaginationRouting) {
|
||||
val pagination = call.request.queryParameters.extractPagination
|
||||
|
||||
call.unianswer(
|
||||
paginationResultSerializer,
|
||||
originalRepo.getByPagination(pagination)
|
||||
)
|
||||
}
|
||||
|
||||
get(getByIdRouting) {
|
||||
val id = call.decodeUrlQueryValueOrSendError(
|
||||
"id",
|
||||
idsSerializer
|
||||
) ?: return@get
|
||||
|
||||
call.unianswer(
|
||||
objectsNullableSerializer,
|
||||
originalRepo.getById(id)
|
||||
)
|
||||
}
|
||||
|
||||
get(containsRouting) {
|
||||
val id = call.decodeUrlQueryValueOrSendError(
|
||||
"id",
|
||||
idsSerializer
|
||||
) ?: return@get
|
||||
|
||||
call.unianswer(
|
||||
Boolean.serializer(),
|
||||
originalRepo.contains(id)
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package dev.inmo.micro_utils.repos.ktor.server.crud
|
||||
|
||||
import dev.inmo.micro_utils.repos.StandardCRUDRepo
|
||||
import io.ktor.routing.Route
|
||||
import io.ktor.routing.route
|
||||
import kotlinx.serialization.KSerializer
|
||||
|
||||
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>
|
||||
) {
|
||||
route(baseSubpart) {
|
||||
configureReadStandardCrudRepoRoutes(originalRepo, objectsSerializer, objectsNullableSerializer, idsSerializer)
|
||||
configureWriteStandardCrudRepoRoutes(originalRepo, objectsSerializer, objectsNullableSerializer, inputsSerializer, idsSerializer)
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
package dev.inmo.micro_utils.repos.ktor.server.crud
|
||||
|
||||
import dev.inmo.micro_utils.repos.WriteStandardCRUDRepo
|
||||
import dev.inmo.micro_utils.repos.ktor.common.crud.*
|
||||
import io.ktor.application.call
|
||||
import io.ktor.routing.Route
|
||||
import io.ktor.routing.post
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.builtins.*
|
||||
|
||||
fun <ObjectType, IdType, InputValue> Route.configureWriteStandardCrudRepoRoutes(
|
||||
originalRepo: WriteStandardCRUDRepo<ObjectType, IdType, InputValue>,
|
||||
objectsSerializer: KSerializer<ObjectType>,
|
||||
objectsNullableSerializer: KSerializer<ObjectType?>,
|
||||
inputsSerializer: KSerializer<InputValue>,
|
||||
idsSerializer: KSerializer<IdType>
|
||||
) {
|
||||
val listObjectsSerializer = ListSerializer(objectsSerializer)
|
||||
val listInputSerializer = ListSerializer(inputsSerializer)
|
||||
val listIdsSerializer = ListSerializer(idsSerializer)
|
||||
val inputUpdateSerializer = PairSerializer(
|
||||
idsSerializer,
|
||||
inputsSerializer
|
||||
)
|
||||
val listInputUpdateSerializer = ListSerializer(inputUpdateSerializer)
|
||||
|
||||
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)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
post(updateRouting) {
|
||||
val (id, input) = call.uniload(inputUpdateSerializer)
|
||||
call.unianswer(
|
||||
objectsNullableSerializer,
|
||||
originalRepo.update(
|
||||
id, input
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
post(updateManyRouting) {
|
||||
val updates = call.uniload(listInputUpdateSerializer)
|
||||
call.unianswer(
|
||||
listObjectsSerializer,
|
||||
originalRepo.update(
|
||||
updates
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
post(deleteByIdRouting) {
|
||||
val ids = call.uniload(listIdsSerializer)
|
||||
call.unianswer(
|
||||
Unit.serializer(),
|
||||
originalRepo.deleteById(
|
||||
ids
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package dev.inmo.micro_utils.repos.ktor.server.key_value
|
||||
|
||||
import dev.inmo.micro_utils.repos.StandardKeyValueRepo
|
||||
import io.ktor.routing.*
|
||||
import kotlinx.serialization.KSerializer
|
||||
|
||||
fun <K, V> Route.configureStandartKeyValueRepoRoutes(
|
||||
baseSubpart: String,
|
||||
originalRepo: StandardKeyValueRepo<K, V>,
|
||||
keySerializer: KSerializer<K>,
|
||||
valueSerializer: KSerializer<V>,
|
||||
valueNullableSerializer: KSerializer<V?>,
|
||||
) {
|
||||
route(baseSubpart) {
|
||||
configureReadStandartKeyValueRepoRoutes(
|
||||
originalRepo,
|
||||
keySerializer,
|
||||
valueSerializer,
|
||||
valueNullableSerializer,
|
||||
)
|
||||
configureWriteStandartKeyValueRepoRoutes(
|
||||
originalRepo,
|
||||
keySerializer,
|
||||
valueSerializer,
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
package dev.inmo.micro_utils.repos.ktor.server.key_value
|
||||
|
||||
import dev.inmo.micro_utils.repos.StandardReadKeyValueRepo
|
||||
import dev.inmo.micro_utils.repos.ktor.common.key_value.*
|
||||
import io.ktor.application.*
|
||||
import io.ktor.routing.*
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
|
||||
fun <K, V> Route.configureReadStandartKeyValueRepoRoutes (
|
||||
originalRepo: StandardReadKeyValueRepo<K, V>,
|
||||
keySerializer: KSerializer<K>,
|
||||
valueSerializer: KSerializer<V>,
|
||||
valueNullableSerializer: KSerializer<V?>,
|
||||
) {
|
||||
get(getRoute) {
|
||||
val key = call.decodeUrlQueryValueOrSendError(
|
||||
keyParameterName,
|
||||
keySerializer
|
||||
) ?: return@get
|
||||
|
||||
call.unianswer(
|
||||
valueNullableSerializer,
|
||||
originalRepo.get(key)
|
||||
)
|
||||
}
|
||||
|
||||
get(valuesRoute) {
|
||||
val parination = call.request.queryParameters.extractPagination;
|
||||
val reversed = call.decodeUrlQueryValueOrSendError(
|
||||
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.decodeUrlQueryValueOrSendError(
|
||||
reversedParameterName,
|
||||
Boolean.serializer()
|
||||
) ?: return@get
|
||||
|
||||
call.unianswer(
|
||||
PaginationResult.serializer(keySerializer),
|
||||
originalRepo.keys(parination, reversed)
|
||||
)
|
||||
}
|
||||
|
||||
get(containsRoute) {
|
||||
val key = call.decodeUrlQueryValueOrSendError(
|
||||
keyParameterName,
|
||||
keySerializer
|
||||
) ?: return@get
|
||||
|
||||
call.unianswer(
|
||||
Boolean.serializer(),
|
||||
originalRepo.contains(key)
|
||||
)
|
||||
}
|
||||
|
||||
get(countRoute) {
|
||||
call.unianswer(
|
||||
Long.serializer(),
|
||||
originalRepo.count()
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package dev.inmo.micro_utils.repos.ktor.server.key_value
|
||||
|
||||
import dev.inmo.micro_utils.repos.StandardWriteKeyValueRepo
|
||||
import dev.inmo.micro_utils.repos.ktor.common.key_value.*
|
||||
import io.ktor.application.*
|
||||
import io.ktor.routing.*
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.builtins.PairSerializer
|
||||
|
||||
fun <K, V> Route.configureWriteStandartKeyValueRepoRoutes (
|
||||
originalRepo: StandardWriteKeyValueRepo<K, V>,
|
||||
keySerializer: KSerializer<K>,
|
||||
valueSerializer: KSerializer<V>,
|
||||
) {
|
||||
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)
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package dev.inmo.micro_utils.repos.ktor.server.one_to_many
|
||||
|
||||
import dev.inmo.micro_utils.repos.OneToManyKeyValueRepo
|
||||
import io.ktor.routing.Route
|
||||
import io.ktor.routing.route
|
||||
import kotlinx.serialization.KSerializer
|
||||
|
||||
fun <Key, Value> Route.configureOneToManyKeyValueRepoRoutes(
|
||||
baseSubpart: String,
|
||||
originalRepo: OneToManyKeyValueRepo<Key, Value>,
|
||||
keySerializer: KSerializer<Key>,
|
||||
valueSealizer: KSerializer<Value>,
|
||||
) {
|
||||
route(baseSubpart) {
|
||||
configureOneToManyReadKeyValueRepoRoutes(originalRepo, keySerializer, valueSealizer)
|
||||
configureOneToManyWriteKeyValueRepoRoutes(originalRepo, keySerializer, valueSealizer)
|
||||
}
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
package dev.inmo.micro_utils.repos.ktor.server.one_to_many
|
||||
|
||||
import dev.inmo.micro_utils.pagination.PaginationResult
|
||||
import dev.inmo.micro_utils.repos.OneToManyReadKeyValueRepo
|
||||
import dev.inmo.micro_utils.repos.ktor.common.one_to_many.*
|
||||
import io.ktor.application.call
|
||||
import io.ktor.routing.Route
|
||||
import io.ktor.routing.get
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
|
||||
fun <Key, Value> Route.configureOneToManyReadKeyValueRepoRoutes(
|
||||
originalRepo: OneToManyReadKeyValueRepo<Key, Value>,
|
||||
keySerializer: KSerializer<Key>,
|
||||
valueSealizer: KSerializer<Value>,
|
||||
) {
|
||||
val paginationKeyResult = PaginationResult.serializer(keySerializer)
|
||||
val paginationValueResult = PaginationResult.serializer(valueSealizer)
|
||||
|
||||
get(getRoute) {
|
||||
val pagination = call.request.queryParameters.extractPagination
|
||||
val key = call.decodeUrlQueryValueOrSendError(
|
||||
keyParameterName,
|
||||
keySerializer
|
||||
) ?: return@get
|
||||
val reversed = call.decodeUrlQueryValue(
|
||||
reversedParameterName,
|
||||
Boolean.serializer()
|
||||
) ?: false
|
||||
|
||||
call.unianswer(
|
||||
paginationValueResult,
|
||||
originalRepo.get(key, pagination, reversed)
|
||||
)
|
||||
}
|
||||
|
||||
get(keysRoute) {
|
||||
val pagination = call.request.queryParameters.extractPagination
|
||||
val reversed = call.decodeUrlQueryValue(
|
||||
reversedParameterName,
|
||||
Boolean.serializer()
|
||||
) ?: false
|
||||
|
||||
call.unianswer(
|
||||
paginationKeyResult,
|
||||
originalRepo.keys(pagination, reversed)
|
||||
)
|
||||
}
|
||||
|
||||
get(containsByKeyRoute) {
|
||||
val key = call.decodeUrlQueryValueOrSendError(
|
||||
keyParameterName,
|
||||
keySerializer
|
||||
) ?: return@get
|
||||
|
||||
call.unianswer(
|
||||
Boolean.serializer(),
|
||||
originalRepo.contains(key)
|
||||
)
|
||||
}
|
||||
|
||||
get(containsByKeyValueRoute) {
|
||||
val key = call.decodeUrlQueryValueOrSendError(
|
||||
keyParameterName,
|
||||
keySerializer
|
||||
) ?: return@get
|
||||
val value = call.decodeUrlQueryValueOrSendError(
|
||||
valueParameterName,
|
||||
valueSealizer
|
||||
) ?: return@get
|
||||
|
||||
call.unianswer(
|
||||
Boolean.serializer(),
|
||||
originalRepo.contains(key, value)
|
||||
)
|
||||
}
|
||||
|
||||
get(countByKeyRoute) {
|
||||
val key = call.decodeUrlQueryValueOrSendError(
|
||||
keyParameterName,
|
||||
keySerializer
|
||||
) ?: return@get
|
||||
|
||||
call.unianswer(
|
||||
Long.serializer(),
|
||||
originalRepo.count(key)
|
||||
)
|
||||
}
|
||||
|
||||
get(countRoute) {
|
||||
call.unianswer(
|
||||
Long.serializer(),
|
||||
originalRepo.count()
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package dev.inmo.micro_utils.repos.ktor.server.one_to_many
|
||||
|
||||
import dev.inmo.micro_utils.repos.OneToManyWriteKeyValueRepo
|
||||
import dev.inmo.micro_utils.repos.ktor.common.one_to_many.*
|
||||
import io.ktor.application.call
|
||||
import io.ktor.routing.Route
|
||||
import io.ktor.routing.post
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.builtins.PairSerializer
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
|
||||
fun <Key, Value> Route.configureOneToManyWriteKeyValueRepoRoutes(
|
||||
originalRepo: OneToManyWriteKeyValueRepo<Key, Value>,
|
||||
keySerializer: KSerializer<Key>,
|
||||
valueSealizer: KSerializer<Value>,
|
||||
) {
|
||||
val keyValueSerializer = PairSerializer(keySerializer, valueSealizer)
|
||||
|
||||
post(addRoute) {
|
||||
val obj = call.uniload(
|
||||
keyValueSerializer
|
||||
)
|
||||
|
||||
call.unianswer(
|
||||
Unit.serializer(),
|
||||
originalRepo.add(obj.first, obj.second)
|
||||
)
|
||||
}
|
||||
|
||||
post(removeRoute) {
|
||||
val obj = call.uniload(
|
||||
keyValueSerializer
|
||||
)
|
||||
|
||||
call.unianswer(
|
||||
Unit.serializer(),
|
||||
originalRepo.remove(obj.first, obj.second),
|
||||
)
|
||||
}
|
||||
|
||||
post(clearRoute) {
|
||||
val key = call.uniload(keySerializer)
|
||||
|
||||
call.unianswer(
|
||||
Unit.serializer(),
|
||||
originalRepo.clear(key),
|
||||
)
|
||||
}
|
||||
}
|
@ -6,6 +6,10 @@ String[] includes = [
|
||||
":pagination:ktor:common",
|
||||
":pagination:ktor:server",
|
||||
":repos:common",
|
||||
":repos:exposed",
|
||||
":repos:ktor:client",
|
||||
":repos:ktor:common",
|
||||
":repos:ktor:server",
|
||||
]
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user