add crud repo server and change a lot of different things
This commit is contained in:
core/ktor
client
src
commonMain
kotlin
com
insanusmokrassar
postssystem
core
ktor
client
server
src
main
kotlin
com
insanusmokrassar
postssystem
core
ktor
ktor
client
src
commonMain
kotlin
com
insanusmokrassar
postssystem
ktor
client
server
src
jvmMain
kotlin
com
insanusmokrassar
postssystem
tests
src
test
kotlin
com
insanusmokrassar
postssystem
ktor
tests
utils/repos
common
src
commonMain
kotlin
com
insanusmokrassar
postssystem
utils
repos
exposed
src
main
kotlin
com
insanusmokrassar
postssystem
utils
repos
ktor
client
src
commonMain
kotlin
com
insanusmokrassar
postssystem
utils
repos
ktor
server
@ -21,11 +21,21 @@ interface WriteStandardCRUDRepo<ObjectType, IdType, InputValueType> : Repo {
|
||||
val updatedObjectsFlow: Flow<ObjectType>
|
||||
val deletedObjectsIdsFlow: Flow<IdType>
|
||||
|
||||
suspend fun create(vararg values: InputValueType): List<ObjectType>
|
||||
suspend fun create(values: List<InputValueType>): List<ObjectType>
|
||||
suspend fun update(id: IdType, value: InputValueType): ObjectType?
|
||||
suspend fun update(vararg values: UpdatedValuePair<IdType, InputValueType>): List<ObjectType>
|
||||
suspend fun deleteById(vararg ids: IdType)
|
||||
suspend fun update(values: List<UpdatedValuePair<IdType, InputValueType>>): List<ObjectType>
|
||||
suspend fun deleteById(ids: List<IdType>)
|
||||
}
|
||||
|
||||
suspend fun <ObjectType, IdType, InputValueType> WriteStandardCRUDRepo<ObjectType, IdType, InputValueType>.create(
|
||||
vararg values: InputValueType
|
||||
): List<ObjectType> = create(values.toList())
|
||||
suspend fun <ObjectType, IdType, InputValueType> WriteStandardCRUDRepo<ObjectType, IdType, InputValueType>.update(
|
||||
vararg values: UpdatedValuePair<IdType, InputValueType>
|
||||
): List<ObjectType> = update(values.toList())
|
||||
suspend fun <ObjectType, IdType, InputValueType> WriteStandardCRUDRepo<ObjectType, IdType, InputValueType>.deleteById(
|
||||
vararg ids: IdType
|
||||
) = deleteById(ids.toList())
|
||||
|
||||
interface StandardCRUDRepo<ObjectType, IdType, InputValueType> : ReadStandardCRUDRepo<ObjectType, IdType>,
|
||||
WriteStandardCRUDRepo<ObjectType, IdType, InputValueType>
|
||||
|
@ -27,20 +27,20 @@ abstract class AbstractExposedWriteCRUDRepo<ObjectType, IdType, InputValueType>(
|
||||
override val deletedObjectsIdsFlow: Flow<IdType> = deleteObjectsIdsChannel.asFlow()
|
||||
|
||||
abstract val InsertStatement<Number>.asObject: ObjectType
|
||||
abstract val selectByIds: SqlExpressionBuilder.(Array<out IdType>) -> Op<Boolean>
|
||||
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(vararg value: InputValueType) {}
|
||||
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(vararg values: InputValueType): List<ObjectType> {
|
||||
onBeforeCreate(*values)
|
||||
override suspend fun create(values: List<InputValueType>): List<ObjectType> {
|
||||
onBeforeCreate(values)
|
||||
return transaction(db = database) {
|
||||
values.map { value -> createWithoutNotification(value) }
|
||||
}.also {
|
||||
@ -50,7 +50,7 @@ abstract class AbstractExposedWriteCRUDRepo<ObjectType, IdType, InputValueType>(
|
||||
}
|
||||
}
|
||||
|
||||
protected open suspend fun onBeforeUpdate(vararg value: UpdatedValuePair<IdType, InputValueType>) {}
|
||||
protected open suspend fun onBeforeUpdate(value: List<UpdatedValuePair<IdType, InputValueType>>) {}
|
||||
private fun updateWithoutNotification(id: IdType, value: InputValueType): ObjectType? {
|
||||
return transaction(db = database) {
|
||||
update(
|
||||
@ -72,15 +72,15 @@ abstract class AbstractExposedWriteCRUDRepo<ObjectType, IdType, InputValueType>(
|
||||
}
|
||||
|
||||
override suspend fun update(id: IdType, value: InputValueType): ObjectType? {
|
||||
onBeforeUpdate(id to value)
|
||||
onBeforeUpdate(listOf(id to value))
|
||||
return updateWithoutNotification(id, value).also {
|
||||
if (it != null) {
|
||||
updateObjectsChannel.send(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
override suspend fun update(vararg values: UpdatedValuePair<IdType, InputValueType>): List<ObjectType> {
|
||||
onBeforeUpdate(*values)
|
||||
override suspend fun update(values: List<UpdatedValuePair<IdType, InputValueType>>): List<ObjectType> {
|
||||
onBeforeUpdate(values)
|
||||
return (
|
||||
transaction(db = database) {
|
||||
values.map { (id, value) -> updateWithoutNotification(id, value) }
|
||||
@ -93,9 +93,9 @@ abstract class AbstractExposedWriteCRUDRepo<ObjectType, IdType, InputValueType>(
|
||||
}
|
||||
}
|
||||
}
|
||||
protected open suspend fun onBeforeDelete(vararg ids: IdType) {}
|
||||
override suspend fun deleteById(vararg ids: IdType) {
|
||||
onBeforeDelete(*ids)
|
||||
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)
|
||||
|
@ -2,15 +2,12 @@ package com.insanusmokrassar.postssystem.utils.repos.ktor.client
|
||||
|
||||
import com.insanusmokrassar.postssystem.ktor.*
|
||||
import com.insanusmokrassar.postssystem.ktor.client.*
|
||||
import com.insanusmokrassar.postssystem.utils.common.pagination.Pagination
|
||||
import com.insanusmokrassar.postssystem.utils.common.pagination.PaginationResult
|
||||
import com.insanusmokrassar.postssystem.utils.repos.*
|
||||
import com.insanusmokrassar.postssystem.utils.repos.ktor.common.*
|
||||
import io.ktor.client.HttpClient
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.builtins.*
|
||||
import kotlinx.serialization.encodeToHexString
|
||||
|
||||
class KtorWriteStandardCrudRepo<ObjectType, IdType, InputValue> (
|
||||
private val baseUrl: String,
|
||||
@ -23,45 +20,47 @@ class KtorWriteStandardCrudRepo<ObjectType, IdType, InputValue> (
|
||||
private val listObjectsSerializer = ListSerializer(objectsSerializer)
|
||||
private val listInputSerializer = ListSerializer(inputsSerializer)
|
||||
private val listIdsSerializer = ListSerializer(idsSerializer)
|
||||
private val inputUpdateSerializer = TemporalInputObjectForUpdate.serializer(
|
||||
private val inputUpdateSerializer = PairSerializer(
|
||||
idsSerializer,
|
||||
inputsSerializer
|
||||
)
|
||||
private val listInputUpdateSerializer = ListSerializer(inputUpdateSerializer)
|
||||
|
||||
override val newObjectsFlow: Flow<ObjectType> = client.createStandardWebsocketFlow(
|
||||
buildStandardUrl(baseUrl, newObjectsFlowRouting)
|
||||
) { standardKtorSerialFormat.decodeFromByteArray(objectsSerializer, it) }
|
||||
buildStandardUrl(baseUrl, newObjectsFlowRouting),
|
||||
deserializer = objectsSerializer
|
||||
)
|
||||
override val updatedObjectsFlow: Flow<ObjectType> = client.createStandardWebsocketFlow(
|
||||
buildStandardUrl(baseUrl, updatedObjectsFlowRouting)
|
||||
) { standardKtorSerialFormat.decodeFromByteArray(objectsSerializer, it) }
|
||||
buildStandardUrl(baseUrl, updatedObjectsFlowRouting),
|
||||
deserializer = objectsSerializer
|
||||
)
|
||||
override val deletedObjectsIdsFlow: Flow<IdType> = client.createStandardWebsocketFlow(
|
||||
buildStandardUrl(baseUrl, deletedObjectsIdsFlowRouting)
|
||||
) { standardKtorSerialFormat.decodeFromByteArray(idsSerializer, it) }
|
||||
buildStandardUrl(baseUrl, deletedObjectsIdsFlowRouting),
|
||||
deserializer = idsSerializer
|
||||
)
|
||||
|
||||
|
||||
|
||||
override suspend fun create(vararg values: InputValue): List<ObjectType> = client.unipost(
|
||||
override suspend fun create(values: List<InputValue>): List<ObjectType> = client.unipost(
|
||||
buildStandardUrl(baseUrl, createRouting),
|
||||
BodyPair(listInputSerializer, values.toList()),
|
||||
BodyPair(listInputSerializer, values),
|
||||
listObjectsSerializer
|
||||
)
|
||||
|
||||
override suspend fun update(id: IdType, value: InputValue): ObjectType? = client.unipost(
|
||||
buildStandardUrl(baseUrl, updateRouting),
|
||||
BodyPair(inputUpdateSerializer, TemporalInputObjectForUpdate(id, value)),
|
||||
BodyPair(inputUpdateSerializer, id to value),
|
||||
objectsNullableSerializer
|
||||
)
|
||||
|
||||
override suspend fun update(vararg values: UpdatedValuePair<IdType, InputValue>): List<ObjectType> = client.unipost(
|
||||
override suspend fun update(values: List<UpdatedValuePair<IdType, InputValue>>): List<ObjectType> = client.unipost(
|
||||
buildStandardUrl(baseUrl, updateManyRouting),
|
||||
BodyPair(listInputUpdateSerializer, values.map { TemporalInputObjectForUpdate(it.first, it.second) }),
|
||||
BodyPair(listInputUpdateSerializer, values),
|
||||
listObjectsSerializer
|
||||
)
|
||||
|
||||
override suspend fun deleteById(vararg ids: IdType) = client.unipost(
|
||||
override suspend fun deleteById(ids: List<IdType>) = client.unipost(
|
||||
buildStandardUrl(baseUrl, deleteByIdRouting),
|
||||
BodyPair(listIdsSerializer, ids.toList()),
|
||||
BodyPair(listIdsSerializer, ids),
|
||||
Unit.serializer()
|
||||
)
|
||||
}
|
||||
|
64
utils/repos/ktor/server/build.gradle
Normal file
64
utils/repos/ktor/server/build.gradle
Normal file
@ -0,0 +1,64 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
|
||||
classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:$gradle_bintray_plugin_version"
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
id "org.jetbrains.kotlin.multiplatform" version "$kotlin_version"
|
||||
id "org.jetbrains.kotlin.plugin.serialization" version "$kotlin_version"
|
||||
}
|
||||
|
||||
project.version = "$core_version"
|
||||
project.group = "com.insanusmokrassar"
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
maven { url "https://kotlin.bintray.com/kotlinx" }
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvm()
|
||||
|
||||
sourceSets {
|
||||
commonMain {
|
||||
dependencies {
|
||||
implementation kotlin('stdlib')
|
||||
api "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines_version"
|
||||
|
||||
api projectByName("postssystem.utils.repos.ktor.common")
|
||||
api projectByName("postssystem.ktor.server")
|
||||
}
|
||||
}
|
||||
commonTest {
|
||||
dependencies {
|
||||
implementation kotlin('test-common')
|
||||
implementation kotlin('test-annotations-common')
|
||||
}
|
||||
}
|
||||
|
||||
jvmMain {
|
||||
dependencies {
|
||||
api "io.ktor:ktor-server:$ktor_version"
|
||||
api "io.ktor:ktor-server-host-common:$ktor_version"
|
||||
api "io.ktor:ktor-server-netty:$ktor_version"
|
||||
api "io.ktor:ktor-websockets:$ktor_version"
|
||||
}
|
||||
}
|
||||
jvmTest {
|
||||
dependencies {
|
||||
implementation kotlin('test-junit')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
55
utils/repos/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/server/KtorReadStandardCrudRepo.kt
Normal file
55
utils/repos/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/server/KtorReadStandardCrudRepo.kt
Normal file
@ -0,0 +1,55 @@
|
||||
package com.insanusmokrassar.postssystem.utils.repos.ktor.server
|
||||
|
||||
import com.insanusmokrassar.postssystem.ktor.server.*
|
||||
import com.insanusmokrassar.postssystem.ktor.standardKtorSerialFormat
|
||||
import com.insanusmokrassar.postssystem.utils.common.pagination.PaginationResult
|
||||
import com.insanusmokrassar.postssystem.utils.repos.ReadStandardCRUDRepo
|
||||
import com.insanusmokrassar.postssystem.utils.repos.ktor.common.*
|
||||
import io.ktor.application.call
|
||||
import io.ktor.routing.Route
|
||||
import io.ktor.routing.get
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
import kotlinx.serialization.decodeFromHexString
|
||||
|
||||
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 = standardKtorSerialFormat.decodeFromHexString(
|
||||
idsSerializer,
|
||||
call.getQueryParameterOrSendError("id") ?: return@get
|
||||
)
|
||||
|
||||
call.unianswer(
|
||||
objectsNullableSerializer,
|
||||
originalRepo.getById(id)
|
||||
)
|
||||
}
|
||||
|
||||
get(containsRouting) {
|
||||
val id = standardKtorSerialFormat.decodeFromHexString(
|
||||
idsSerializer,
|
||||
call.getQueryParameterOrSendError("id") ?: return@get
|
||||
)
|
||||
|
||||
call.unianswer(
|
||||
Boolean.serializer(),
|
||||
originalRepo.contains(id)
|
||||
)
|
||||
}
|
||||
}
|
27
utils/repos/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/server/KtorStandardCrudRepo.kt
Normal file
27
utils/repos/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/server/KtorStandardCrudRepo.kt
Normal file
@ -0,0 +1,27 @@
|
||||
package com.insanusmokrassar.postssystem.utils.repos.ktor.server
|
||||
|
||||
import com.insanusmokrassar.postssystem.ktor.server.*
|
||||
import com.insanusmokrassar.postssystem.ktor.standardKtorSerialFormat
|
||||
import com.insanusmokrassar.postssystem.utils.common.pagination.PaginationResult
|
||||
import com.insanusmokrassar.postssystem.utils.repos.*
|
||||
import com.insanusmokrassar.postssystem.utils.repos.ktor.common.*
|
||||
import io.ktor.application.call
|
||||
import io.ktor.routing.*
|
||||
import io.ktor.routing.get
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.builtins.*
|
||||
import kotlinx.serialization.decodeFromHexString
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
86
utils/repos/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/server/KtorWriteStandardCrudRepo.kt
Normal file
86
utils/repos/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/utils/repos/ktor/server/KtorWriteStandardCrudRepo.kt
Normal file
@ -0,0 +1,86 @@
|
||||
package com.insanusmokrassar.postssystem.utils.repos.ktor.server
|
||||
|
||||
import com.insanusmokrassar.postssystem.ktor.server.*
|
||||
import com.insanusmokrassar.postssystem.ktor.standardKtorSerialFormat
|
||||
import com.insanusmokrassar.postssystem.utils.common.pagination.PaginationResult
|
||||
import com.insanusmokrassar.postssystem.utils.repos.ReadStandardCRUDRepo
|
||||
import com.insanusmokrassar.postssystem.utils.repos.WriteStandardCRUDRepo
|
||||
import com.insanusmokrassar.postssystem.utils.repos.ktor.common.*
|
||||
import io.ktor.application.call
|
||||
import io.ktor.routing.*
|
||||
import io.ktor.routing.get
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.builtins.*
|
||||
import kotlinx.serialization.decodeFromHexString
|
||||
|
||||
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
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user