mirror of
https://github.com/InsanusMokrassar/MicroUtils.git
synced 2024-12-22 16:47:15 +00:00
add new started clients for crud
This commit is contained in:
parent
8eed435302
commit
bcb0e42fa2
@ -9,6 +9,7 @@ import io.ktor.client.plugins.websocket.*
|
||||
import io.ktor.client.request.HttpRequestBuilder
|
||||
import io.ktor.websocket.Frame
|
||||
import io.ktor.websocket.readBytes
|
||||
import io.ktor.websocket.serialization.sendSerializedBase
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.channelFlow
|
||||
import kotlinx.coroutines.isActive
|
||||
@ -18,9 +19,9 @@ import kotlinx.serialization.DeserializationStrategy
|
||||
* @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(
|
||||
inline fun <reified T> HttpClient.createStandardWebsocketFlow(
|
||||
url: String,
|
||||
crossinline checkReconnection: suspend (Throwable?) -> Boolean = { true },
|
||||
noinline checkReconnection: suspend (Throwable?) -> Boolean = { true },
|
||||
noinline requestBuilder: HttpRequestBuilder.() -> Unit = {}
|
||||
): Flow<T> {
|
||||
pluginOrNull(WebSockets) ?: error("Plugin $WebSockets must be installed for using createStandardWebsocketFlow")
|
||||
|
@ -42,4 +42,11 @@ suspend fun <ObjectType, IdType, InputValueType> WriteStandardCRUDRepo<ObjectTyp
|
||||
|
||||
interface StandardCRUDRepo<ObjectType, IdType, InputValueType> : ReadStandardCRUDRepo<ObjectType, IdType>,
|
||||
WriteStandardCRUDRepo<ObjectType, IdType, InputValueType>
|
||||
typealias CRUDRepo<ObjectType, IdType, InputValueType> = StandardCRUDRepo<ObjectType, IdType, InputValueType>
|
||||
typealias CRUDRepo<ObjectType, IdType, InputValueType> = StandardCRUDRepo<ObjectType, IdType, InputValueType>
|
||||
|
||||
class DelegateBasedStandardCRUDRepo<ObjectType, IdType, InputValueType>(
|
||||
readDelegate: ReadStandardCRUDRepo<ObjectType, IdType>,
|
||||
writeDelegate: WriteStandardCRUDRepo<ObjectType, IdType, InputValueType>
|
||||
) : StandardCRUDRepo<ObjectType, IdType, InputValueType>,
|
||||
ReadStandardCRUDRepo<ObjectType, IdType> by readDelegate,
|
||||
WriteStandardCRUDRepo<ObjectType, IdType, InputValueType> by writeDelegate
|
||||
|
@ -74,19 +74,24 @@ abstract class MapCRUDRepo<ObjectType, IdType, InputValueType>(
|
||||
|
||||
fun <ObjectType, IdType, InputValueType> MapCRUDRepo(
|
||||
map: MutableMap<IdType, ObjectType>,
|
||||
updateCallback: suspend (newValue: InputValueType, id: IdType, old: ObjectType) -> ObjectType,
|
||||
createCallback: suspend (newValue: InputValueType) -> Pair<IdType, ObjectType>
|
||||
updateCallback: suspend MutableMap<IdType, ObjectType>.(newValue: InputValueType, id: IdType, old: ObjectType) -> ObjectType,
|
||||
createCallback: suspend MutableMap<IdType, ObjectType>.(newValue: InputValueType) -> Pair<IdType, ObjectType>
|
||||
) = object : MapCRUDRepo<ObjectType, IdType, InputValueType>(map) {
|
||||
override suspend fun updateObject(
|
||||
newValue: InputValueType,
|
||||
id: IdType,
|
||||
old: ObjectType
|
||||
): ObjectType = updateCallback(newValue, id, old)
|
||||
): ObjectType = map.updateCallback(newValue, id, old)
|
||||
|
||||
override suspend fun createObject(newValue: InputValueType): Pair<IdType, ObjectType> = createCallback(newValue)
|
||||
override suspend fun createObject(newValue: InputValueType): Pair<IdType, ObjectType> = map.createCallback(newValue)
|
||||
}
|
||||
|
||||
fun <ObjectType, IdType, InputValueType> MapCRUDRepo(
|
||||
updateCallback: suspend MutableMap<IdType, ObjectType>.(newValue: InputValueType, id: IdType, old: ObjectType) -> ObjectType,
|
||||
createCallback: suspend MutableMap<IdType, ObjectType>.(newValue: InputValueType) -> Pair<IdType, ObjectType>
|
||||
) = MapCRUDRepo(mutableMapOf(), updateCallback, createCallback)
|
||||
|
||||
fun <ObjectType, IdType, InputValueType> MutableMap<IdType, ObjectType>.asCrudRepo(
|
||||
updateCallback: suspend (newValue: InputValueType, id: IdType, old: ObjectType) -> ObjectType,
|
||||
createCallback: suspend (newValue: InputValueType) -> Pair<IdType, ObjectType>
|
||||
updateCallback: suspend MutableMap<IdType, ObjectType>.(newValue: InputValueType, id: IdType, old: ObjectType) -> ObjectType,
|
||||
createCallback: suspend MutableMap<IdType, ObjectType>.(newValue: InputValueType) -> Pair<IdType, ObjectType>
|
||||
) = MapCRUDRepo(this, updateCallback, createCallback)
|
||||
|
@ -7,7 +7,7 @@ import dev.inmo.micro_utils.repos.ktor.common.crud.*
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.call.body
|
||||
import io.ktor.client.request.get
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.http.*
|
||||
import io.ktor.util.reflect.TypeInfo
|
||||
import io.ktor.util.reflect.typeInfo
|
||||
import kotlinx.serialization.*
|
||||
@ -16,11 +16,14 @@ class KtorReadStandardCrudRepoClient<ObjectType, IdType> (
|
||||
private val baseUrl: String,
|
||||
private val httpClient: HttpClient,
|
||||
private val objectType: TypeInfo,
|
||||
private val contentType: ContentType,
|
||||
private val idSerializer: suspend (IdType) -> String
|
||||
) : ReadStandardCRUDRepo<ObjectType, IdType> {
|
||||
override suspend fun getByPagination(pagination: Pagination): PaginationResult<ObjectType> = httpClient.get(
|
||||
buildStandardUrl(baseUrl, getByPaginationRouting, pagination.asUrlQueryParts)
|
||||
).body()
|
||||
) {
|
||||
contentType(contentType)
|
||||
}.body()
|
||||
|
||||
override suspend fun getById(id: IdType): ObjectType? = httpClient.get(
|
||||
buildStandardUrl(
|
||||
@ -30,7 +33,9 @@ class KtorReadStandardCrudRepoClient<ObjectType, IdType> (
|
||||
"id" to idSerializer(id)
|
||||
)
|
||||
)
|
||||
).takeIf { it.status != HttpStatusCode.NoContent } ?.body<ObjectType>(objectType)
|
||||
) {
|
||||
contentType(contentType)
|
||||
}.takeIf { it.status != HttpStatusCode.NoContent } ?.body<ObjectType>(objectType)
|
||||
|
||||
override suspend fun contains(id: IdType): Boolean = httpClient.get(
|
||||
buildStandardUrl(
|
||||
@ -40,24 +45,30 @@ class KtorReadStandardCrudRepoClient<ObjectType, IdType> (
|
||||
"id" to idSerializer(id)
|
||||
)
|
||||
)
|
||||
).body()
|
||||
) {
|
||||
contentType(contentType)
|
||||
}.body()
|
||||
|
||||
override suspend fun count(): Long = httpClient.get(
|
||||
buildStandardUrl(
|
||||
baseUrl,
|
||||
countRouting
|
||||
)
|
||||
).body()
|
||||
) {
|
||||
contentType(contentType)
|
||||
}.body()
|
||||
}
|
||||
|
||||
inline fun <reified ObjectType, IdType> KtorReadStandardCrudRepoClient(
|
||||
baseUrl: String,
|
||||
httpClient: HttpClient,
|
||||
contentType: ContentType,
|
||||
noinline idSerializer: suspend (IdType) -> String
|
||||
) = KtorReadStandardCrudRepoClient<ObjectType, IdType>(
|
||||
baseUrl,
|
||||
httpClient,
|
||||
typeInfo<ObjectType>(),
|
||||
contentType,
|
||||
idSerializer
|
||||
)
|
||||
|
||||
@ -65,8 +76,9 @@ inline fun <reified ObjectType, IdType> KtorReadStandardCrudRepoClient(
|
||||
baseUrl: String,
|
||||
httpClient: HttpClient,
|
||||
idsSerializer: KSerializer<IdType>,
|
||||
serialFormat: StringFormat
|
||||
) = KtorReadStandardCrudRepoClient<ObjectType, IdType>(baseUrl, httpClient) {
|
||||
serialFormat: StringFormat,
|
||||
contentType: ContentType,
|
||||
) = KtorReadStandardCrudRepoClient<ObjectType, IdType>(baseUrl, httpClient, contentType) {
|
||||
serialFormat.encodeToString(idsSerializer, it)
|
||||
}
|
||||
|
||||
@ -74,7 +86,8 @@ inline fun <reified ObjectType, IdType> KtorReadStandardCrudRepoClient(
|
||||
baseUrl: String,
|
||||
httpClient: HttpClient,
|
||||
idsSerializer: KSerializer<IdType>,
|
||||
serialFormat: BinaryFormat
|
||||
) = KtorReadStandardCrudRepoClient<ObjectType, IdType>(baseUrl, httpClient) {
|
||||
serialFormat: BinaryFormat,
|
||||
contentType: ContentType,
|
||||
) = KtorReadStandardCrudRepoClient<ObjectType, IdType>(baseUrl, httpClient, contentType) {
|
||||
serialFormat.encodeHex(idsSerializer, it)
|
||||
}
|
||||
|
@ -3,91 +3,120 @@ package dev.inmo.micro_utils.repos.ktor.client.crud
|
||||
import dev.inmo.micro_utils.ktor.common.*
|
||||
import dev.inmo.micro_utils.repos.*
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.utils.EmptyContent.contentType
|
||||
import io.ktor.http.ContentType
|
||||
import io.ktor.util.reflect.TypeInfo
|
||||
import io.ktor.util.reflect.typeInfo
|
||||
import kotlinx.serialization.*
|
||||
|
||||
class KtorStandardCrudRepoClient<ObjectType, IdType, InputValue> (
|
||||
baseUrl: String,
|
||||
httpClient: HttpClient,
|
||||
objectTypeInfo: TypeInfo,
|
||||
idSerializer: suspend (IdType) -> String
|
||||
) : StandardCRUDRepo<ObjectType, IdType, InputValue>,
|
||||
ReadStandardCRUDRepo<ObjectType, IdType> by KtorReadStandardCrudRepoClient(
|
||||
baseUrl,
|
||||
httpClient,
|
||||
objectTypeInfo,
|
||||
idSerializer
|
||||
),
|
||||
WriteStandardCRUDRepo<ObjectType, IdType, InputValue> by KtorWriteStandardCrudRepoClient(
|
||||
baseUrl,
|
||||
httpClient
|
||||
) {
|
||||
constructor(
|
||||
baseUrl: String,
|
||||
subpart: String,
|
||||
httpClient: HttpClient,
|
||||
objectTypeInfo: TypeInfo,
|
||||
idSerializer: suspend (IdType) -> String
|
||||
) : this(
|
||||
buildStandardUrl(baseUrl, subpart), httpClient, objectTypeInfo, idSerializer
|
||||
)
|
||||
readDelegate: ReadStandardCRUDRepo<ObjectType, IdType>,
|
||||
writeDelegate: WriteStandardCRUDRepo<ObjectType, IdType, InputValue>
|
||||
) : StandardCRUDRepo<ObjectType, IdType, InputValue> by DelegateBasedStandardCRUDRepo(
|
||||
readDelegate,
|
||||
writeDelegate
|
||||
) {
|
||||
companion object {
|
||||
inline operator fun <reified ObjectType, reified IdType, reified InputValue>invoke(
|
||||
baseUrl: String,
|
||||
httpClient: HttpClient,
|
||||
objectTypeInfo: TypeInfo,
|
||||
contentType: ContentType,
|
||||
noinline idSerializer: suspend (IdType) -> String
|
||||
) = KtorStandardCrudRepoClient(
|
||||
KtorReadStandardCrudRepoClient(
|
||||
baseUrl,
|
||||
httpClient,
|
||||
objectTypeInfo,
|
||||
contentType,
|
||||
idSerializer
|
||||
),
|
||||
KtorWriteStandardCrudRepoClient<ObjectType, IdType, InputValue>(
|
||||
baseUrl,
|
||||
httpClient,
|
||||
contentType
|
||||
)
|
||||
)
|
||||
|
||||
inline operator fun <reified ObjectType, reified IdType, reified InputValue>invoke(
|
||||
baseUrl: String,
|
||||
subpart: String,
|
||||
httpClient: HttpClient,
|
||||
objectTypeInfo: TypeInfo,
|
||||
contentType: ContentType,
|
||||
noinline idSerializer: suspend (IdType) -> String
|
||||
) = KtorStandardCrudRepoClient<ObjectType, IdType, InputValue>(
|
||||
buildStandardUrl(baseUrl, subpart),
|
||||
httpClient,
|
||||
objectTypeInfo,
|
||||
contentType,
|
||||
idSerializer
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline fun <reified ObjectType, IdType, InputValue> KtorStandardCrudRepoClient(
|
||||
inline fun <reified ObjectType, reified IdType, reified InputValue> KtorStandardCrudRepoClient(
|
||||
baseUrl: String,
|
||||
httpClient: HttpClient,
|
||||
contentType: ContentType,
|
||||
noinline idSerializer: suspend (IdType) -> String
|
||||
) = KtorStandardCrudRepoClient<ObjectType, IdType, InputValue>(
|
||||
baseUrl,
|
||||
httpClient,
|
||||
typeInfo<ObjectType>(),
|
||||
contentType,
|
||||
idSerializer
|
||||
)
|
||||
|
||||
inline fun <reified ObjectType, IdType, InputValue> KtorStandardCrudRepoClient(
|
||||
inline fun <reified ObjectType, reified IdType, reified InputValue> KtorStandardCrudRepoClient(
|
||||
baseUrl: String,
|
||||
httpClient: HttpClient,
|
||||
idsSerializer: KSerializer<IdType>,
|
||||
serialFormat: StringFormat
|
||||
) = KtorStandardCrudRepoClient<ObjectType, IdType, InputValue>(baseUrl, httpClient) {
|
||||
serialFormat: StringFormat,
|
||||
contentType: ContentType,
|
||||
) = KtorStandardCrudRepoClient<ObjectType, IdType, InputValue>(baseUrl, httpClient, contentType) {
|
||||
serialFormat.encodeToString(idsSerializer, it)
|
||||
}
|
||||
|
||||
inline fun <reified ObjectType, IdType, InputValue> KtorStandardCrudRepoClient(
|
||||
inline fun <reified ObjectType, reified IdType, reified InputValue> KtorStandardCrudRepoClient(
|
||||
baseUrl: String,
|
||||
httpClient: HttpClient,
|
||||
idsSerializer: KSerializer<IdType>,
|
||||
serialFormat: BinaryFormat
|
||||
) = KtorStandardCrudRepoClient<ObjectType, IdType, InputValue>(baseUrl, httpClient) {
|
||||
serialFormat: BinaryFormat,
|
||||
contentType: ContentType,
|
||||
) = KtorStandardCrudRepoClient<ObjectType, IdType, InputValue>(baseUrl, httpClient, contentType) {
|
||||
serialFormat.encodeHex(idsSerializer, it)
|
||||
}
|
||||
|
||||
|
||||
inline fun <reified ObjectType, IdType, InputValue> KtorStandardCrudRepoClient(
|
||||
inline fun <reified ObjectType, reified IdType, reified InputValue> KtorStandardCrudRepoClient(
|
||||
baseUrl: String,
|
||||
subpart: String,
|
||||
httpClient: HttpClient,
|
||||
contentType: ContentType,
|
||||
noinline idSerializer: suspend (IdType) -> String
|
||||
) = KtorStandardCrudRepoClient<ObjectType, IdType, InputValue>(
|
||||
buildStandardUrl(baseUrl, subpart),
|
||||
httpClient,
|
||||
contentType,
|
||||
idSerializer
|
||||
)
|
||||
|
||||
inline fun <reified ObjectType, IdType, InputValue> KtorStandardCrudRepoClient(
|
||||
inline fun <reified ObjectType, reified IdType, reified InputValue> KtorStandardCrudRepoClient(
|
||||
baseUrl: String,
|
||||
subpart: String,
|
||||
httpClient: HttpClient,
|
||||
idsSerializer: KSerializer<IdType>,
|
||||
serialFormat: StringFormat
|
||||
) = KtorStandardCrudRepoClient<ObjectType, IdType, InputValue>(buildStandardUrl(baseUrl, subpart), httpClient, idsSerializer, serialFormat)
|
||||
serialFormat: StringFormat,
|
||||
contentType: ContentType,
|
||||
) = KtorStandardCrudRepoClient<ObjectType, IdType, InputValue>(buildStandardUrl(baseUrl, subpart), httpClient, idsSerializer, serialFormat, contentType)
|
||||
|
||||
inline fun <reified ObjectType, IdType, InputValue> KtorStandardCrudRepoClient(
|
||||
inline fun <reified ObjectType, reified IdType, reified InputValue> KtorStandardCrudRepoClient(
|
||||
baseUrl: String,
|
||||
subpart: String,
|
||||
httpClient: HttpClient,
|
||||
idsSerializer: KSerializer<IdType>,
|
||||
serialFormat: BinaryFormat
|
||||
) = KtorStandardCrudRepoClient<ObjectType, IdType, InputValue>(buildStandardUrl(baseUrl, subpart), httpClient, idsSerializer, serialFormat)
|
||||
serialFormat: BinaryFormat,
|
||||
contentType: ContentType,
|
||||
) = KtorStandardCrudRepoClient<ObjectType, IdType, InputValue>(buildStandardUrl(baseUrl, subpart), httpClient, idsSerializer, serialFormat, contentType)
|
||||
|
@ -8,6 +8,9 @@ import dev.inmo.micro_utils.repos.ktor.common.crud.*
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.call.body
|
||||
import io.ktor.client.request.*
|
||||
import io.ktor.client.statement.HttpResponse
|
||||
import io.ktor.http.ContentType
|
||||
import io.ktor.http.contentType
|
||||
import io.ktor.util.reflect.TypeInfo
|
||||
import io.ktor.util.reflect.typeInfo
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
@ -16,36 +19,71 @@ import kotlinx.serialization.builtins.*
|
||||
|
||||
class KtorWriteStandardCrudRepoClient<ObjectType, IdType, InputValue> (
|
||||
private val baseUrl: String,
|
||||
private val httpClient: HttpClient
|
||||
private val httpClient: HttpClient,
|
||||
override val newObjectsFlow: Flow<ObjectType>,
|
||||
override val updatedObjectsFlow: Flow<ObjectType>,
|
||||
override val deletedObjectsIdsFlow: Flow<IdType>,
|
||||
private val createSetup: suspend HttpRequestBuilder.(List<InputValue>) -> Unit,
|
||||
private val updateSetup: suspend HttpRequestBuilder.(List<UpdatedValuePair<IdType, InputValue>>) -> Unit,
|
||||
private val deleteByIdSetup: suspend HttpRequestBuilder.(List<IdType>) -> Unit,
|
||||
private val createBodyGetter: suspend HttpResponse.() -> List<ObjectType>,
|
||||
private val updateBodyGetter: suspend HttpResponse.() -> List<ObjectType>
|
||||
) : WriteStandardCRUDRepo<ObjectType, IdType, InputValue> {
|
||||
override suspend fun create(values: List<InputValue>): List<ObjectType> = httpClient.post(
|
||||
buildStandardUrl(baseUrl, createRouting)
|
||||
) {
|
||||
createSetup(values)
|
||||
}.createBodyGetter()
|
||||
|
||||
override val newObjectsFlow: Flow<ObjectType> = httpClient.createStandardWebsocketFlow(
|
||||
buildStandardUrl(baseUrl, newObjectsFlowRouting),
|
||||
)
|
||||
override val updatedObjectsFlow: Flow<ObjectType> = httpClient.createStandardWebsocketFlow(
|
||||
buildStandardUrl(baseUrl, updatedObjectsFlowRouting)
|
||||
)
|
||||
override val deletedObjectsIdsFlow: Flow<IdType> = httpClient.createStandardWebsocketFlow(
|
||||
buildStandardUrl(baseUrl, deletedObjectsIdsFlowRouting)
|
||||
)
|
||||
|
||||
|
||||
override suspend fun create(values: List<InputValue>): List<ObjectType> = httpClient.post {
|
||||
url(buildStandardUrl(baseUrl, createRouting))
|
||||
setBody(values)
|
||||
}.body()
|
||||
|
||||
override suspend fun update(values: List<UpdatedValuePair<IdType, InputValue>>): List<ObjectType> = httpClient.post {
|
||||
url(buildStandardUrl(baseUrl, updateManyRouting))
|
||||
setBody(values)
|
||||
}.body()
|
||||
override suspend fun update(
|
||||
values: List<UpdatedValuePair<IdType, InputValue>>
|
||||
): List<ObjectType> = httpClient.post(
|
||||
buildStandardUrl(baseUrl, updateManyRouting)
|
||||
) {
|
||||
updateSetup(values)
|
||||
}.updateBodyGetter()
|
||||
|
||||
override suspend fun update(id: IdType, value: InputValue): ObjectType? = update(listOf(id to value)).firstOrNull()
|
||||
|
||||
override suspend fun deleteById(ids: List<IdType>) {
|
||||
httpClient.post {
|
||||
url(buildStandardUrl(baseUrl, deleteByIdRouting))
|
||||
setBody(ids)
|
||||
}
|
||||
httpClient.post(
|
||||
buildStandardUrl(baseUrl, deleteByIdRouting)
|
||||
) {
|
||||
deleteByIdSetup(ids)
|
||||
}.status
|
||||
}
|
||||
|
||||
companion object {
|
||||
inline operator fun <reified ObjectType, reified IdType, reified InputValue> invoke(
|
||||
baseUrl: String,
|
||||
httpClient: HttpClient,
|
||||
contentType: ContentType
|
||||
) = KtorWriteStandardCrudRepoClient<ObjectType, IdType, InputValue>(
|
||||
baseUrl,
|
||||
httpClient,
|
||||
httpClient.createStandardWebsocketFlow(
|
||||
buildStandardUrl(baseUrl, newObjectsFlowRouting),
|
||||
),
|
||||
httpClient.createStandardWebsocketFlow(
|
||||
buildStandardUrl(baseUrl, updatedObjectsFlowRouting),
|
||||
),
|
||||
httpClient.createStandardWebsocketFlow(
|
||||
buildStandardUrl(baseUrl, deletedObjectsIdsFlowRouting),
|
||||
),
|
||||
{
|
||||
contentType(contentType)
|
||||
setBody(it)
|
||||
},
|
||||
{
|
||||
contentType(contentType)
|
||||
setBody(it)
|
||||
},
|
||||
{
|
||||
contentType(contentType)
|
||||
setBody(it)
|
||||
},
|
||||
{ body() },
|
||||
{ body() }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user