add crud repo server and change a lot of different things
This commit is contained in:
parent
14d6915282
commit
b94417b77d
@ -4,7 +4,6 @@ import com.insanusmokrassar.postssystem.core.content.*
|
||||
import com.insanusmokrassar.postssystem.core.content.api.WriteContentRepo
|
||||
import com.insanusmokrassar.postssystem.core.ktor.*
|
||||
import com.insanusmokrassar.postssystem.ktor.client.*
|
||||
import com.insanusmokrassar.postssystem.ktor.standardKtorSerialFormat
|
||||
import io.ktor.client.HttpClient
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.serialization.builtins.nullable
|
||||
@ -15,16 +14,14 @@ class WriteContentRepoKtorClient(
|
||||
private val client: HttpClient = HttpClient()
|
||||
) : WriteContentRepo {
|
||||
override val contentCreatedFlow: Flow<RegisteredContent> = client.createStandardWebsocketFlow(
|
||||
"$baseUrl/$contentCreatedFlowRoute"
|
||||
) {
|
||||
standardKtorSerialFormat.decodeFromByteArray(RegisteredContent.serializer(), it)
|
||||
}
|
||||
"$baseUrl/$contentCreatedFlowRoute",
|
||||
deserializer = RegisteredContent.serializer()
|
||||
)
|
||||
|
||||
override val contentDeletedFlow: Flow<RegisteredContent> = client.createStandardWebsocketFlow(
|
||||
"$baseUrl/$contentDeletedFlowRoute"
|
||||
) {
|
||||
standardKtorSerialFormat.decodeFromByteArray(RegisteredContent.serializer(), it)
|
||||
}
|
||||
"$baseUrl/$contentDeletedFlowRoute",
|
||||
deserializer = RegisteredContent.serializer()
|
||||
)
|
||||
|
||||
override suspend fun registerContent(content: Content): RegisteredContent? = client.unipost(
|
||||
"$baseUrl/$registerContentRoute",
|
||||
|
@ -4,7 +4,6 @@ import com.insanusmokrassar.postssystem.core.ktor.*
|
||||
import com.insanusmokrassar.postssystem.core.post.*
|
||||
import com.insanusmokrassar.postssystem.core.post.repo.WritePostsRepo
|
||||
import com.insanusmokrassar.postssystem.ktor.client.*
|
||||
import com.insanusmokrassar.postssystem.ktor.standardKtorSerialFormat
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.features.websocket.WebSockets
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
@ -18,20 +17,17 @@ class WritePostsRepoKtorClient (
|
||||
}
|
||||
) : WritePostsRepo {
|
||||
override val postCreatedFlow: Flow<RegisteredPost> = client.createStandardWebsocketFlow(
|
||||
"$baseUrl/$postCreatedFlowRoute"
|
||||
) {
|
||||
standardKtorSerialFormat.decodeFromByteArray(RegisteredPost.serializer(), it)
|
||||
}
|
||||
"$baseUrl/$postCreatedFlowRoute",
|
||||
deserializer = RegisteredPost.serializer()
|
||||
)
|
||||
override val postDeletedFlow: Flow<RegisteredPost> = client.createStandardWebsocketFlow(
|
||||
"$baseUrl/$postDeletedFlowRoute"
|
||||
) {
|
||||
standardKtorSerialFormat.decodeFromByteArray(RegisteredPost.serializer(), it)
|
||||
}
|
||||
"$baseUrl/$postDeletedFlowRoute",
|
||||
deserializer = RegisteredPost.serializer()
|
||||
)
|
||||
override val postUpdatedFlow: Flow<RegisteredPost> = client.createStandardWebsocketFlow(
|
||||
"$baseUrl/$postUpdatedFlowRoute"
|
||||
) {
|
||||
standardKtorSerialFormat.decodeFromByteArray(RegisteredPost.serializer(), it)
|
||||
}
|
||||
"$baseUrl/$postUpdatedFlowRoute",
|
||||
deserializer = RegisteredPost.serializer()
|
||||
)
|
||||
|
||||
override suspend fun createPost(post: Post): RegisteredPost? = client.unipost(
|
||||
"$baseUrl/$createPostRoute",
|
||||
|
@ -15,12 +15,8 @@ import kotlinx.serialization.builtins.serializer
|
||||
fun Route.configureWriteContentRepoRoutes(
|
||||
proxyTo: WriteContentRepo
|
||||
) {
|
||||
includeWebsocketHandling(contentCreatedFlowRoute, proxyTo.contentCreatedFlow) {
|
||||
standardKtorSerialFormat.encodeToByteArray(RegisteredContent.serializer(), it)
|
||||
}
|
||||
includeWebsocketHandling(contentDeletedFlowRoute, proxyTo.contentDeletedFlow) {
|
||||
standardKtorSerialFormat.encodeToByteArray(RegisteredContent.serializer(), it)
|
||||
}
|
||||
includeWebsocketHandling(contentCreatedFlowRoute, proxyTo.contentCreatedFlow, RegisteredContent.serializer())
|
||||
includeWebsocketHandling(contentDeletedFlowRoute, proxyTo.contentDeletedFlow, RegisteredContent.serializer())
|
||||
post(registerContentRoute) {
|
||||
val content = call.uniload(Content.serializer())
|
||||
val registered = proxyTo.registerContent(content)
|
||||
|
@ -15,15 +15,9 @@ import kotlinx.serialization.builtins.serializer
|
||||
fun Route.configureWritePostsRepoRoutes(
|
||||
proxyTo: WritePostsRepo
|
||||
) {
|
||||
includeWebsocketHandling(postCreatedFlowRoute, proxyTo.postCreatedFlow) {
|
||||
standardKtorSerialFormat.encodeToByteArray(RegisteredPost.serializer(), it)
|
||||
}
|
||||
includeWebsocketHandling(postDeletedFlowRoute, proxyTo.postDeletedFlow) {
|
||||
standardKtorSerialFormat.encodeToByteArray(RegisteredPost.serializer(), it)
|
||||
}
|
||||
includeWebsocketHandling(postUpdatedFlowRoute, proxyTo.postUpdatedFlow) {
|
||||
standardKtorSerialFormat.encodeToByteArray(RegisteredPost.serializer(), it)
|
||||
}
|
||||
includeWebsocketHandling(postCreatedFlowRoute, proxyTo.postCreatedFlow, RegisteredPost.serializer())
|
||||
includeWebsocketHandling(postDeletedFlowRoute, proxyTo.postDeletedFlow, RegisteredPost.serializer())
|
||||
includeWebsocketHandling(postUpdatedFlowRoute, proxyTo.postUpdatedFlow, RegisteredPost.serializer())
|
||||
|
||||
post(createPostRoute) {
|
||||
call.unianswer(
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.insanusmokrassar.postssystem.ktor.client
|
||||
|
||||
import com.insanusmokrassar.postssystem.ktor.asCorrectWebSocketUrl
|
||||
import com.insanusmokrassar.postssystem.ktor.standardKtorSerialFormat
|
||||
import com.insanusmokrassar.postssystem.utils.common.safely
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.features.websocket.ws
|
||||
@ -8,6 +9,7 @@ import io.ktor.http.cio.websocket.Frame
|
||||
import io.ktor.http.cio.websocket.readBytes
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.channelFlow
|
||||
import kotlinx.serialization.DeserializationStrategy
|
||||
|
||||
/**
|
||||
* @param checkReconnection This lambda will be called when it is required to reconnect to websocket to establish
|
||||
@ -63,3 +65,19 @@ inline fun <T> HttpClient.createStandardWebsocketFlow(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param checkReconnection This lambda will be called when it is required to reconnect to websocket to establish
|
||||
* connection. Must return true in case if must be reconnected. By default always reconnecting
|
||||
*/
|
||||
inline fun <T> HttpClient.createStandardWebsocketFlow(
|
||||
url: String,
|
||||
crossinline checkReconnection: (Throwable?) -> Boolean = { true },
|
||||
deserializer: DeserializationStrategy<T>
|
||||
) = createStandardWebsocketFlow(
|
||||
url,
|
||||
checkReconnection
|
||||
) {
|
||||
standardKtorSerialFormat.decodeFromByteArray(deserializer, it)
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,15 @@
|
||||
package com.insanusmokrassar.postssystem.ktor.server
|
||||
|
||||
import com.insanusmokrassar.postssystem.ktor.CorrectCloseException
|
||||
import com.insanusmokrassar.postssystem.ktor.standardKtorSerialFormat
|
||||
import com.insanusmokrassar.postssystem.utils.common.safely
|
||||
import io.ktor.http.cio.websocket.*
|
||||
import io.ktor.routing.Route
|
||||
import io.ktor.websocket.webSocket
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.serialization.DeserializationStrategy
|
||||
import kotlinx.serialization.SerializationStrategy
|
||||
|
||||
private suspend fun DefaultWebSocketSession.checkReceivedAndCloseIfExists() {
|
||||
if (incoming.poll() != null) {
|
||||
@ -29,3 +32,14 @@ fun <T> Route.includeWebsocketHandling(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> Route.includeWebsocketHandling(
|
||||
suburl: String,
|
||||
flow: Flow<T>,
|
||||
serializer: SerializationStrategy<T>
|
||||
) = includeWebsocketHandling(
|
||||
suburl,
|
||||
flow
|
||||
) {
|
||||
standardKtorSerialFormat.encodeToByteArray(serializer, it)
|
||||
}
|
||||
|
@ -30,6 +30,14 @@ suspend fun ApplicationCall.getParameterOrSendError(
|
||||
field: String
|
||||
) = parameters[field].also {
|
||||
if (it == null) {
|
||||
respond(HttpStatusCode.BadRequest, "request must contains $field")
|
||||
respond(HttpStatusCode.BadRequest, "Request must contains $field")
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun ApplicationCall.getQueryParameterOrSendError(
|
||||
field: String
|
||||
) = request.queryParameters[field].also {
|
||||
if (it == null) {
|
||||
respond(HttpStatusCode.BadRequest, "Request query parametersmust contains $field")
|
||||
}
|
||||
}
|
||||
|
@ -27,9 +27,7 @@ class WebsocketsTest {
|
||||
val server = createKtorServer(host = "127.0.0.1", port = port) {
|
||||
install(WebSockets)
|
||||
routing {
|
||||
includeWebsocketHandling(suburl, dataFlow) {
|
||||
standardKtorSerialFormat.encodeToByteArray(Int.serializer(), it)
|
||||
}
|
||||
includeWebsocketHandling(suburl, dataFlow, Int.serializer())
|
||||
}
|
||||
}.also {
|
||||
it.start(false)
|
||||
@ -42,10 +40,9 @@ class WebsocketsTest {
|
||||
}
|
||||
val incomingWebsocketFlow = client.createStandardWebsocketFlow(
|
||||
"$serverUrl/$suburl",
|
||||
{ false } // always skip reconnection
|
||||
) {
|
||||
standardKtorSerialFormat.decodeFromByteArray(Int.serializer(), it)
|
||||
}
|
||||
{ false }, // always skip reconnection
|
||||
deserializer = Int.serializer()
|
||||
)
|
||||
|
||||
var currentlyCheckingData: Int? = null
|
||||
incomingWebsocketFlow.onEach {
|
||||
|
@ -6,6 +6,7 @@ String[] includes = [
|
||||
':utils:repos:common',
|
||||
':utils:repos:ktor:common',
|
||||
':utils:repos:ktor:client',
|
||||
':utils:repos:ktor:server',
|
||||
':utils:repos:exposed',
|
||||
|
||||
':exposed:commons',
|
||||
|
@ -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')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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)
|
||||
)
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
@ -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
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user