ids in crud repos

This commit is contained in:
InsanusMokrassar 2022-12-02 13:46:06 +06:00
parent 04c301d1ac
commit 217e977f0d
14 changed files with 88 additions and 0 deletions

View File

@ -2,6 +2,18 @@
## 0.15.0 ## 0.15.0
* `Repos`:
* `CRUD`:
* `Common`:
* New method `ReadCRUDRepo#getIdsByPagination`
* `Android`:
* `AbstractAndroidCRUDRepo` got new abstract method `toId`
* `Exposed`:
* `CommonExposedRepo` new abstract property `asId`
* `Ktor`:
* `Client`:
* `KtorReadCRUDRepoClient` now requires `paginationIdType`
## 0.14.4 ## 0.14.4
* `Common`: * `Common`:

View File

@ -46,6 +46,12 @@ open class FullReadCRUDCacheRepo<ObjectType, IdType>(
{ if (it.results.isNotEmpty()) actualizeAll() } { if (it.results.isNotEmpty()) actualizeAll() }
) )
override suspend fun getIdsByPagination(pagination: Pagination): PaginationResult<IdType> = doOrTakeAndActualize(
{ keys(pagination).takeIf { it.results.isNotEmpty() }.optionalOrAbsentIfNull },
{ getIdsByPagination(pagination) },
{ if (it.results.isNotEmpty()) actualizeAll() }
)
override suspend fun count(): Long = doOrTakeAndActualize( override suspend fun count(): Long = doOrTakeAndActualize(
{ count().takeIf { it != 0L }.optionalOrAbsentIfNull }, { count().takeIf { it != 0L }.optionalOrAbsentIfNull },
{ count() }, { count() },

View File

@ -6,6 +6,7 @@ import kotlinx.coroutines.flow.Flow
interface ReadCRUDRepo<ObjectType, IdType> : Repo { interface ReadCRUDRepo<ObjectType, IdType> : Repo {
suspend fun getByPagination(pagination: Pagination): PaginationResult<ObjectType> suspend fun getByPagination(pagination: Pagination): PaginationResult<ObjectType>
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 count(): Long suspend fun count(): Long

View File

@ -20,6 +20,14 @@ open class MapperReadCRUDRepo<FromId, FromRegistered, ToId, ToRegistered>(
) )
} }
override suspend fun getIdsByPagination(pagination: Pagination): PaginationResult<FromId> = to.getIdsByPagination(
pagination
).let {
it.changeResultsUnchecked(
it.results.map { it.toInnerKey() }
)
}
override suspend fun count(): Long = to.count() override suspend fun count(): Long = to.count()
override suspend fun contains(id: FromId): Boolean = to.contains(id.toOutKey()) override suspend fun contains(id: FromId): Boolean = to.contains(id.toOutKey())

View File

@ -16,6 +16,7 @@ abstract class AbstractAndroidCRUDRepo<ObjectType, IdType>(
protected abstract val tableName: String protected abstract val tableName: String
protected abstract val idColumnName: String protected abstract val idColumnName: String
protected abstract suspend fun Cursor.toObject(): ObjectType protected abstract suspend fun Cursor.toObject(): ObjectType
protected abstract suspend fun Cursor.toId(): IdType
protected fun SQLiteDatabase.count(): Long = select(tableName).use { protected fun SQLiteDatabase.count(): Long = select(tableName).use {
it.count it.count
}.toLong() }.toLong()
@ -64,4 +65,23 @@ abstract class AbstractAndroidCRUDRepo<ObjectType, IdType>(
} }
} }
} }
override suspend fun getIdsByPagination(pagination: Pagination): PaginationResult<IdType> {
return helper.readableTransaction {
select(
tableName,
limit = pagination.limitClause()
).use {
if (it.moveToFirst()) {
val resultList = mutableListOf(it.toId())
while (it.moveToNext()) {
resultList.add(it.toId())
}
resultList.createPaginationResult(pagination, count())
} else {
emptyList<IdType>().createPaginationResult(pagination, 0)
}
}
}
}
} }

View File

@ -22,6 +22,17 @@ abstract class AbstractExposedReadCRUDRepo<ObjectType, IdType>(
) )
} }
} }
override suspend fun getIdsByPagination(pagination: Pagination): PaginationResult<IdType> {
return transaction(db = database) {
selectAll().paginate(pagination).map {
it.asId
}.createPaginationResult(
pagination,
selectAll().count()
)
}
}
override suspend fun getById(id: IdType): ObjectType? { override suspend fun getById(id: IdType): ObjectType? {
return transaction(db = database) { return transaction(db = database) {
select { select {

View File

@ -4,6 +4,7 @@ import org.jetbrains.exposed.sql.*
interface CommonExposedRepo<IdType, ObjectType> : ExposedRepo { interface CommonExposedRepo<IdType, ObjectType> : ExposedRepo {
val ResultRow.asObject: ObjectType val ResultRow.asObject: ObjectType
val ResultRow.asId: IdType
val selectById: ISqlExpressionBuilder.(IdType) -> Op<Boolean> val selectById: ISqlExpressionBuilder.(IdType) -> Op<Boolean>
val selectByIds: ISqlExpressionBuilder.(List<IdType>) -> Op<Boolean> val selectByIds: ISqlExpressionBuilder.(List<IdType>) -> Op<Boolean>
get() = { list -> get() = { list ->

View File

@ -15,7 +15,13 @@ abstract class AbstractExposedReadKeyValueRepo<Key, Value>(
CommonExposedRepo<Key, Value>, CommonExposedRepo<Key, Value>,
Table(tableName ?: "") { Table(tableName ?: "") {
abstract val keyColumn: Column<*> abstract val keyColumn: Column<*>
/**
* Same as [asId] in context of KeyValue repo
*/
abstract val ResultRow.asKey: Key abstract val ResultRow.asKey: Key
override val ResultRow.asId: Key
get() = asKey
abstract val selectByValue: ISqlExpressionBuilder.(Value) -> Op<Boolean> abstract val selectByValue: ISqlExpressionBuilder.(Value) -> Op<Boolean>
override suspend fun get(k: Key): Value? = transaction(database) { override suspend fun get(k: Key): Value? = transaction(database) {

View File

@ -17,6 +17,8 @@ abstract class AbstractExposedReadKeyValuesRepo<Key, Value>(
Table(tableName ?: "") { Table(tableName ?: "") {
abstract val keyColumn: Column<*> abstract val keyColumn: Column<*>
abstract val ResultRow.asKey: Key abstract val ResultRow.asKey: Key
override val ResultRow.asId: Key
get() = asKey
abstract val selectByValue: ISqlExpressionBuilder.(Value) -> Op<Boolean> abstract val selectByValue: ISqlExpressionBuilder.(Value) -> Op<Boolean>
override suspend fun count(k: Key): Long = transaction(database) { select { selectById(k) }.count() } override suspend fun count(k: Key): Long = transaction(database) { select { selectById(k) }.count() }

View File

@ -15,6 +15,13 @@ class ReadMapCRUDRepo<ObjectType, IdType>(
) )
} }
override suspend fun getIdsByPagination(pagination: Pagination): PaginationResult<IdType> {
return map.keys.drop(pagination.firstIndex).take(pagination.size).createPaginationResult(
pagination,
count()
)
}
override suspend fun getById(id: IdType): ObjectType? = map[id] override suspend fun getById(id: IdType): ObjectType? = map[id]
override suspend fun contains(id: IdType): Boolean = map.containsKey(id) override suspend fun contains(id: IdType): Boolean = map.containsKey(id)

View File

@ -28,6 +28,7 @@ class KtorCRUDRepoClient<ObjectType, IdType, InputValue> (
httpClient, httpClient,
typeInfo<ObjectType>(), typeInfo<ObjectType>(),
typeInfo<PaginationResult<ObjectType>>(), typeInfo<PaginationResult<ObjectType>>(),
typeInfo<PaginationResult<IdType>>(),
contentType, contentType,
idSerializer idSerializer
), ),

View File

@ -19,6 +19,7 @@ class KtorReadCRUDRepoClient<ObjectType, IdType> (
private val httpClient: HttpClient, private val httpClient: HttpClient,
private val objectType: TypeInfo, private val objectType: TypeInfo,
private val paginationObjectType: TypeInfo, private val paginationObjectType: TypeInfo,
private val paginationIdType: TypeInfo,
private val contentType: ContentType, private val contentType: ContentType,
private val idSerializer: suspend (IdType) -> String private val idSerializer: suspend (IdType) -> String
) : ReadCRUDRepo<ObjectType, IdType> { ) : ReadCRUDRepo<ObjectType, IdType> {
@ -27,6 +28,11 @@ class KtorReadCRUDRepoClient<ObjectType, IdType> (
) { ) {
contentType(contentType) contentType(contentType)
}.body(paginationObjectType) }.body(paginationObjectType)
override suspend fun getIdsByPagination(pagination: Pagination): PaginationResult<IdType> = httpClient.get(
buildStandardUrl(baseUrl, getIdsByPaginationRouting, pagination.asUrlQueryParts)
) {
contentType(contentType)
}.body(paginationIdType)
override suspend fun getById(id: IdType): ObjectType? = httpClient.get( override suspend fun getById(id: IdType): ObjectType? = httpClient.get(
buildStandardUrl( buildStandardUrl(
@ -72,6 +78,7 @@ inline fun <reified ObjectType, IdType> KtorReadCRUDRepoClient(
httpClient, httpClient,
typeInfo<ObjectType>(), typeInfo<ObjectType>(),
typeInfo<PaginationResult<ObjectType>>(), typeInfo<PaginationResult<ObjectType>>(),
typeInfo<PaginationResult<IdType>>(),
contentType, contentType,
idSerializer idSerializer
) )

View File

@ -1,5 +1,6 @@
package dev.inmo.micro_utils.repos.ktor.common.crud package dev.inmo.micro_utils.repos.ktor.common.crud
const val getByPaginationRouting = "getByPagination" const val getByPaginationRouting = "getByPagination"
const val getIdsByPaginationRouting = "getIdsByPagination"
const val getByIdRouting = "getById" const val getByIdRouting = "getById"
const val containsRouting = "contains" const val containsRouting = "contains"

View File

@ -23,6 +23,11 @@ inline fun <reified ObjectType, reified IdType> Route.configureReadCRUDRepoRoute
call.respond(originalRepo.getByPagination(pagination)) call.respond(originalRepo.getByPagination(pagination))
} }
get(getIdsByPaginationRouting) {
val pagination = call.request.queryParameters.extractPagination
call.respond(originalRepo.getIdsByPagination(pagination))
}
get(getByIdRouting) { get(getByIdRouting) {
val id = idDeserializer( val id = idDeserializer(