add MapKeyValueRepo.kt

This commit is contained in:
InsanusMokrassar 2020-10-14 18:13:40 +06:00
parent af207d78a4
commit e78961b597
9 changed files with 115 additions and 4 deletions

View File

@ -50,3 +50,8 @@ fun calculatePagesNumber(datasetSize: Int, pageSize: Int): Int =
datasetSize.toLong(),
pageSize
)
/**
* @return calculated page number which can be correctly used in [PaginationResult] as [PaginationResult.page] value
*/
fun calculatePage(firstIndex: Int, resultsSize: Int): Int = firstIndex / resultsSize

View File

@ -23,6 +23,19 @@ fun <T> List<T>.createPaginationResult(
pagination.size
)
fun <T> List<T>.createPaginationResult(
firstIndex: Int,
commonObjectsNumber: Long
) = PaginationResult(
calculatePage(firstIndex, size),
calculatePagesNumber(
commonObjectsNumber,
size
),
this,
size
)
fun <T> Pair<Long, List<T>>.createPaginationResult(
pagination: Pagination
) = second.createPaginationResult(pagination, first)

View File

@ -8,6 +8,7 @@ interface ReadStandardCRUDRepo<ObjectType, IdType> : Repo {
suspend fun getByPagination(pagination: Pagination): PaginationResult<ObjectType>
suspend fun getById(id: IdType): ObjectType?
suspend fun contains(id: IdType): Boolean
suspend fun count(): Long
}
typealias UpdatedValuePair<IdType, ValueType> = Pair<IdType, ValueType>

View File

@ -33,4 +33,6 @@ abstract class AbstractExposedReadCRUDRepo<ObjectType, IdType>(
override suspend fun contains(id: IdType): Boolean = transaction(db = database) {
select { selectById(id) }.limit(1).any()
}
override suspend fun count(): Long = transaction(db = database) { selectAll().count() }
}

View File

@ -12,13 +12,15 @@ class ReadMapCRUDRepo<ObjectType, IdType>(
map[it]
}.createPaginationResult(
pagination,
map.size.toLong()
count()
)
}
override suspend fun getById(id: IdType): ObjectType? = map[id]
override suspend fun contains(id: IdType): Boolean = map.containsKey(id)
override suspend fun count(): Long = map.size.toLong()
}
abstract class WriteMapCRUDRepo<ObjectType, IdType, InputValueType>(

View File

@ -0,0 +1,74 @@
package dev.inmo.micro_utils.repos
import dev.inmo.micro_utils.coroutines.BroadcastFlow
import dev.inmo.micro_utils.pagination.*
import kotlinx.coroutines.flow.Flow
class ReadMapKeyValueRepo<Key, Value>(
private val map: Map<Key, Value> = emptyMap()
) : StandardReadKeyValueRepo<Key, Value> {
override suspend fun get(k: Key): Value? = map[k]
override suspend fun values(
pagination: Pagination,
reversed: Boolean
): PaginationResult<Value> {
val firstIndex: Int = if (reversed) {
val size = map.size
(size - pagination.lastIndex).let { if (it < 0) 0 else it }
} else {
pagination.firstIndex
}
return map.keys.drop(firstIndex).take(pagination.size).mapNotNull { map[it] }.createPaginationResult(
firstIndex,
count()
)
}
override suspend fun keys(pagination: Pagination, reversed: Boolean): PaginationResult<Key> {
val firstIndex: Int = if (reversed) {
val size = map.size
(size - pagination.lastIndex).let { if (it < 0) 0 else it }
} else {
pagination.firstIndex
}
return map.keys.drop(firstIndex).take(pagination.size).createPaginationResult(
firstIndex,
count()
)
}
override suspend fun contains(key: Key): Boolean = map.containsKey(key)
override suspend fun count(): Long = map.size.toLong()
}
class WriteMapKeyValueRepo<Key, Value>(
private val map: MutableMap<Key, Value> = mutableMapOf()
) : StandardWriteKeyValueRepo<Key, Value> {
private val _onNewValue: BroadcastFlow<Pair<Key, Value>> = BroadcastFlow()
override val onNewValue: Flow<Pair<Key, Value>>
get() = _onNewValue
private val _onValueRemoved: BroadcastFlow<Key> = BroadcastFlow()
override val onValueRemoved: Flow<Key>
get() = _onValueRemoved
override suspend fun set(k: Key, v: Value) {
map[k] = v
_onNewValue.send(k to v)
}
override suspend fun unset(k: Key) {
map.remove(k) ?.also { _onValueRemoved.send(k) }
}
}
class MapKeyValueRepo<Key, Value>(
private val map: MutableMap<Key, Value> = mutableMapOf()
) : StandardKeyValueRepo<Key, Value>,
StandardReadKeyValueRepo<Key, Value> by ReadMapKeyValueRepo(map),
StandardWriteKeyValueRepo<Key, Value> by WriteMapKeyValueRepo(map)
fun <K, V> MutableMap<K, V>.asKeyValueRepo(): StandardKeyValueRepo<K, V> = MapKeyValueRepo(this)

View File

@ -47,4 +47,12 @@ class KtorReadStandardCrudRepo<ObjectType, IdType> (
),
Boolean.serializer()
)
override suspend fun count(): Long = client.uniget(
buildStandardUrl(
baseUrl,
countRouting
),
Long.serializer()
)
}

View File

@ -3,3 +3,4 @@ package dev.inmo.micro_utils.repos.ktor.common.crud
const val getByPaginationRouting = "getByPagination"
const val getByIdRouting = "getById"
const val containsRouting = "contains"
const val countRouting = "count"

View File

@ -2,12 +2,10 @@ package dev.inmo.micro_utils.repos.ktor.server.crud
import dev.inmo.micro_utils.ktor.server.decodeUrlQueryValueOrSendError
import dev.inmo.micro_utils.ktor.server.unianswer
import dev.inmo.micro_utils.repos.ktor.common.crud.containsRouting
import dev.inmo.micro_utils.repos.ktor.common.crud.getByIdRouting
import dev.inmo.micro_utils.repos.ktor.common.crud.getByPaginationRouting
import dev.inmo.micro_utils.pagination.PaginationResult
import dev.inmo.micro_utils.pagination.extractPagination
import dev.inmo.micro_utils.repos.ReadStandardCRUDRepo
import dev.inmo.micro_utils.repos.ktor.common.crud.*
import io.ktor.application.call
import io.ktor.routing.Route
import io.ktor.routing.get
@ -54,4 +52,11 @@ fun <ObjectType, IdType> Route.configureReadStandardCrudRepoRoutes(
originalRepo.contains(id)
)
}
get(countRouting) {
call.unianswer(
Long.serializer(),
originalRepo.count()
)
}
}