mirror of
https://github.com/InsanusMokrassar/MicroUtils.git
synced 2025-09-17 22:39:25 +00:00
Compare commits
34 Commits
Author | SHA1 | Date | |
---|---|---|---|
cfc7119697 | |||
22a6520d3e | |||
fb25e91191 | |||
c116b270b6 | |||
aa2d598689 | |||
5ef3bb746b | |||
037616e271 | |||
abbea906f1 | |||
9132e216c9 | |||
12a7e3c4af | |||
b40c093917 | |||
7ac12455c8 | |||
5043eec7a2 | |||
cf31f53e01 | |||
cd22d76fa7 | |||
c8759843f7 | |||
781bbcc012 | |||
6da29c0686 | |||
fcdb6fc45a | |||
e785a99bd7 | |||
121e513fdd | |||
9cf01ab54f | |||
c655107681 | |||
91a5af6a9a | |||
86e74c0a6f | |||
d8f01f21a0 | |||
9fb8626d8c | |||
1c52e04cdb | |||
798128256e | |||
72c2df47fd | |||
c9c6d4c0c1 | |||
2f4f9f3003 | |||
22e8f8e5d6 | |||
04cf8c3d9a |
50
CHANGELOG.md
50
CHANGELOG.md
@@ -1,5 +1,55 @@
|
||||
# Changelog
|
||||
|
||||
## 0.11.9
|
||||
|
||||
* `Versions`
|
||||
* `Coroutines`: `1.6.1` -> `1.6.3`
|
||||
* `Ktor`: `2.0.2` -> `2.0.3`
|
||||
* `Compose`: `1.2.0-alpha01-dev686` -> `1.2.0-alpha01-dev729`
|
||||
|
||||
## 0.11.8
|
||||
|
||||
* `Repos`:
|
||||
* `Common`:
|
||||
* Fixes in `FileKeyValueRepo`
|
||||
|
||||
## 0.11.7
|
||||
|
||||
* `Common`:
|
||||
* New abstractions `SimpleMapper` and `SimpleSuspendableMapper`
|
||||
* `Repos`:
|
||||
* `Common`:
|
||||
* Add mappers for `CRUDRepo`
|
||||
|
||||
## 0.11.6
|
||||
|
||||
* `FSM`:
|
||||
* `Common`
|
||||
* Several fixes related to the jobs handling
|
||||
|
||||
## 0.11.5
|
||||
|
||||
* `Coroutines`:
|
||||
* `Compose`:
|
||||
* Add extension `StateFlow#asMutableComposeListState` and `StateFlow#asComposeList`
|
||||
* Add extension `StateFlow#asMutableComposeState`/`StateFlow#asComposeState`
|
||||
|
||||
## 0.11.4
|
||||
|
||||
**THIS VERSION HAS BEEN BROKEN, DO NOT USE IT**
|
||||
|
||||
## 0.11.3
|
||||
|
||||
* `Ktor`:
|
||||
* Support of `WebSockets` has been improved
|
||||
* `Client`:
|
||||
* New extensions: `HttpClient#openBaseWebSocketFlow`, `HttpClient#openWebSocketFlow`, `HttpClient#openSecureWebSocketFlow`
|
||||
|
||||
## 0.11.2
|
||||
|
||||
* `Ktor`:
|
||||
* Support of `WebSockets` has been improved and added fixes inside of clients
|
||||
|
||||
## 0.11.1
|
||||
|
||||
* `Repos`
|
||||
|
@@ -0,0 +1,53 @@
|
||||
package dev.inmo.micro_utils.common
|
||||
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
interface SimpleMapper<T1, T2> {
|
||||
fun convertToT1(from: T2): T1
|
||||
fun convertToT2(from: T1): T2
|
||||
}
|
||||
|
||||
@JvmName("convertFromT2")
|
||||
fun <T1, T2> SimpleMapper<T1, T2>.convert(from: T2) = convertToT1(from)
|
||||
@JvmName("convertFromT1")
|
||||
fun <T1, T2> SimpleMapper<T1, T2>.convert(from: T1) = convertToT2(from)
|
||||
|
||||
class SimpleMapperImpl<T1, T2>(
|
||||
private val t1: (T2) -> T1,
|
||||
private val t2: (T1) -> T2,
|
||||
) : SimpleMapper<T1, T2> {
|
||||
override fun convertToT1(from: T2): T1 = t1.invoke(from)
|
||||
|
||||
override fun convertToT2(from: T1): T2 = t2.invoke(from)
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <T1, T2> simpleMapper(
|
||||
noinline t1: (T2) -> T1,
|
||||
noinline t2: (T1) -> T2,
|
||||
) = SimpleMapperImpl(t1, t2)
|
||||
|
||||
interface SimpleSuspendableMapper<T1, T2> {
|
||||
suspend fun convertToT1(from: T2): T1
|
||||
suspend fun convertToT2(from: T1): T2
|
||||
}
|
||||
|
||||
@JvmName("convertFromT2")
|
||||
suspend fun <T1, T2> SimpleSuspendableMapper<T1, T2>.convert(from: T2) = convertToT1(from)
|
||||
@JvmName("convertFromT1")
|
||||
suspend fun <T1, T2> SimpleSuspendableMapper<T1, T2>.convert(from: T1) = convertToT2(from)
|
||||
|
||||
class SimpleSuspendableMapperImpl<T1, T2>(
|
||||
private val t1: suspend (T2) -> T1,
|
||||
private val t2: suspend (T1) -> T2,
|
||||
) : SimpleSuspendableMapper<T1, T2> {
|
||||
override suspend fun convertToT1(from: T2): T1 = t1.invoke(from)
|
||||
|
||||
override suspend fun convertToT2(from: T1): T2 = t2.invoke(from)
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <T1, T2> simpleSuspendableMapper(
|
||||
noinline t1: suspend (T2) -> T1,
|
||||
noinline t2: suspend (T1) -> T2,
|
||||
) = SimpleSuspendableMapperImpl(t1, t2)
|
@@ -0,0 +1,26 @@
|
||||
package dev.inmo.micro_utils.coroutines.compose
|
||||
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.snapshots.SnapshotStateList
|
||||
import dev.inmo.micro_utils.common.applyDiff
|
||||
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <reified T> Flow<List<T>>.asMutableComposeListState(
|
||||
scope: CoroutineScope
|
||||
): SnapshotStateList<T> {
|
||||
val state = mutableStateListOf<T>()
|
||||
subscribeSafelyWithoutExceptions(scope) {
|
||||
state.applyDiff(it)
|
||||
}
|
||||
return state
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <reified T> Flow<List<T>>.asComposeList(
|
||||
scope: CoroutineScope
|
||||
): List<T> = asMutableComposeListState(scope)
|
||||
|
@@ -0,0 +1,35 @@
|
||||
package dev.inmo.micro_utils.coroutines.compose
|
||||
|
||||
import androidx.compose.runtime.*
|
||||
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
fun <T> Flow<T>.asMutableComposeState(
|
||||
initial: T,
|
||||
scope: CoroutineScope
|
||||
): MutableState<T> {
|
||||
val state = mutableStateOf(initial)
|
||||
subscribeSafelyWithoutExceptions(scope) { state.value = it }
|
||||
return state
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <T> StateFlow<T>.asMutableComposeState(
|
||||
scope: CoroutineScope
|
||||
): MutableState<T> = asMutableComposeState(value, scope)
|
||||
|
||||
fun <T> Flow<T>.asComposeState(
|
||||
initial: T,
|
||||
scope: CoroutineScope
|
||||
): State<T> {
|
||||
val state = asMutableComposeState(initial, scope)
|
||||
return derivedStateOf { state.value }
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <T> StateFlow<T>.asComposeState(
|
||||
scope: CoroutineScope
|
||||
): State<T> = asComposeState(value, scope)
|
||||
|
@@ -6,6 +6,7 @@ import dev.inmo.micro_utils.coroutines.*
|
||||
import dev.inmo.micro_utils.fsm.common.utils.StateHandlingErrorHandler
|
||||
import dev.inmo.micro_utils.fsm.common.utils.defaultStateHandlingErrorHandler
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.asFlow
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
|
||||
@@ -85,10 +86,10 @@ open class DefaultStatesMachine <T: State>(
|
||||
|
||||
protected open suspend fun performUpdate(state: T) {
|
||||
val newState = launchStateHandling(state, handlers)
|
||||
if (newState != null) {
|
||||
statesManager.update(state, newState)
|
||||
} else {
|
||||
if (newState == null) {
|
||||
statesManager.endChain(state)
|
||||
} else {
|
||||
statesManager.update(state, newState)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,7 +119,7 @@ open class DefaultStatesMachine <T: State>(
|
||||
* [StatesManager.endChain].
|
||||
*/
|
||||
override fun start(scope: CoroutineScope): Job = scope.launchSafelyWithoutExceptions {
|
||||
statesManager.onStartChain.subscribeSafelyWithoutExceptions(this) {
|
||||
(statesManager.getActiveStates().asFlow() + statesManager.onStartChain).subscribeSafelyWithoutExceptions(this) {
|
||||
launch { performStateUpdate(Optional.absent(), it, scope.LinkedSupervisorScope()) }
|
||||
}
|
||||
statesManager.onChainStateUpdated.subscribeSafelyWithoutExceptions(this) {
|
||||
@@ -134,10 +135,6 @@ open class DefaultStatesMachine <T: State>(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
statesManager.getActiveStates().forEach {
|
||||
launch { performStateUpdate(Optional.absent(), it, scope.LinkedSupervisorScope()) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -52,6 +52,7 @@ open class DefaultUpdatableStatesMachine<T : State>(
|
||||
statesJobs.remove(
|
||||
jobsStates[job] ?: return@withLock
|
||||
)
|
||||
jobsStates.remove(job)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -14,5 +14,5 @@ crypto_js_version=4.1.1
|
||||
# Project data
|
||||
|
||||
group=dev.inmo
|
||||
version=0.11.1
|
||||
android_code_version=125
|
||||
version=0.11.9
|
||||
android_code_version=133
|
||||
|
@@ -2,18 +2,18 @@
|
||||
|
||||
kt = "1.6.21"
|
||||
kt-serialization = "1.3.3"
|
||||
kt-coroutines = "1.6.1"
|
||||
kt-coroutines = "1.6.3"
|
||||
|
||||
jb-compose = "1.2.0-alpha01-dev686"
|
||||
jb-compose = "1.2.0-alpha01-dev729"
|
||||
jb-exposed = "0.38.2"
|
||||
jb-dokka = "1.6.21"
|
||||
|
||||
klock = "2.7.0"
|
||||
uuid = "0.4.1"
|
||||
|
||||
ktor = "2.0.2"
|
||||
ktor = "2.0.3"
|
||||
|
||||
gh-release = "2.3.7"
|
||||
gh-release = "2.4.1"
|
||||
|
||||
android-gradle = "7.0.4"
|
||||
dexcount = "3.1.0"
|
||||
|
@@ -1,5 +1,6 @@
|
||||
package dev.inmo.micro_utils.ktor.client
|
||||
|
||||
import dev.inmo.micro_utils.common.Warning
|
||||
import dev.inmo.micro_utils.coroutines.runCatchingSafely
|
||||
import dev.inmo.micro_utils.coroutines.safely
|
||||
import dev.inmo.micro_utils.ktor.common.*
|
||||
@@ -7,35 +8,25 @@ import io.ktor.client.HttpClient
|
||||
import io.ktor.client.plugins.pluginOrNull
|
||||
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 io.ktor.http.URLProtocol
|
||||
import kotlinx.coroutines.channels.SendChannel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.channelFlow
|
||||
import kotlinx.coroutines.isActive
|
||||
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 <reified T> HttpClient.createStandardWebsocketFlow(
|
||||
url: String,
|
||||
@Warning("This feature is internal and should not be used directly. It is can be changed without any notification and warranty on compile-time or other guaranties")
|
||||
inline fun <reified T : Any> openBaseWebSocketFlow(
|
||||
noinline checkReconnection: suspend (Throwable?) -> Boolean = { true },
|
||||
noinline requestBuilder: HttpRequestBuilder.() -> Unit = {}
|
||||
noinline webSocketSessionRequest: suspend SendChannel<T>.() -> Unit
|
||||
): Flow<T> {
|
||||
pluginOrNull(WebSockets) ?: error("Plugin $WebSockets must be installed for using createStandardWebsocketFlow")
|
||||
|
||||
val correctedUrl = url.asCorrectWebSocketUrl
|
||||
|
||||
return channelFlow {
|
||||
do {
|
||||
val reconnect = runCatchingSafely {
|
||||
ws(correctedUrl, requestBuilder) {
|
||||
for (received in incoming) {
|
||||
sendSerialized(received.data)
|
||||
}
|
||||
}
|
||||
webSocketSessionRequest()
|
||||
checkReconnection(null)
|
||||
}.getOrElse { e ->
|
||||
checkReconnection(e).also {
|
||||
@@ -53,3 +44,60 @@ inline fun <reified 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 <reified T : Any> HttpClient.openWebSocketFlow(
|
||||
url: String,
|
||||
useSecureConnection: Boolean,
|
||||
noinline checkReconnection: suspend (Throwable?) -> Boolean = { true },
|
||||
noinline requestBuilder: HttpRequestBuilder.() -> Unit = {}
|
||||
): Flow<T> {
|
||||
pluginOrNull(WebSockets) ?: error("Plugin $WebSockets must be installed for using createStandardWebsocketFlow")
|
||||
|
||||
return openBaseWebSocketFlow<T>(checkReconnection) {
|
||||
val block: suspend DefaultClientWebSocketSession.() -> Unit = {
|
||||
while (isActive) {
|
||||
send(receiveDeserialized<T>())
|
||||
}
|
||||
}
|
||||
|
||||
if (useSecureConnection) {
|
||||
wss(url, requestBuilder, block)
|
||||
} else {
|
||||
ws(url, requestBuilder, block)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 <reified T : Any> HttpClient.openWebSocketFlow(
|
||||
url: String,
|
||||
noinline checkReconnection: suspend (Throwable?) -> Boolean = { true },
|
||||
noinline requestBuilder: HttpRequestBuilder.() -> Unit = {}
|
||||
): Flow<T> = openWebSocketFlow(url, false, checkReconnection, requestBuilder)
|
||||
|
||||
/**
|
||||
* @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 <reified T : Any> HttpClient.openSecureWebSocketFlow(
|
||||
url: String,
|
||||
noinline checkReconnection: suspend (Throwable?) -> Boolean = { true },
|
||||
noinline requestBuilder: HttpRequestBuilder.() -> Unit = {}
|
||||
): Flow<T> = openWebSocketFlow(url, true, checkReconnection, requestBuilder)
|
||||
|
||||
/**
|
||||
* @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 <reified T : Any> HttpClient.createStandardWebsocketFlow(
|
||||
url: String,
|
||||
noinline checkReconnection: suspend (Throwable?) -> Boolean = { true },
|
||||
noinline requestBuilder: HttpRequestBuilder.() -> Unit = {}
|
||||
): Flow<T> = openWebSocketFlow(url, checkReconnection, requestBuilder)
|
||||
|
@@ -4,7 +4,10 @@ import dev.inmo.micro_utils.common.MPPFile
|
||||
import dev.inmo.micro_utils.ktor.common.TemporalFileId
|
||||
import io.ktor.client.HttpClient
|
||||
import kotlinx.coroutines.*
|
||||
import org.w3c.dom.mediasource.ENDED
|
||||
import org.w3c.dom.mediasource.ReadyState
|
||||
import org.w3c.xhr.*
|
||||
import org.w3c.xhr.XMLHttpRequest.Companion.DONE
|
||||
|
||||
suspend fun tempUpload(
|
||||
fullTempUploadDraftPath: String,
|
||||
@@ -12,7 +15,7 @@ suspend fun tempUpload(
|
||||
onUpload: (Long, Long) -> Unit
|
||||
): TemporalFileId {
|
||||
val formData = FormData()
|
||||
val answer = CompletableDeferred<TemporalFileId>()
|
||||
val answer = CompletableDeferred<TemporalFileId>(currentCoroutineContext().job)
|
||||
|
||||
formData.append(
|
||||
"data",
|
||||
@@ -37,17 +40,15 @@ suspend fun tempUpload(
|
||||
request.open("POST", fullTempUploadDraftPath, true)
|
||||
request.send(formData)
|
||||
|
||||
val handle = currentCoroutineContext().job.invokeOnCompletion {
|
||||
answer.invokeOnCompletion {
|
||||
runCatching {
|
||||
request.abort()
|
||||
if (request.readyState != DONE) {
|
||||
request.abort()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return runCatching {
|
||||
answer.await()
|
||||
}.also {
|
||||
handle.dispose()
|
||||
}.getOrThrow()
|
||||
return answer.await()
|
||||
}
|
||||
|
||||
|
||||
|
@@ -12,6 +12,7 @@ import io.ktor.websocket.send
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.serialization.SerializationStrategy
|
||||
|
||||
@Deprecated("This method will be removed soon")
|
||||
fun <T> Route.includeWebsocketHandling(
|
||||
suburl: String,
|
||||
flow: Flow<T>,
|
||||
|
@@ -15,7 +15,8 @@ import kotlinx.serialization.SerializationStrategy
|
||||
inline fun <reified T : Any> Route.includeWebsocketHandling(
|
||||
suburl: String,
|
||||
flow: Flow<T>,
|
||||
protocol: URLProtocol? = null
|
||||
protocol: URLProtocol? = null,
|
||||
noinline dataMapper: suspend WebSocketServerSession.(T) -> T? = { it }
|
||||
) {
|
||||
application.apply {
|
||||
pluginOrNull(WebSockets) ?: install(WebSockets)
|
||||
@@ -23,7 +24,7 @@ inline fun <reified T : Any> Route.includeWebsocketHandling(
|
||||
webSocket(suburl, protocol ?.name) {
|
||||
safely {
|
||||
flow.collect {
|
||||
sendSerialized(it)
|
||||
sendSerialized(dataMapper(it) ?: return@collect)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,22 +1,51 @@
|
||||
package dev.inmo.micro_utils.repos
|
||||
|
||||
import dev.inmo.micro_utils.common.*
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
interface MapperRepo<FromKey, FromValue, ToKey, ToValue> {
|
||||
val keyMapper: SimpleSuspendableMapper<FromKey, ToKey>
|
||||
get() = simpleSuspendableMapper(
|
||||
{ it.toInnerKey() },
|
||||
{ it.toOutKey() }
|
||||
)
|
||||
val valueMapper: SimpleSuspendableMapper<FromValue, ToValue>
|
||||
get() = simpleSuspendableMapper(
|
||||
{ it.toInnerValue() },
|
||||
{ it.toOutValue() }
|
||||
)
|
||||
|
||||
suspend fun FromKey.toOutKey() = this as ToKey
|
||||
suspend fun FromValue.toOutValue() = this as ToValue
|
||||
|
||||
suspend fun ToKey.toInnerKey() = this as FromKey
|
||||
suspend fun ToValue.toInnerValue() = this as FromValue
|
||||
|
||||
companion object
|
||||
}
|
||||
|
||||
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> mapper(
|
||||
crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
||||
crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
|
||||
crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
|
||||
crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
|
||||
) = object : MapperRepo<FromKey, FromValue, ToKey, ToValue> {
|
||||
class SimpleMapperRepo<FromKey, FromValue, ToKey, ToValue>(
|
||||
private val keyFromToTo: suspend FromKey.() -> ToKey,
|
||||
private val valueFromToTo: suspend FromValue.() -> ToValue,
|
||||
private val keyToToFrom: suspend ToKey.() -> FromKey,
|
||||
private val valueToToFrom: suspend ToValue.() -> FromValue
|
||||
) : MapperRepo<FromKey, FromValue, ToKey, ToValue> {
|
||||
override suspend fun FromKey.toOutKey(): ToKey = keyFromToTo()
|
||||
override suspend fun FromValue.toOutValue(): ToValue = valueFromToTo()
|
||||
override suspend fun ToKey.toInnerKey(): FromKey = keyToToFrom()
|
||||
override suspend fun ToValue.toInnerValue(): FromValue = valueToToFrom()
|
||||
}
|
||||
|
||||
operator fun <FromKey, FromValue, ToKey, ToValue> MapperRepo.Companion.invoke(
|
||||
keyFromToTo: suspend FromKey.() -> ToKey,
|
||||
valueFromToTo: suspend FromValue.() -> ToValue,
|
||||
keyToToFrom: suspend ToKey.() -> FromKey,
|
||||
valueToToFrom: suspend ToValue.() -> FromValue
|
||||
) = SimpleMapperRepo(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
|
||||
|
||||
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> mapper(
|
||||
noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
||||
noinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
|
||||
noinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
|
||||
noinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
|
||||
) = MapperRepo(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
|
||||
|
@@ -0,0 +1,130 @@
|
||||
package dev.inmo.micro_utils.repos.mappers
|
||||
|
||||
import dev.inmo.micro_utils.common.*
|
||||
import dev.inmo.micro_utils.pagination.*
|
||||
import dev.inmo.micro_utils.repos.*
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
open class MapperReadCRUDRepo<FromId, FromRegistered, ToId, ToRegistered>(
|
||||
private val to: ReadCRUDRepo<ToRegistered, ToId>,
|
||||
mapper: MapperRepo<FromId, FromRegistered, ToId, ToRegistered>
|
||||
) : ReadCRUDRepo<FromRegistered, FromId>, MapperRepo<FromId, FromRegistered, ToId, ToRegistered> by mapper {
|
||||
override suspend fun getByPagination(
|
||||
pagination: Pagination
|
||||
): PaginationResult<FromRegistered> = to.getByPagination(
|
||||
pagination
|
||||
).let {
|
||||
it.changeResultsUnchecked(
|
||||
it.results.map { it.toInnerValue() }
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun count(): Long = to.count()
|
||||
|
||||
override suspend fun contains(id: FromId): Boolean = to.contains(id.toOutKey())
|
||||
|
||||
override suspend fun getById(id: FromId): FromRegistered? = to.getById(
|
||||
id.toOutKey()
|
||||
) ?.toInnerValue()
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <FromKey, FromValue, ToKey, ToValue> ReadCRUDRepo<ToValue, ToKey>.withMapper(
|
||||
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
|
||||
): ReadCRUDRepo<FromValue, FromKey> = MapperReadCRUDRepo(this, mapper)
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> ReadCRUDRepo<ToValue, ToKey>.withMapper(
|
||||
noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
||||
noinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
|
||||
noinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
|
||||
noinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
|
||||
): ReadCRUDRepo<FromValue, FromKey> = withMapper(
|
||||
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
|
||||
)
|
||||
|
||||
open class MapperWriteCRUDRepo<FromId, FromRegistered, FromInput, ToId, ToRegistered, ToInput>(
|
||||
private val to: WriteCRUDRepo<ToRegistered, ToId, ToInput>,
|
||||
mapper: MapperRepo<FromId, FromRegistered, ToId, ToRegistered>,
|
||||
inputMapper: SimpleSuspendableMapper<FromInput, ToInput>
|
||||
) : WriteCRUDRepo<FromRegistered, FromId, FromInput>,
|
||||
MapperRepo<FromId, FromRegistered, ToId, ToRegistered> by mapper,
|
||||
SimpleSuspendableMapper<FromInput, ToInput> by inputMapper {
|
||||
override val newObjectsFlow: Flow<FromRegistered> = to.newObjectsFlow.map { it.toInnerValue() }
|
||||
override val updatedObjectsFlow: Flow<FromRegistered> = to.updatedObjectsFlow.map { it.toInnerValue() }
|
||||
override val deletedObjectsIdsFlow: Flow<FromId> = to.deletedObjectsIdsFlow.map { it.toInnerKey() }
|
||||
|
||||
override suspend fun deleteById(ids: List<FromId>) = to.deleteById(ids.map { it.toOutKey() })
|
||||
|
||||
override suspend fun update(
|
||||
values: List<UpdatedValuePair<FromId, FromInput>>
|
||||
): List<FromRegistered> = to.update(
|
||||
values.map {
|
||||
it.first.toOutKey() to convert(it.second)
|
||||
}
|
||||
).map { it.toInnerValue() }
|
||||
|
||||
override suspend fun update(
|
||||
id: FromId,
|
||||
value: FromInput
|
||||
): FromRegistered? = to.update(id.toOutKey(), convert(value)) ?.toInnerValue()
|
||||
|
||||
override suspend fun create(values: List<FromInput>): List<FromRegistered> = to.create(
|
||||
values.map {
|
||||
convert(it)
|
||||
}
|
||||
).map {
|
||||
it.toInnerValue()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <FromKey, FromValue, FromInput, ToKey, ToValue, ToInput> WriteCRUDRepo<ToValue, ToKey, ToInput>.withMapper(
|
||||
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>,
|
||||
simpleSuspendableMapper: SimpleSuspendableMapper<FromInput, ToInput>
|
||||
): WriteCRUDRepo<FromValue, FromKey, FromInput> = MapperWriteCRUDRepo(this, mapper, simpleSuspendableMapper)
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <reified FromKey, reified FromValue, reified FromInput, reified ToKey, reified ToValue, reified ToInput> WriteCRUDRepo<ToValue, ToKey, ToInput>.withMapper(
|
||||
noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
||||
noinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
|
||||
noinline inputFromToTo: suspend FromInput.() -> ToInput = { this as ToInput },
|
||||
noinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
|
||||
noinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
|
||||
noinline inputToToFrom: suspend ToInput.() -> FromInput = { this as FromInput },
|
||||
): WriteCRUDRepo<FromValue, FromKey, FromInput> = withMapper(
|
||||
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom),
|
||||
simpleSuspendableMapper({ inputToToFrom(it) }, { inputFromToTo(it) })
|
||||
)
|
||||
|
||||
@Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE")
|
||||
open class MapperCRUDRepo<FromId, FromRegistered, FromInput, ToId, ToRegistered, ToInput>(
|
||||
private val to: CRUDRepo<ToRegistered, ToId, ToInput>,
|
||||
private val mapper: MapperRepo<FromId, FromRegistered, ToId, ToRegistered>,
|
||||
private val inputMapper: SimpleSuspendableMapper<FromInput, ToInput>
|
||||
) : CRUDRepo<FromRegistered, FromId, FromInput>,
|
||||
MapperRepo<FromId, FromRegistered, ToId, ToRegistered> by mapper,
|
||||
ReadCRUDRepo<FromRegistered, FromId> by MapperReadCRUDRepo(to, mapper),
|
||||
WriteCRUDRepo<FromRegistered, FromId, FromInput> by MapperWriteCRUDRepo(to, mapper, inputMapper)
|
||||
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <FromKey, FromValue, FromInput, ToKey, ToValue, ToInput> CRUDRepo<ToValue, ToKey, ToInput>.withMapper(
|
||||
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>,
|
||||
simpleSuspendableMapper: SimpleSuspendableMapper<FromInput, ToInput>
|
||||
): CRUDRepo<FromValue, FromKey, FromInput> = MapperCRUDRepo(this, mapper, simpleSuspendableMapper)
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <reified FromKey, reified FromValue, reified FromInput, reified ToKey, reified ToValue, reified ToInput> CRUDRepo<ToValue, ToKey, ToInput>.withMapper(
|
||||
noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
||||
noinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
|
||||
noinline inputFromToTo: suspend FromInput.() -> ToInput = { this as ToInput },
|
||||
noinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
|
||||
noinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
|
||||
noinline inputToToFrom: suspend ToInput.() -> FromInput = { this as FromInput },
|
||||
): CRUDRepo<FromValue, FromKey, FromInput> = withMapper(
|
||||
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom),
|
||||
simpleSuspendableMapper({ inputToToFrom(it) }, { inputFromToTo(it) })
|
||||
)
|
@@ -77,10 +77,10 @@ inline fun <FromKey, FromValue, ToKey, ToValue> ReadKeyValueRepo<ToKey, ToValue>
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> ReadKeyValueRepo<ToKey, ToValue>.withMapper(
|
||||
crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
||||
crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
|
||||
crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
|
||||
crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
|
||||
noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
||||
noinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
|
||||
noinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
|
||||
noinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
|
||||
): ReadKeyValueRepo<FromKey, FromValue> = withMapper(
|
||||
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
|
||||
)
|
||||
@@ -122,10 +122,10 @@ inline fun <FromKey, FromValue, ToKey, ToValue> WriteKeyValueRepo<ToKey, ToValue
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> WriteKeyValueRepo<ToKey, ToValue>.withMapper(
|
||||
crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
||||
crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
|
||||
crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
|
||||
crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
|
||||
noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
||||
noinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
|
||||
noinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
|
||||
noinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
|
||||
): WriteKeyValueRepo<FromKey, FromValue> = withMapper(
|
||||
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
|
||||
)
|
||||
@@ -148,10 +148,10 @@ inline fun <FromKey, FromValue, ToKey, ToValue> KeyValueRepo<ToKey, ToValue>.wit
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> KeyValueRepo<ToKey, ToValue>.withMapper(
|
||||
crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
||||
crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
|
||||
crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
|
||||
crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
|
||||
noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
||||
noinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
|
||||
noinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
|
||||
noinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
|
||||
): KeyValueRepo<FromKey, FromValue> = withMapper(
|
||||
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
|
||||
)
|
||||
|
@@ -75,10 +75,10 @@ inline fun <FromKey, FromValue, ToKey, ToValue> ReadKeyValuesRepo<ToKey, ToValue
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> ReadKeyValuesRepo<ToKey, ToValue>.withMapper(
|
||||
crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
||||
crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
|
||||
crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
|
||||
crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
|
||||
noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
||||
noinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
|
||||
noinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
|
||||
noinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
|
||||
): ReadKeyValuesRepo<FromKey, FromValue> = withMapper(
|
||||
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
|
||||
)
|
||||
@@ -128,10 +128,10 @@ inline fun <FromKey, FromValue, ToKey, ToValue> WriteKeyValuesRepo<ToKey, ToValu
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> WriteKeyValuesRepo<ToKey, ToValue>.withMapper(
|
||||
crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
||||
crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
|
||||
crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
|
||||
crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
|
||||
noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
||||
noinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
|
||||
noinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
|
||||
noinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
|
||||
): WriteKeyValuesRepo<FromKey, FromValue> = withMapper(
|
||||
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
|
||||
)
|
||||
@@ -154,10 +154,10 @@ inline fun <FromKey, FromValue, ToKey, ToValue> KeyValuesRepo<ToKey, ToValue>.wi
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> KeyValuesRepo<ToKey, ToValue>.withMapper(
|
||||
crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
||||
crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
|
||||
crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
|
||||
crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
|
||||
noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
|
||||
noinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
|
||||
noinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
|
||||
noinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
|
||||
): KeyValuesRepo<FromKey, FromValue> = withMapper(
|
||||
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
|
||||
)
|
||||
|
@@ -99,7 +99,9 @@ class FileWriteKeyValueRepo(
|
||||
override val onValueRemoved: Flow<String> = _onValueRemoved.asSharedFlow()
|
||||
|
||||
init {
|
||||
folder.mkdirs()
|
||||
if (!folder.mkdirs() && !folder.exists()) {
|
||||
error("Unable to create folder ${folder.absolutePath}")
|
||||
}
|
||||
filesChangedProcessingScope ?.let {
|
||||
it.launch {
|
||||
try {
|
||||
@@ -144,15 +146,17 @@ class FileWriteKeyValueRepo(
|
||||
}
|
||||
|
||||
override suspend fun set(toSet: Map<String, File>) {
|
||||
supervisorScope {
|
||||
toSet.map { (filename, fileSource) ->
|
||||
launch {
|
||||
val file = File(folder, filename)
|
||||
val scope = CoroutineScope(currentCoroutineContext())
|
||||
toSet.map { (filename, fileSource) ->
|
||||
scope.launch {
|
||||
val file = File(folder, filename)
|
||||
|
||||
file.delete()
|
||||
fileSource.copyTo(file, overwrite = true)
|
||||
_onNewValue.emit(filename to file)
|
||||
file.delete()
|
||||
fileSource.copyTo(file, overwrite = true)
|
||||
if (!file.exists()) {
|
||||
error("Can't create file $file with new content")
|
||||
}
|
||||
_onNewValue.emit(filename to file)
|
||||
}
|
||||
}.joinAll()
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
swagger: "2.0"
|
||||
openapi: "3.0.0"
|
||||
info:
|
||||
description: "This is a template for the CRUD repositories from [microutils](https://github.com/InsanusMokrassar/MicroUtils/tree/master/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/crud)"
|
||||
version: "0.11.0"
|
||||
version: "0.11.3"
|
||||
title: "CRUD Repo"
|
||||
contact:
|
||||
email: "ovsyannikov.alexey95@gmail.com"
|
||||
@@ -11,91 +11,61 @@ tags:
|
||||
- name: "Write"
|
||||
description: "Operations with `post` request in most cases"
|
||||
|
||||
parameters:
|
||||
IdInQuery:
|
||||
in: "query"
|
||||
name: "id"
|
||||
allOf:
|
||||
- $ref: "#/definitions/Key"
|
||||
IdsInBody:
|
||||
in: "body"
|
||||
name: "body"
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/Key"
|
||||
NewValuesInBody:
|
||||
in: "body"
|
||||
name: "body"
|
||||
type: array
|
||||
allOf:
|
||||
- $ref: "#/definitions/NewValues"
|
||||
NewValuesWithIdsInBody:
|
||||
in: "body"
|
||||
name: "body"
|
||||
type: array
|
||||
items:
|
||||
allOf:
|
||||
- $ref: "#/definitions/Pair"
|
||||
- properties:
|
||||
first:
|
||||
$ref: "#/definitions/Key"
|
||||
second:
|
||||
$ref: "#/definitions/NewValue"
|
||||
PaginationInQueryPage:
|
||||
in: "query"
|
||||
type: integer
|
||||
name: "ppage"
|
||||
description: "Page of pagination"
|
||||
required: false
|
||||
PaginationInQuerySize:
|
||||
in: "query"
|
||||
type: integer
|
||||
name: "psize"
|
||||
description: "Size of each page in pagination"
|
||||
required: false
|
||||
components:
|
||||
parameters:
|
||||
IdInQuery:
|
||||
in: "query"
|
||||
name: "id"
|
||||
schema:
|
||||
$ref: "#/components/schemas/Key"
|
||||
PaginationInQueryPage:
|
||||
in: "query"
|
||||
name: "ppage"
|
||||
description: "Page of pagination"
|
||||
schema:
|
||||
type: integer
|
||||
required: false
|
||||
PaginationInQuerySize:
|
||||
in: "query"
|
||||
name: "psize"
|
||||
description: "Size of each page in pagination"
|
||||
schema:
|
||||
type: integer
|
||||
required: false
|
||||
schemas:
|
||||
|
||||
|
||||
definitions:
|
||||
Key:
|
||||
type: integer
|
||||
description: "REWRITE THIS TYPE AS KEY IN SWAGGER FILE"
|
||||
Value:
|
||||
type: integer
|
||||
description: "REWRITE THIS TYPE AS VALUE IN SWAGGER FILE"
|
||||
Values:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/Value"
|
||||
NewValue:
|
||||
type: integer
|
||||
description: "REWRITE THIS TYPE AS NEW VALUE IN SWAGGER FILE"
|
||||
Pair:
|
||||
type: object
|
||||
description: "Pair of objects"
|
||||
properties:
|
||||
first:
|
||||
second:
|
||||
NewValues:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/NewValue"
|
||||
PaginationResult:
|
||||
type: object
|
||||
properties:
|
||||
page:
|
||||
type: integer
|
||||
description: "Page of pagination"
|
||||
pagesNumber:
|
||||
type: integer
|
||||
description: "Count of pages with the size from this pagination"
|
||||
size:
|
||||
type: integer
|
||||
description: "Size of each page in pagination"
|
||||
results:
|
||||
type: array
|
||||
description: "Array of all elements on that page. Size of pagination and size of array can be different and it can be interpreted like current page is the last one"
|
||||
items:
|
||||
type: object
|
||||
Key:
|
||||
type: integer
|
||||
description: "REWRITE THIS TYPE AS KEY IN SWAGGER FILE"
|
||||
Value:
|
||||
type: integer
|
||||
description: "REWRITE THIS TYPE AS VALUE IN SWAGGER FILE"
|
||||
NewValue:
|
||||
type: integer
|
||||
description: "REWRITE THIS TYPE AS NEW VALUE IN SWAGGER FILE"
|
||||
Pair:
|
||||
type: object
|
||||
description: "Pair of objects"
|
||||
properties:
|
||||
first:
|
||||
second:
|
||||
PaginationResult:
|
||||
type: object
|
||||
properties:
|
||||
page:
|
||||
type: integer
|
||||
description: "Page of pagination"
|
||||
pagesNumber:
|
||||
type: integer
|
||||
description: "Count of pages with the size from this pagination"
|
||||
size:
|
||||
type: integer
|
||||
description: "Size of each page in pagination"
|
||||
results:
|
||||
type: array
|
||||
description: "Array of all elements on that page. Size of pagination and size of array can be different and it can be interpreted like current page is the last one"
|
||||
items:
|
||||
type: object
|
||||
|
||||
paths:
|
||||
/getByPagination:
|
||||
@@ -103,30 +73,34 @@ paths:
|
||||
tags:
|
||||
- "Read"
|
||||
parameters:
|
||||
- $ref: "#/parameters/PaginationInQueryPage"
|
||||
- $ref: "#/parameters/PaginationInQuerySize"
|
||||
- $ref: "#/components/parameters/PaginationInQueryPage"
|
||||
- $ref: "#/components/parameters/PaginationInQuerySize"
|
||||
responses:
|
||||
"200":
|
||||
description: "Pagination with elements"
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: "#/definitions/PaginationResult"
|
||||
- properties:
|
||||
results:
|
||||
items:
|
||||
$ref: "#/definitions/Value"
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: "#/components/schemas/PaginationResult"
|
||||
- properties:
|
||||
results:
|
||||
items:
|
||||
$ref: "#/components/schemas/Value"
|
||||
/getById:
|
||||
get:
|
||||
tags:
|
||||
- "Read"
|
||||
parameters:
|
||||
- $ref: "#/parameters/IdInQuery"
|
||||
- $ref: "#/components/parameters/IdInQuery"
|
||||
required: true
|
||||
responses:
|
||||
"200":
|
||||
description: "Result object"
|
||||
schema:
|
||||
$ref: "#/definitions/Value"
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Value"
|
||||
"204":
|
||||
description: "No value by id"
|
||||
/contains:
|
||||
@@ -134,13 +108,15 @@ paths:
|
||||
tags:
|
||||
- "Read"
|
||||
parameters:
|
||||
- $ref: "#/parameters/IdInQuery"
|
||||
- $ref: "#/components/parameters/IdInQuery"
|
||||
required: true
|
||||
responses:
|
||||
"200":
|
||||
description: "Object with id availability in repo"
|
||||
schema:
|
||||
type: boolean
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: boolean
|
||||
/count:
|
||||
get:
|
||||
tags:
|
||||
@@ -148,40 +124,75 @@ paths:
|
||||
responses:
|
||||
"200":
|
||||
description: "Amount of objects in repo"
|
||||
schema:
|
||||
type: integer
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: integer
|
||||
|
||||
|
||||
/create:
|
||||
post:
|
||||
tags:
|
||||
- "Write"
|
||||
parameters:
|
||||
- $ref: "#/parameters/NewValuesInBody"
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/NewValue"
|
||||
responses:
|
||||
"200":
|
||||
description: "Objects has been created and saved"
|
||||
schema:
|
||||
$ref: "#/definitions/Values"
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Value"
|
||||
/update:
|
||||
post:
|
||||
tags:
|
||||
- "Write"
|
||||
parameters:
|
||||
- $ref: "#/parameters/NewValuesWithIdsInBody"
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
allOf:
|
||||
- $ref: "#/components/schemas/Pair"
|
||||
- properties:
|
||||
first:
|
||||
$ref: "#/components/schemas/Key"
|
||||
second:
|
||||
$ref: "#/components/schemas/NewValue"
|
||||
responses:
|
||||
"200":
|
||||
description: "Objects has been updated"
|
||||
schema:
|
||||
$ref: "#/definitions/Values"
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Value"
|
||||
/deleteById:
|
||||
post:
|
||||
tags:
|
||||
- "Write"
|
||||
parameters:
|
||||
- $ref: "#/parameters/IdsInBody"
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Key"
|
||||
responses:
|
||||
"200":
|
||||
description: "Objects has been updated"
|
||||
schema:
|
||||
$ref: "#/definitions/Values"
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Value"
|
||||
|
Reference in New Issue
Block a user