diff --git a/repos/exposed/build.gradle b/repos/exposed/build.gradle new file mode 100644 index 00000000000..15db9cd680d --- /dev/null +++ b/repos/exposed/build.gradle @@ -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") + } + } + } +} diff --git a/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/AbstractExposedCRUDRepo.kt b/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/AbstractExposedCRUDRepo.kt new file mode 100644 index 00000000000..a39322eee24 --- /dev/null +++ b/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/AbstractExposedCRUDRepo.kt @@ -0,0 +1,13 @@ +package dev.inmo.micro_utils.repos.exposed + +import kotlinx.coroutines.channels.Channel + +abstract class AbstractExposedCRUDRepo( + flowsChannelsSize: Int = Channel.BUFFERED, + databaseName: String = "" +) : + AbstractExposedWriteCRUDRepo( + flowsChannelsSize, + databaseName + ), + ExposedCRUDRepo diff --git a/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/AbstractExposedReadCRUDRepo.kt b/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/AbstractExposedReadCRUDRepo.kt new file mode 100644 index 00000000000..2662389b3b4 --- /dev/null +++ b/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/AbstractExposedReadCRUDRepo.kt @@ -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( + tableName: String +) : + ReadStandardCRUDRepo, + ExposedCRUDRepo, + Table(tableName) +{ + override suspend fun getByPagination(pagination: Pagination): PaginationResult { + 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() + } +} diff --git a/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/AbstractExposedWriteCRUDRepo.kt b/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/AbstractExposedWriteCRUDRepo.kt new file mode 100644 index 00000000000..4e0a0ff9bc7 --- /dev/null +++ b/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/AbstractExposedWriteCRUDRepo.kt @@ -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( + flowsChannelsSize: Int = 64, + databaseName: String = "" +) : + AbstractExposedReadCRUDRepo(databaseName), + ExposedCRUDRepo, + WriteStandardCRUDRepo +{ + protected val newObjectsChannel = BroadcastChannel(flowsChannelsSize) + protected val updateObjectsChannel = BroadcastChannel(flowsChannelsSize) + protected val deleteObjectsIdsChannel = BroadcastChannel(flowsChannelsSize) + + override val newObjectsFlow: Flow = newObjectsChannel.asFlow() + override val updatedObjectsFlow: Flow = updateObjectsChannel.asFlow() + override val deletedObjectsIdsFlow: Flow = deleteObjectsIdsChannel.asFlow() + + abstract val InsertStatement.asObject: ObjectType + abstract val selectByIds: SqlExpressionBuilder.(List) -> Op + + protected abstract fun insert(value: InputValueType, it: InsertStatement) + protected abstract fun update(id: IdType, value: InputValueType, it: UpdateStatement) + + protected open suspend fun onBeforeCreate(value: List) {} + private fun createWithoutNotification(value: InputValueType): ObjectType { + return transaction(database) { + insert { insert(value, it) }.asObject + } + } + + override suspend fun create(values: List): List { + onBeforeCreate(values) + return transaction(db = database) { + values.map { value -> createWithoutNotification(value) } + }.also { + it.forEach { + newObjectsChannel.send(it) + } + } + } + + protected open suspend fun onBeforeUpdate(value: List>) {} + 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>): List { + onBeforeUpdate(values) + return ( + transaction(db = database) { + values.map { (id, value) -> updateWithoutNotification(id, value) } + }.filter { + it != null + } as List + ).also { + it.forEach { + updateObjectsChannel.send(it) + } + } + } + protected open suspend fun onBeforeDelete(ids: List) {} + override suspend fun deleteById(ids: List) { + onBeforeDelete(ids) + transaction(db = database) { + deleteWhere(null, null) { + selectByIds(ids) + } + } + } +} \ No newline at end of file diff --git a/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/ExposedCRUDRepo.kt b/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/ExposedCRUDRepo.kt new file mode 100644 index 00000000000..a9a9ed3d0a9 --- /dev/null +++ b/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/ExposedCRUDRepo.kt @@ -0,0 +1,10 @@ +package dev.inmo.micro_utils.repos.exposed + +import org.jetbrains.exposed.sql.* + +interface ExposedCRUDRepo { + val database: Database + + val ResultRow.asObject: ObjectType + val selectById: SqlExpressionBuilder.(IdType) -> Op +} diff --git a/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/ExposedTableInitialization.kt b/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/ExposedTableInitialization.kt new file mode 100644 index 00000000000..6f23d0dbb80 --- /dev/null +++ b/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/ExposedTableInitialization.kt @@ -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) } +} diff --git a/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/keyvalue/AbstractExposedKeyValueRepo.kt b/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/keyvalue/AbstractExposedKeyValueRepo.kt new file mode 100644 index 00000000000..3cefadb086f --- /dev/null +++ b/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/keyvalue/AbstractExposedKeyValueRepo.kt @@ -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( + database: Database, + keyColumn: Column, + valueColumn: Column +) : StandardKeyValueRepo, AbstractExposedReadKeyValueRepo( + database, + keyColumn, + valueColumn +) { + private val onNewValueChannel = BroadcastChannel>(Channel.BUFFERED) + private val onValueRemovedChannel = BroadcastChannel(Channel.BUFFERED) + + override val onNewValue: Flow> = onNewValueChannel.asFlow() + override val onValueRemoved: Flow = 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) + } +} diff --git a/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/keyvalue/AbstractExposedReadKeyValueRepo.kt b/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/keyvalue/AbstractExposedReadKeyValueRepo.kt new file mode 100644 index 00000000000..d8d96986060 --- /dev/null +++ b/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/keyvalue/AbstractExposedReadKeyValueRepo.kt @@ -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( + protected val database: Database, + protected val keyColumn: Column, + protected val valueColumn: Column +) : StandardReadKeyValueRepo, 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 = 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 = transaction(db = database) { + selectAll().paginate(pagination, keyColumn to if (reversed) SortOrder.DESC else SortOrder.ASC).map { + it[valueColumn] + } + }.createPaginationResult(pagination, count()) +} diff --git a/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/onetomany/AbstractOneToManyExposedKeyValueRepo.kt b/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/onetomany/AbstractOneToManyExposedKeyValueRepo.kt new file mode 100644 index 00000000000..013d3edfc52 --- /dev/null +++ b/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/onetomany/AbstractOneToManyExposedKeyValueRepo.kt @@ -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( + keyColumnAllocator: ColumnAllocator, + valueColumnAllocator: ColumnAllocator, + database: Database +) : OneToManyKeyValueRepo, AbstractOneToManyExposedReadKeyValueRepo( + 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) } } + } +} diff --git a/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/onetomany/AbstractOneToManyExposedReadKeyValueRepo.kt b/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/onetomany/AbstractOneToManyExposedReadKeyValueRepo.kt new file mode 100644 index 00000000000..90434afbf10 --- /dev/null +++ b/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/onetomany/AbstractOneToManyExposedReadKeyValueRepo.kt @@ -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 = Table.() -> Column + +abstract class AbstractOneToManyExposedReadKeyValueRepo( + keyColumnAllocator: ColumnAllocator, + valueColumnAllocator: ColumnAllocator, + protected val database: Database +) : OneToManyReadKeyValueRepo, Table() { + protected val keyColumn: Column = keyColumnAllocator() + protected val valueColumn: Column = 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 = 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 = 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() + } +} diff --git a/repos/ktor/client/build.gradle b/repos/ktor/client/build.gradle new file mode 100644 index 00000000000..b96eda83744 --- /dev/null +++ b/repos/ktor/client/build.gradle @@ -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" + } + } + } +} diff --git a/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/crud/KtorReadStandardCrudRepo.kt b/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/crud/KtorReadStandardCrudRepo.kt new file mode 100644 index 00000000000..b36e4424fba --- /dev/null +++ b/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/crud/KtorReadStandardCrudRepo.kt @@ -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 ( + private val baseUrl: String, + private val client: HttpClient = HttpClient(), + private val objectsSerializer: KSerializer, + private val objectsSerializerNullable: KSerializer, + private val idsSerializer: KSerializer +) : ReadStandardCRUDRepo { + private val paginationResultSerializer = PaginationResult.serializer(objectsSerializer) + + override suspend fun getByPagination(pagination: Pagination): PaginationResult = 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() + ) +} diff --git a/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/crud/KtorStandardCrudRepo.kt b/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/crud/KtorStandardCrudRepo.kt new file mode 100644 index 00000000000..97d8a0abbab --- /dev/null +++ b/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/crud/KtorStandardCrudRepo.kt @@ -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 ( + baseUrl: String, + baseSubpart: String, + client: HttpClient, + objectsSerializer: KSerializer, + objectsNullableSerializer: KSerializer, + inputsSerializer: KSerializer, + idsSerializer: KSerializer +) : StandardCRUDRepo, + ReadStandardCRUDRepo by KtorReadStandardCrudRepo( + "$baseUrl/$baseSubpart", + client, + objectsSerializer, + objectsNullableSerializer, + idsSerializer + ), + WriteStandardCRUDRepo by KtorWriteStandardCrudRepo( + "$baseUrl/$baseSubpart", + client, + objectsSerializer, + objectsNullableSerializer, + inputsSerializer, + idsSerializer + ) diff --git a/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/crud/KtorWriteStandardCrudRepo.kt b/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/crud/KtorWriteStandardCrudRepo.kt new file mode 100644 index 00000000000..be78bd22db2 --- /dev/null +++ b/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/crud/KtorWriteStandardCrudRepo.kt @@ -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 ( + private val baseUrl: String, + private val client: HttpClient = HttpClient(), + private val objectsSerializer: KSerializer, + private val objectsNullableSerializer: KSerializer, + private val inputsSerializer: KSerializer, + private val idsSerializer: KSerializer +) : WriteStandardCRUDRepo { + 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 = client.createStandardWebsocketFlow( + buildStandardUrl(baseUrl, newObjectsFlowRouting), + deserializer = objectsSerializer + ) + override val updatedObjectsFlow: Flow = client.createStandardWebsocketFlow( + buildStandardUrl(baseUrl, updatedObjectsFlowRouting), + deserializer = objectsSerializer + ) + override val deletedObjectsIdsFlow: Flow = client.createStandardWebsocketFlow( + buildStandardUrl(baseUrl, deletedObjectsIdsFlowRouting), + deserializer = idsSerializer + ) + + + override suspend fun create(values: List): List = 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>): List = client.unipost( + buildStandardUrl(baseUrl, updateManyRouting), + BodyPair(listInputUpdateSerializer, values), + listObjectsSerializer + ) + + override suspend fun deleteById(ids: List) = client.unipost( + buildStandardUrl(baseUrl, deleteByIdRouting), + BodyPair(listIdsSerializer, ids), + Unit.serializer() + ) +} diff --git a/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/key_value/KtorStandartKeyValueRepo.kt b/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/key_value/KtorStandartKeyValueRepo.kt new file mode 100644 index 00000000000..d81700e52f9 --- /dev/null +++ b/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/key_value/KtorStandartKeyValueRepo.kt @@ -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 ( + baseUrl: String, + baseSubpart: String, + client: HttpClient = HttpClient(), + keySerializer: KSerializer, + valueSerializer: KSerializer, + valueNullableSerializer: KSerializer +) : StandardKeyValueRepo, + StandardReadKeyValueRepo by KtorStandartReadKeyValueRepo( + "$baseUrl/$baseSubpart", + client, + keySerializer, + valueSerializer, + valueNullableSerializer + ), + StandardWriteKeyValueRepo by KtorStandartWriteKeyValueRepo( + "$baseUrl/$baseSubpart", + client, + keySerializer, + valueSerializer + ) \ No newline at end of file diff --git a/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/key_value/KtorStandartReadKeyValueRepo.kt b/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/key_value/KtorStandartReadKeyValueRepo.kt new file mode 100644 index 00000000000..bf7c32759bf --- /dev/null +++ b/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/key_value/KtorStandartReadKeyValueRepo.kt @@ -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 ( + private var baseUrl: String, + private var client: HttpClient = HttpClient(), + private var keySerializer: KSerializer, + private var valueSerializer: KSerializer, + private var valueNullableSerializer: KSerializer, +) : StandardReadKeyValueRepo { + override suspend fun get(k: Key): Value? = client.uniget( + buildStandardUrl( + baseUrl, + getRoute, + mapOf( + keyParameterName to keySerializer.encodeUrlQueryValue(k) + ) + ), + valueNullableSerializer + ) + + override suspend fun values(pagination: Pagination, reversed: Boolean): PaginationResult = 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 = 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() + ) +} \ No newline at end of file diff --git a/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/key_value/KtorStandartWriteKeyValueRepo.kt b/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/key_value/KtorStandartWriteKeyValueRepo.kt new file mode 100644 index 00000000000..b7ad3c114c0 --- /dev/null +++ b/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/key_value/KtorStandartWriteKeyValueRepo.kt @@ -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 ( + private var baseUrl: String, + private var client: HttpClient = HttpClient(), + private var keySerializer: KSerializer, + private var valueSerializer: KSerializer, +) : StandardWriteKeyValueRepo { + override val onNewValue: Flow> = client.createStandardWebsocketFlow( + buildStandardUrl(baseUrl, onNewValueRoute), + deserializer = PairSerializer(keySerializer, valueSerializer) + ) + + override val onValueRemoved: Flow = client.createStandardWebsocketFlow( + buildStandardUrl(baseUrl, onValueRemovedRoute), + deserializer = keySerializer + ) + + override suspend fun set(k: K, v: V) = client.unipost( + buildStandardUrl( + baseUrl, + setRoute + ), + BodyPair(KeyValuePostObject.serializer(keySerializer, valueSerializer), KeyValuePostObject(k, v)), + Unit.serializer() + ) + + override suspend fun unset(k: K) = client.unipost( + buildStandardUrl( + baseUrl, + unsetRoute, + ), + BodyPair(keySerializer, k), + Unit.serializer() + ) +} \ No newline at end of file diff --git a/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/one_to_many/KtorOneToManyKeyValueRepo.kt b/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/one_to_many/KtorOneToManyKeyValueRepo.kt new file mode 100644 index 00000000000..d6107824816 --- /dev/null +++ b/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/one_to_many/KtorOneToManyKeyValueRepo.kt @@ -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( + baseUrl: String, + baseSubpart: String, + client: HttpClient, + keySerializer: KSerializer, + valueSerializer: KSerializer, +) : OneToManyKeyValueRepo, + OneToManyReadKeyValueRepo by KtorOneToManyReadKeyValueRepo ( + "$baseUrl/$baseSubpart", + client, + keySerializer, + valueSerializer, + ), + OneToManyWriteKeyValueRepo by KtorOneToManyWriteKeyValueRepo ( + "$baseUrl/$baseSubpart", + client, + keySerializer, + valueSerializer, + ) \ No newline at end of file diff --git a/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/one_to_many/KtorOneToManyReadKeyValueRepo.kt b/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/one_to_many/KtorOneToManyReadKeyValueRepo.kt new file mode 100644 index 00000000000..33e5cf05ee5 --- /dev/null +++ b/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/one_to_many/KtorOneToManyReadKeyValueRepo.kt @@ -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 ( + private val baseUrl: String, + private val client: HttpClient = HttpClient(), + private val keySerializer: KSerializer, + private val valueSerializer: KSerializer, +) : OneToManyReadKeyValueRepo { + private val paginationValueResultSerializer = PaginationResult.serializer(valueSerializer) + private val paginationKeyResultSerializer = PaginationResult.serializer(keySerializer) + + override suspend fun get(k: Key, pagination: Pagination, reversed: Boolean): PaginationResult = 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 = 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() + ) + +} \ No newline at end of file diff --git a/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/one_to_many/KtorOneToManyWriteKeyValueRepo.kt b/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/one_to_many/KtorOneToManyWriteKeyValueRepo.kt new file mode 100644 index 00000000000..7d6b8b69fc4 --- /dev/null +++ b/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/one_to_many/KtorOneToManyWriteKeyValueRepo.kt @@ -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 ( + private val baseUrl: String, + private val client: HttpClient = HttpClient(), + private val keySerializer: KSerializer, + private val valueSerializer: KSerializer, +) : OneToManyWriteKeyValueRepo { + 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(), + ) +} \ No newline at end of file diff --git a/repos/ktor/common/build.gradle b/repos/ktor/common/build.gradle new file mode 100644 index 00000000000..506faf0b021 --- /dev/null +++ b/repos/ktor/common/build.gradle @@ -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") + } + } + } +} diff --git a/repos/ktor/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/common/crud/CrudReadRoutes.kt b/repos/ktor/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/common/crud/CrudReadRoutes.kt new file mode 100644 index 00000000000..dc44163c26e --- /dev/null +++ b/repos/ktor/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/common/crud/CrudReadRoutes.kt @@ -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" diff --git a/repos/ktor/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/common/crud/CrudWriteRoutes.kt b/repos/ktor/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/common/crud/CrudWriteRoutes.kt new file mode 100644 index 00000000000..f138429fd3a --- /dev/null +++ b/repos/ktor/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/common/crud/CrudWriteRoutes.kt @@ -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" diff --git a/repos/ktor/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/common/key_value/KeyValueParameterNames.kt b/repos/ktor/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/common/key_value/KeyValueParameterNames.kt new file mode 100644 index 00000000000..d0b168a7bcb --- /dev/null +++ b/repos/ktor/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/common/key_value/KeyValueParameterNames.kt @@ -0,0 +1,4 @@ +package dev.inmo.micro_utils.repos.ktor.common.key_value + +const val keyParameterName = "key" +const val reversedParameterName = "reversed" \ No newline at end of file diff --git a/repos/ktor/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/common/key_value/KeyValuePostObject.kt b/repos/ktor/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/common/key_value/KeyValuePostObject.kt new file mode 100644 index 00000000000..77739fc2e87 --- /dev/null +++ b/repos/ktor/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/common/key_value/KeyValuePostObject.kt @@ -0,0 +1,9 @@ +package dev.inmo.micro_utils.repos.ktor.common.key_value + +import kotlinx.serialization.Serializable + +@Serializable +data class KeyValuePostObject ( + val key: K, + val value: V, +) \ No newline at end of file diff --git a/repos/ktor/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/common/key_value/KeyValueRoutes.kt b/repos/ktor/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/common/key_value/KeyValueRoutes.kt new file mode 100644 index 00000000000..77b32a459ad --- /dev/null +++ b/repos/ktor/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/common/key_value/KeyValueRoutes.kt @@ -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" \ No newline at end of file diff --git a/repos/ktor/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/common/one_to_many/OneToManyParametersNames.kt b/repos/ktor/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/common/one_to_many/OneToManyParametersNames.kt new file mode 100644 index 00000000000..c8f8b2ea7eb --- /dev/null +++ b/repos/ktor/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/common/one_to_many/OneToManyParametersNames.kt @@ -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" \ No newline at end of file diff --git a/repos/ktor/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/common/one_to_many/OneToManyRoutes.kt b/repos/ktor/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/common/one_to_many/OneToManyRoutes.kt new file mode 100644 index 00000000000..ed56f7ced53 --- /dev/null +++ b/repos/ktor/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/common/one_to_many/OneToManyRoutes.kt @@ -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" \ No newline at end of file diff --git a/repos/ktor/server/build.gradle b/repos/ktor/server/build.gradle new file mode 100644 index 00000000000..ebcb40ce03d --- /dev/null +++ b/repos/ktor/server/build.gradle @@ -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" + } + } + } +} diff --git a/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/crud/KtorReadStandardCrudRepo.kt b/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/crud/KtorReadStandardCrudRepo.kt new file mode 100644 index 00000000000..0c74ddd8e23 --- /dev/null +++ b/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/crud/KtorReadStandardCrudRepo.kt @@ -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 Route.configureReadStandardCrudRepoRoutes( + originalRepo: ReadStandardCRUDRepo, + objectsSerializer: KSerializer, + objectsNullableSerializer: KSerializer, + idsSerializer: KSerializer +) { + 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) + ) + } +} diff --git a/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/crud/KtorStandardCrudRepo.kt b/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/crud/KtorStandardCrudRepo.kt new file mode 100644 index 00000000000..f619b9da745 --- /dev/null +++ b/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/crud/KtorStandardCrudRepo.kt @@ -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 Route.configureStandardCrudRepoRoutes( + baseSubpart: String, + originalRepo: StandardCRUDRepo, + objectsSerializer: KSerializer, + objectsNullableSerializer: KSerializer, + inputsSerializer: KSerializer, + idsSerializer: KSerializer +) { + route(baseSubpart) { + configureReadStandardCrudRepoRoutes(originalRepo, objectsSerializer, objectsNullableSerializer, idsSerializer) + configureWriteStandardCrudRepoRoutes(originalRepo, objectsSerializer, objectsNullableSerializer, inputsSerializer, idsSerializer) + } +} diff --git a/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/crud/KtorWriteStandardCrudRepo.kt b/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/crud/KtorWriteStandardCrudRepo.kt new file mode 100644 index 00000000000..4b393163609 --- /dev/null +++ b/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/crud/KtorWriteStandardCrudRepo.kt @@ -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 Route.configureWriteStandardCrudRepoRoutes( + originalRepo: WriteStandardCRUDRepo, + objectsSerializer: KSerializer, + objectsNullableSerializer: KSerializer, + inputsSerializer: KSerializer, + idsSerializer: KSerializer +) { + 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 + ) + ) + } +} diff --git a/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/key_value/KtorStandartKeyValueRepo.kt b/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/key_value/KtorStandartKeyValueRepo.kt new file mode 100644 index 00000000000..a4e22e915e7 --- /dev/null +++ b/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/key_value/KtorStandartKeyValueRepo.kt @@ -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 Route.configureStandartKeyValueRepoRoutes( + baseSubpart: String, + originalRepo: StandardKeyValueRepo, + keySerializer: KSerializer, + valueSerializer: KSerializer, + valueNullableSerializer: KSerializer, +) { + route(baseSubpart) { + configureReadStandartKeyValueRepoRoutes( + originalRepo, + keySerializer, + valueSerializer, + valueNullableSerializer, + ) + configureWriteStandartKeyValueRepoRoutes( + originalRepo, + keySerializer, + valueSerializer, + ) + } +} \ No newline at end of file diff --git a/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/key_value/KtorStandartReadKeyValueRepo.kt b/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/key_value/KtorStandartReadKeyValueRepo.kt new file mode 100644 index 00000000000..a0d66c1a967 --- /dev/null +++ b/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/key_value/KtorStandartReadKeyValueRepo.kt @@ -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 Route.configureReadStandartKeyValueRepoRoutes ( + originalRepo: StandardReadKeyValueRepo, + keySerializer: KSerializer, + valueSerializer: KSerializer, + valueNullableSerializer: KSerializer, +) { + 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() + ) + } +} \ No newline at end of file diff --git a/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/key_value/KtorStandartWriteKeyValueRepo.kt b/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/key_value/KtorStandartWriteKeyValueRepo.kt new file mode 100644 index 00000000000..ff043aaaa24 --- /dev/null +++ b/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/key_value/KtorStandartWriteKeyValueRepo.kt @@ -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 Route.configureWriteStandartKeyValueRepoRoutes ( + originalRepo: StandardWriteKeyValueRepo, + keySerializer: KSerializer, + valueSerializer: KSerializer, +) { + includeWebsocketHandling( + onNewValueRoute, + originalRepo.onNewValue, + PairSerializer(keySerializer, valueSerializer) + ) + + includeWebsocketHandling( + onValueRemovedRoute, + originalRepo.onValueRemoved, + keySerializer + ) + + post(setRoute) { + val (key, value) = call.uniload( + KeyValuePostObject.serializer(keySerializer, valueSerializer) + ) + + originalRepo.set(key, value) + } + + post(unsetRoute) { + val key = call.uniload( + keySerializer + ) + + originalRepo.unset(key) + } +} \ No newline at end of file diff --git a/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/one_to_many/ConfigureOneToManyKeyValueRepoRoutes.kt b/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/one_to_many/ConfigureOneToManyKeyValueRepoRoutes.kt new file mode 100644 index 00000000000..c17599baa2b --- /dev/null +++ b/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/one_to_many/ConfigureOneToManyKeyValueRepoRoutes.kt @@ -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 Route.configureOneToManyKeyValueRepoRoutes( + baseSubpart: String, + originalRepo: OneToManyKeyValueRepo, + keySerializer: KSerializer, + valueSealizer: KSerializer, +) { + route(baseSubpart) { + configureOneToManyReadKeyValueRepoRoutes(originalRepo, keySerializer, valueSealizer) + configureOneToManyWriteKeyValueRepoRoutes(originalRepo, keySerializer, valueSealizer) + } +} \ No newline at end of file diff --git a/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/one_to_many/ConfigureOneToManyReadKeyValueRepoRoutes.kt b/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/one_to_many/ConfigureOneToManyReadKeyValueRepoRoutes.kt new file mode 100644 index 00000000000..4a5a40075ea --- /dev/null +++ b/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/one_to_many/ConfigureOneToManyReadKeyValueRepoRoutes.kt @@ -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 Route.configureOneToManyReadKeyValueRepoRoutes( + originalRepo: OneToManyReadKeyValueRepo, + keySerializer: KSerializer, + valueSealizer: KSerializer, +) { + 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() + ) + } +} \ No newline at end of file diff --git a/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/one_to_many/ConfigureOneToManyWriteKeyValueRepoRoutes.kt b/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/one_to_many/ConfigureOneToManyWriteKeyValueRepoRoutes.kt new file mode 100644 index 00000000000..9ef1ada0a3b --- /dev/null +++ b/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/one_to_many/ConfigureOneToManyWriteKeyValueRepoRoutes.kt @@ -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 Route.configureOneToManyWriteKeyValueRepoRoutes( + originalRepo: OneToManyWriteKeyValueRepo, + keySerializer: KSerializer, + valueSealizer: KSerializer, +) { + 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), + ) + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index ec72891f7d1..a114ba3ac77 100644 --- a/settings.gradle +++ b/settings.gradle @@ -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", ]