This commit is contained in:
InsanusMokrassar 2023-03-10 18:37:48 +06:00
parent afc6aeea15
commit eeebbff70d
30 changed files with 154 additions and 5 deletions

View File

@ -7,6 +7,8 @@
* `Repos`: * `Repos`:
* `Common`: * `Common`:
* By default, `getAll` for repos will take all the size of repo as page size * By default, `getAll` for repos will take all the size of repo as page size
* New extension for all built-in repos `maxPagePagination`
* All the repos got `getAll` functions
## 0.17.4 ## 0.17.4

View File

@ -2,6 +2,7 @@ package dev.inmo.micro_utils.repos.cache
import dev.inmo.micro_utils.repos.* import dev.inmo.micro_utils.repos.*
import dev.inmo.micro_utils.repos.cache.cache.KVCache import dev.inmo.micro_utils.repos.cache.cache.KVCache
import dev.inmo.micro_utils.repos.cache.util.actualizeAll
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.*
@ -15,6 +16,12 @@ open class ReadCRUDCacheRepo<ObjectType, IdType>(
kvCache.set(id, it) kvCache.set(id, it)
}) })
override suspend fun getAll(): Map<IdType, ObjectType> {
return kvCache.getAll().takeIf { it.size.toLong() == count() } ?: parentRepo.getAll().also {
kvCache.actualizeAll(true) { it }
}
}
override suspend fun contains(id: IdType): Boolean = kvCache.contains(id) || parentRepo.contains(id) override suspend fun contains(id: IdType): Boolean = kvCache.contains(id) || parentRepo.contains(id)
override suspend fun invalidate() = kvCache.clear() override suspend fun invalidate() = kvCache.clear()

View File

@ -24,6 +24,12 @@ open class ReadKeyValueCacheRepo<Key,Value>(
} }
} }
override suspend fun getAll(): Map<Key, Value> = kvCache.getAll().takeIf {
it.size.toLong() == count()
} ?: parentRepo.getAll().also {
kvCache.set(it)
}
override suspend fun invalidate() = kvCache.clear() override suspend fun invalidate() = kvCache.clear()
} }

View File

@ -52,6 +52,14 @@ open class AutoRecacheReadCRUDRepo<RegisteredObject, Id>(
kvCache.contains(id) kvCache.contains(id)
} }
override suspend fun getAll(): Map<Id, RegisteredObject> = actionWrapper.wrap {
originalRepo.getAll()
}.onSuccess {
kvCache.actualizeAll(clear = true) { it }
}.getOrElse {
kvCache.getAll()
}
override suspend fun count(): Long = actionWrapper.wrap { override suspend fun count(): Long = actionWrapper.wrap {
originalRepo.count() originalRepo.count()
}.getOrElse { }.getOrElse {

View File

@ -52,6 +52,8 @@ open class AutoRecacheReadKeyValueRepo<Id, RegisteredObject>(
kvCache.contains(key) kvCache.contains(key)
} }
override suspend fun getAll(): Map<Id, RegisteredObject> = kvCache.getAll()
override suspend fun count(): Long = actionWrapper.wrap { override suspend fun count(): Long = actionWrapper.wrap {
originalRepo.count() originalRepo.count()
}.getOrElse { }.getOrElse {

View File

@ -58,6 +58,12 @@ open class FullReadCRUDCacheRepo<ObjectType, IdType>(
{ if (it) parentRepo.getById(id) ?.let { set(id, it) } } { if (it) parentRepo.getById(id) ?.let { set(id, it) } }
) )
override suspend fun getAll(): Map<IdType, ObjectType> = doOrTakeAndActualize(
{ getAll().takeIf { it.isNotEmpty() }.optionalOrAbsentIfNull },
{ getAll() },
{ kvCache.actualizeAll(clear = true) { it } }
)
override suspend fun getById(id: IdType): ObjectType? = doOrTakeAndActualize( override suspend fun getById(id: IdType): ObjectType? = doOrTakeAndActualize(
{ get(id) ?.optional ?: Optional.absent() }, { get(id) ?.optional ?: Optional.absent() },
{ getById(id) }, { getById(id) },

View File

@ -9,7 +9,6 @@ import dev.inmo.micro_utils.repos.cache.util.actualizeAll
import dev.inmo.micro_utils.repos.pagination.getAll import dev.inmo.micro_utils.repos.pagination.getAll
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.*
open class FullReadKeyValueCacheRepo<Key,Value>( open class FullReadKeyValueCacheRepo<Key,Value>(
@ -59,6 +58,12 @@ open class FullReadKeyValueCacheRepo<Key,Value>(
{ if (it) parentRepo.get(key) ?.also { kvCache.set(key, it) } } { if (it) parentRepo.get(key) ?.also { kvCache.set(key, it) } }
) )
override suspend fun getAll(): Map<Key, Value> = doOrTakeAndActualize(
{ getAll().takeIf { it.isNotEmpty() }.optionalOrAbsentIfNull },
{ getAll() },
{ kvCache.actualizeAll(clear = true) { it } }
)
override suspend fun keys(pagination: Pagination, reversed: Boolean): PaginationResult<Key> = doOrTakeAndActualize( override suspend fun keys(pagination: Pagination, reversed: Boolean): PaginationResult<Key> = doOrTakeAndActualize(
{ keys(pagination, reversed).takeIf { it.results.isNotEmpty() }.optionalOrAbsentIfNull }, { keys(pagination, reversed).takeIf { it.results.isNotEmpty() }.optionalOrAbsentIfNull },
{ keys(pagination, reversed) }, { keys(pagination, reversed) },

View File

@ -2,8 +2,10 @@ package dev.inmo.micro_utils.repos
import dev.inmo.micro_utils.pagination.* import dev.inmo.micro_utils.pagination.*
import dev.inmo.micro_utils.pagination.utils.doAllWithCurrentPaging import dev.inmo.micro_utils.pagination.utils.doAllWithCurrentPaging
import dev.inmo.micro_utils.pagination.utils.getAllByWithNextPaging
import dev.inmo.micro_utils.pagination.utils.getAllWithNextPaging import dev.inmo.micro_utils.pagination.utils.getAllWithNextPaging
import dev.inmo.micro_utils.pagination.utils.paginate import dev.inmo.micro_utils.pagination.utils.paginate
import dev.inmo.micro_utils.repos.pagination.maxPagePagination
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
/** /**
@ -51,6 +53,16 @@ interface ReadKeyValueRepo<Key, Value> : Repo {
*/ */
suspend fun contains(key: Key): Boolean suspend fun contains(key: Key): Boolean
suspend fun getAll(): Map<Key, Value> = getAllByWithNextPaging(maxPagePagination()) {
keys(it).let {
it.changeResultsUnchecked(
it.results.mapNotNull {
it to (get(it) ?: return@mapNotNull null)
}
)
}
}.toMap()
/** /**
* @return count of all collection objects * @return count of all collection objects
*/ */

View File

@ -2,6 +2,9 @@ package dev.inmo.micro_utils.repos
import dev.inmo.micro_utils.pagination.Pagination import dev.inmo.micro_utils.pagination.Pagination
import dev.inmo.micro_utils.pagination.PaginationResult import dev.inmo.micro_utils.pagination.PaginationResult
import dev.inmo.micro_utils.pagination.changeResultsUnchecked
import dev.inmo.micro_utils.pagination.utils.getAllWithCurrentPaging
import dev.inmo.micro_utils.repos.pagination.maxPagePagination
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
interface ReadCRUDRepo<ObjectType, IdType> : Repo { interface ReadCRUDRepo<ObjectType, IdType> : Repo {
@ -9,6 +12,14 @@ interface ReadCRUDRepo<ObjectType, IdType> : Repo {
suspend fun getIdsByPagination(pagination: Pagination): PaginationResult<IdType> suspend fun getIdsByPagination(pagination: Pagination): PaginationResult<IdType>
suspend fun getById(id: IdType): ObjectType? suspend fun getById(id: IdType): ObjectType?
suspend fun contains(id: IdType): Boolean suspend fun contains(id: IdType): Boolean
suspend fun getAll(): Map<IdType, ObjectType> = getAllWithCurrentPaging(maxPagePagination()) {
getIdsByPagination(it).let {
it.changeResultsUnchecked(
it.results.mapNotNull { it to (getById(it) ?: return@mapNotNull null) }
)
}
}.toMap()
suspend fun count(): Long suspend fun count(): Long
} }
typealias ReadStandardCRUDRepo<ObjectType, IdType> = ReadCRUDRepo<ObjectType, IdType> typealias ReadStandardCRUDRepo<ObjectType, IdType> = ReadCRUDRepo<ObjectType, IdType>

View File

@ -32,6 +32,10 @@ open class MapperReadCRUDRepo<FromId, FromRegistered, ToId, ToRegistered>(
override suspend fun contains(id: FromId): Boolean = to.contains(id.toOutKey()) override suspend fun contains(id: FromId): Boolean = to.contains(id.toOutKey())
override suspend fun getAll(): Map<FromId, FromRegistered> = to.getAll().asSequence().associate { (k, v) ->
k.toInnerKey() to v.toInnerValue()
}
override suspend fun getById(id: FromId): FromRegistered? = to.getById( override suspend fun getById(id: FromId): FromRegistered? = to.getById(
id.toOutKey() id.toOutKey()
) ?.toInnerValue() ) ?.toInnerValue()

View File

@ -55,6 +55,10 @@ open class MapperReadKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
key.toOutKey() key.toOutKey()
) )
override suspend fun getAll(): Map<FromKey, FromValue> = to.getAll().map { (k, v) ->
k.toInnerKey() to v.toInnerValue()
}.toMap()
override suspend fun count(): Long = to.count() override suspend fun count(): Long = to.count()
} }

View File

@ -16,4 +16,4 @@ suspend inline fun <T, ID, REPO : ReadCRUDRepo<T, ID>> REPO.getAll(
suspend inline fun <T, ID, REPO : ReadCRUDRepo<T, ID>> REPO.getAll( suspend inline fun <T, ID, REPO : ReadCRUDRepo<T, ID>> REPO.getAll(
@Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE") @Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE")
crossinline methodCaller: suspend REPO.(Pagination) -> PaginationResult<T> crossinline methodCaller: suspend REPO.(Pagination) -> PaginationResult<T>
): List<T> = getAll(FirstPagePagination(count().toCoercedInt()), methodCaller) ): List<T> = getAll(maxPagePagination(), methodCaller)

View File

@ -19,4 +19,4 @@ suspend inline fun <Key, Value, REPO : ReadKeyValueRepo<Key, Value>> REPO.getAll
suspend inline fun <Key, Value, REPO : ReadKeyValueRepo<Key, Value>> REPO.getAll( suspend inline fun <Key, Value, REPO : ReadKeyValueRepo<Key, Value>> REPO.getAll(
@Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE") @Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE")
crossinline methodCaller: suspend REPO.(Pagination) -> PaginationResult<Key> crossinline methodCaller: suspend REPO.(Pagination) -> PaginationResult<Key>
): List<Pair<Key, Value>> = getAll(FirstPagePagination(count().toCoercedInt()), methodCaller) ): List<Pair<Key, Value>> = getAll(maxPagePagination(), methodCaller)

View File

@ -0,0 +1,11 @@
package dev.inmo.micro_utils.repos.pagination
import dev.inmo.micro_utils.common.toCoercedInt
import dev.inmo.micro_utils.pagination.FirstPagePagination
import dev.inmo.micro_utils.repos.ReadCRUDRepo
import dev.inmo.micro_utils.repos.ReadKeyValueRepo
import dev.inmo.micro_utils.repos.ReadKeyValuesRepo
suspend inline fun ReadCRUDRepo<*, *>.maxPagePagination() = FirstPagePagination(count().toCoercedInt())
suspend inline fun ReadKeyValueRepo<*, *>.maxPagePagination() = FirstPagePagination(count().toCoercedInt())
suspend inline fun ReadKeyValuesRepo<*, *>.maxPagePagination() = FirstPagePagination(count().toCoercedInt())

View File

@ -21,4 +21,4 @@ suspend inline fun <Key, Value, REPO : ReadKeyValuesRepo<Key, Value>> REPO.getAl
suspend inline fun <Key, Value, REPO : ReadKeyValuesRepo<Key, Value>> REPO.getAll( suspend inline fun <Key, Value, REPO : ReadKeyValuesRepo<Key, Value>> REPO.getAll(
@Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE") @Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE")
crossinline methodCaller: suspend REPO.(Pagination) -> PaginationResult<Key> crossinline methodCaller: suspend REPO.(Pagination) -> PaginationResult<Key>
): List<Pair<Key, List<Value>>> = getAll(FirstPagePagination(count().toCoercedInt()), methodCaller) ): List<Pair<Key, List<Value>>> = getAll(maxPagePagination(), methodCaller)

View File

@ -12,6 +12,8 @@ open class ReadCRUDFromKeyValueRepo<RegisteredType, IdType>(
override suspend fun count(): Long = original.count() override suspend fun count(): Long = original.count()
override suspend fun getAll(): Map<IdType, RegisteredType> = original.getAll()
override suspend fun getByPagination(pagination: Pagination): PaginationResult<RegisteredType> = original.values(pagination) override suspend fun getByPagination(pagination: Pagination): PaginationResult<RegisteredType> = original.values(pagination)
override suspend fun getIdsByPagination(pagination: Pagination): PaginationResult<IdType> = original.keys(pagination) override suspend fun getIdsByPagination(pagination: Pagination): PaginationResult<IdType> = original.keys(pagination)

View File

@ -11,6 +11,7 @@ import dev.inmo.micro_utils.pagination.utils.paginate
import dev.inmo.micro_utils.repos.ReadCRUDRepo import dev.inmo.micro_utils.repos.ReadCRUDRepo
import dev.inmo.micro_utils.repos.ReadKeyValueRepo import dev.inmo.micro_utils.repos.ReadKeyValueRepo
import dev.inmo.micro_utils.repos.ReadKeyValuesRepo import dev.inmo.micro_utils.repos.ReadKeyValuesRepo
import dev.inmo.micro_utils.repos.pagination.getAll
import dev.inmo.micro_utils.repos.transforms.kvs.ReadKeyValuesFromKeyValueRepo import dev.inmo.micro_utils.repos.transforms.kvs.ReadKeyValuesFromKeyValueRepo
import kotlin.jvm.JvmInline import kotlin.jvm.JvmInline
@ -40,6 +41,8 @@ value class ReadKeyValueFromCRUDRepo<Key, Value>(
} }
} }
override suspend fun getAll(): Map<Key, Value> = original.getAll()
override suspend fun count(): Long = original.count() override suspend fun count(): Long = original.count()
override suspend fun contains(key: Key): Boolean = original.contains(key) override suspend fun contains(key: Key): Boolean = original.contains(key)

View File

@ -41,6 +41,8 @@ open class ReadKeyValueFromKeyValuesRepo<Key, Value>(
return original.contains(key) return original.contains(key)
} }
override suspend fun getAll(): Map<Key, List<Value>> = original.getAll()
override suspend fun keys(v: List<Value>, pagination: Pagination, reversed: Boolean): PaginationResult<Key> { override suspend fun keys(v: List<Value>, pagination: Pagination, reversed: Boolean): PaginationResult<Key> {
val keys = mutableSetOf<Key>() val keys = mutableSetOf<Key>()

View File

@ -1,6 +1,7 @@
package dev.inmo.micro_utils.repos package dev.inmo.micro_utils.repos
import dev.inmo.micro_utils.common.Warning import dev.inmo.micro_utils.common.Warning
import dev.inmo.micro_utils.common.filename
import dev.inmo.micro_utils.pagination.* import dev.inmo.micro_utils.pagination.*
import dev.inmo.micro_utils.pagination.utils.reverse import dev.inmo.micro_utils.pagination.utils.reverse
import kotlinx.coroutines.* import kotlinx.coroutines.*
@ -94,6 +95,8 @@ class FileReadKeyValueRepo(
return File(folder, key).exists() return File(folder, key).exists()
} }
override suspend fun getAll(): Map<String, File> = (folder.listFiles() ?.toList() ?: emptyList()).associateBy { it.filename.name }
override suspend fun count(): Long = folder.list() ?.size ?.toLong() ?: 0L override suspend fun count(): Long = folder.list() ?.size ?.toLong() ?: 0L
} }

View File

@ -32,6 +32,18 @@ abstract class AbstractAndroidCRUDRepo<ObjectType, IdType>(
} }
} }
override suspend fun getAll(): Map<IdType, ObjectType> = helper.readableTransaction {
select(
tableName,
null,
""
).use {
it.map {
it.toId() to it.toObject()
}
}
}.toMap()
override suspend fun getById(id: IdType): ObjectType? = helper.readableTransaction { override suspend fun getById(id: IdType): ObjectType? = helper.readableTransaction {
select( select(
tableName, tableName,

View File

@ -104,6 +104,15 @@ class KeyValueStore<T : Any> internal constructor (
override suspend fun contains(key: String): Boolean = sharedPreferences.contains(key) override suspend fun contains(key: String): Boolean = sharedPreferences.contains(key)
override suspend fun getAll(): Map<String, T> {
val resultMap = mutableMapOf<String, T>()
sharedPreferences.all.forEach { (k, v) ->
@Suppress("UNCHECKED_CAST")
resultMap[k] = (v as? T) ?: return@forEach
}
return resultMap.toMap()
}
override suspend fun count(): Long = sharedPreferences.all.size.toLong() override suspend fun count(): Long = sharedPreferences.all.size.toLong()
override suspend fun set(toSet: Map<String, T>) { override suspend fun set(toSet: Map<String, T>) {

View File

@ -45,5 +45,9 @@ abstract class AbstractExposedReadCRUDRepo<ObjectType, IdType>(
select { selectById(id) }.limit(1).any() select { selectById(id) }.limit(1).any()
} }
override suspend fun getAll(): Map<IdType, ObjectType> = transaction(database) {
selectAll().associate { it.asId to it.asObject }
}
override suspend fun count(): Long = transaction(db = database) { selectAll().count() } override suspend fun count(): Long = transaction(db = database) { selectAll().count() }
} }

View File

@ -5,7 +5,6 @@ import dev.inmo.micro_utils.repos.ReadKeyValueRepo
import dev.inmo.micro_utils.repos.exposed.* import dev.inmo.micro_utils.repos.exposed.*
import dev.inmo.micro_utils.repos.exposed.utils.selectPaginated import dev.inmo.micro_utils.repos.exposed.utils.selectPaginated
import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
import org.jetbrains.exposed.sql.transactions.transaction import org.jetbrains.exposed.sql.transactions.transaction
abstract class AbstractExposedReadKeyValueRepo<Key, Value>( abstract class AbstractExposedReadKeyValueRepo<Key, Value>(
@ -32,6 +31,8 @@ abstract class AbstractExposedReadKeyValueRepo<Key, Value>(
select { selectById(key) }.limit(1).any() select { selectById(key) }.limit(1).any()
} }
override suspend fun getAll(): Map<Key, Value> = transaction(database) { selectAll().associate { it.asKey to it.asObject } }
override suspend fun count(): Long = transaction(database) { selectAll().count() } override suspend fun count(): Long = transaction(database) { selectAll().count() }
override suspend fun keys(pagination: Pagination, reversed: Boolean): PaginationResult<Key> = transaction(database) { override suspend fun keys(pagination: Pagination, reversed: Boolean): PaginationResult<Key> = transaction(database) {

View File

@ -26,6 +26,8 @@ class ReadMapCRUDRepo<ObjectType, IdType>(
override suspend fun contains(id: IdType): Boolean = map.containsKey(id) override suspend fun contains(id: IdType): Boolean = map.containsKey(id)
override suspend fun getAll(): Map<IdType, ObjectType> = map.toMap()
override suspend fun count(): Long = map.size.toLong() override suspend fun count(): Long = map.size.toLong()
} }

View File

@ -51,6 +51,8 @@ class ReadMapKeyValueRepo<Key, Value>(
} }
} }
override suspend fun getAll(): Map<Key, Value> = map.toMap()
override suspend fun contains(key: Key): Boolean = map.containsKey(key) override suspend fun contains(key: Key): Boolean = map.containsKey(key)
override suspend fun count(): Long = map.size.toLong() override suspend fun count(): Long = map.size.toLong()

View File

@ -5,6 +5,7 @@ import dev.inmo.micro_utils.pagination.*
import dev.inmo.micro_utils.repos.ReadCRUDRepo import dev.inmo.micro_utils.repos.ReadCRUDRepo
import dev.inmo.micro_utils.repos.ktor.common.countRouting import dev.inmo.micro_utils.repos.ktor.common.countRouting
import dev.inmo.micro_utils.repos.ktor.common.crud.* import dev.inmo.micro_utils.repos.ktor.common.crud.*
import dev.inmo.micro_utils.repos.ktor.common.getAllRoute
import dev.inmo.micro_utils.repos.ktor.common.idParameterName import dev.inmo.micro_utils.repos.ktor.common.idParameterName
import io.ktor.client.HttpClient import io.ktor.client.HttpClient
import io.ktor.client.call.body import io.ktor.client.call.body
@ -58,6 +59,15 @@ class KtorReadCRUDRepoClient<ObjectType, IdType> (
contentType(contentType) contentType(contentType)
}.body() }.body()
override suspend fun getAll(): Map<IdType, ObjectType> = httpClient.get(
buildStandardUrl(
baseUrl,
getAllRoute
)
) {
contentType(contentType)
}.body()
override suspend fun count(): Long = httpClient.get( override suspend fun count(): Long = httpClient.get(
buildStandardUrl( buildStandardUrl(
baseUrl, baseUrl,

View File

@ -48,6 +48,15 @@ class KtorReadKeyValueRepoClient<Key, Value>(
contentType(contentType) contentType(contentType)
}.body() }.body()
override suspend fun getAll(): Map<Key, Value> = httpClient.get(
buildStandardUrl(
baseUrl,
getAllRoute
)
) {
contentType(contentType)
}.body()
override suspend fun values( override suspend fun values(
pagination: Pagination, pagination: Pagination,
reversed: Boolean reversed: Boolean

View File

@ -0,0 +1,3 @@
package dev.inmo.micro_utils.repos.ktor.common
const val getAllRoute = "getAll"

View File

@ -6,6 +6,7 @@ import dev.inmo.micro_utils.pagination.extractPagination
import dev.inmo.micro_utils.repos.ReadCRUDRepo import dev.inmo.micro_utils.repos.ReadCRUDRepo
import dev.inmo.micro_utils.repos.ktor.common.countRouting import dev.inmo.micro_utils.repos.ktor.common.countRouting
import dev.inmo.micro_utils.repos.ktor.common.crud.* import dev.inmo.micro_utils.repos.ktor.common.crud.*
import dev.inmo.micro_utils.repos.ktor.common.getAllRoute
import dev.inmo.micro_utils.repos.ktor.common.idParameterName import dev.inmo.micro_utils.repos.ktor.common.idParameterName
import io.ktor.http.HttpStatusCode import io.ktor.http.HttpStatusCode
import io.ktor.server.application.call import io.ktor.server.application.call
@ -53,6 +54,10 @@ inline fun <reified ObjectType, reified IdType> Route.configureReadCRUDRepoRoute
) )
} }
get(getAllRoute) {
call.respond(originalRepo.getAll())
}
get(countRouting) { get(countRouting) {
call.respond( call.respond(
originalRepo.count() originalRepo.count()

View File

@ -70,6 +70,10 @@ inline fun <reified Key, reified Value> Route.configureReadKeyValueRepoRoutes (
call.respond(originalRepo.contains(key)) call.respond(originalRepo.contains(key))
} }
get(getAllRoute) {
call.respond(originalRepo.getAll())
}
get(countRoute) { get(countRoute) {
call.respond(originalRepo.count()) call.respond(originalRepo.count())
} }