diff --git a/CHANGELOG.md b/CHANGELOG.md index 9944c55e8e5..07d8f37bbcb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## 0.4.0 +* `Repos`: + * `ReadOneToManyKeyValueRepo` got `keys` method with value parameter + * All implementations inside of this library has been updated + ## 0.3.3 * `Coroutines`: diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/OneToManyKeyValueRepo.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/OneToManyKeyValueRepo.kt index 4a4e25f0c23..4572bce20dc 100644 --- a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/OneToManyKeyValueRepo.kt +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/OneToManyKeyValueRepo.kt @@ -6,6 +6,7 @@ import kotlinx.coroutines.flow.Flow interface ReadOneToManyKeyValueRepo : Repo { suspend fun get(k: Key, pagination: Pagination, reversed: Boolean = false): PaginationResult suspend fun keys(pagination: Pagination, reversed: Boolean = false): PaginationResult + suspend fun keys(v: Value, pagination: Pagination, reversed: Boolean = false): PaginationResult suspend fun contains(k: Key): Boolean suspend fun contains(k: Key, v: Value): Boolean suspend fun count(k: Key): Long diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/mappers/OneToManyKeyValueMappers.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/mappers/OneToManyKeyValueMappers.kt index b3fbddd9db7..1e61ae461f5 100644 --- a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/mappers/OneToManyKeyValueMappers.kt +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/mappers/OneToManyKeyValueMappers.kt @@ -42,6 +42,23 @@ open class MapperReadOneToManyKeyValueRepo( ) } + override suspend fun keys( + v: FromValue, + pagination: Pagination, + reversed: Boolean + ): PaginationResult = to.keys( + v.toOutValue(), + pagination, + reversed + ).let { + PaginationResult( + it.page, + it.pagesNumber, + it.results.map { it.toInnerKey() }, + it.size + ) + } + override suspend fun contains(k: FromKey): Boolean = to.contains(k.toOutKey()) override suspend fun contains(k: FromKey, v: FromValue): Boolean = to.contains(k.toOutKey(), v.toOutValue()) diff --git a/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/onetomany/OneToManyAndroidRepo.kt b/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/onetomany/OneToManyAndroidRepo.kt index de4b6f22078..48afbe42a8f 100644 --- a/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/onetomany/OneToManyAndroidRepo.kt +++ b/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/onetomany/OneToManyAndroidRepo.kt @@ -169,6 +169,33 @@ class OneToManyAndroidRepo( ) } + override suspend fun keys( + v: Value, + pagination: Pagination, + reversed: Boolean + ): PaginationResult = count().let { count -> + val resultPagination = pagination.let { if (reversed) pagination.reverse(count) else pagination } + helper.readableTransaction { + select( + tableName, + selection = "$valueColumnName=?", + selectionArgs = arrayOf(v.asValue()), + limit = resultPagination.limitClause() + ).use { c -> + mutableListOf().also { + if (c.moveToFirst()) { + do { + it.add(c.getString(idColumnName).asKey()) + } while (c.moveToNext()) + } + } + } + }.createPaginationResult( + pagination, + count + ) + } + override suspend fun remove(toRemove: Map>) { helper.writableTransaction { toRemove.flatMap { (k, vs) -> diff --git a/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/onetomany/ExposedReadOneToManyKeyValueRepo.kt b/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/onetomany/ExposedReadOneToManyKeyValueRepo.kt index 336fc7cd95e..37d5b9f0feb 100644 --- a/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/onetomany/ExposedReadOneToManyKeyValueRepo.kt +++ b/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/onetomany/ExposedReadOneToManyKeyValueRepo.kt @@ -39,6 +39,21 @@ open class ExposedReadOneToManyKeyValueRepo( count() ) + override suspend fun keys( + v: Value, + pagination: Pagination, + reversed: Boolean + ): PaginationResult = transaction(database) { + select { valueColumn.eq(v) }.let { + it.count() to it.paginate(pagination, keyColumn, reversed).map { it[keyColumn] } + } + }.let { (count, list) -> + list.createPaginationResult( + pagination, + count + ) + } + override suspend fun contains(k: Key): Boolean = transaction(database) { select { keyColumn.eq(k) }.limit(1).any() } diff --git a/repos/inmemory/src/commonMain/kotlin/dev/inmo/micro_utils/repos/MapOneToManyKeyValueRepo.kt b/repos/inmemory/src/commonMain/kotlin/dev/inmo/micro_utils/repos/MapOneToManyKeyValueRepo.kt index 485210e40ad..48bc9c697e0 100644 --- a/repos/inmemory/src/commonMain/kotlin/dev/inmo/micro_utils/repos/MapOneToManyKeyValueRepo.kt +++ b/repos/inmemory/src/commonMain/kotlin/dev/inmo/micro_utils/repos/MapOneToManyKeyValueRepo.kt @@ -32,6 +32,18 @@ class MapReadOneToManyKeyValueRepo( } } + override suspend fun keys(v: Value, pagination: Pagination, reversed: Boolean): PaginationResult { + val keys = map.keys.filter { map[it] ?.contains(v) == true } + val actualPagination = if (reversed) pagination.reverse(keys.size) else pagination + return keys.paginate(actualPagination).let { + if (reversed) { + it.copy(results = it.results.reversed()) + } else { + it + } + } + } + override suspend fun contains(k: Key): Boolean = map.containsKey(k) override suspend fun contains(k: Key, v: Value): Boolean = map[k] ?.contains(v) == true diff --git a/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/one_to_many/KtorReadOneToManyKeyValueRepo.kt b/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/one_to_many/KtorReadOneToManyKeyValueRepo.kt index 5811374ad1c..fe96655361f 100644 --- a/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/one_to_many/KtorReadOneToManyKeyValueRepo.kt +++ b/repos/ktor/client/src/commonMain/kotlin/dev/inmo/micro_utils/repos/ktor/client/one_to_many/KtorReadOneToManyKeyValueRepo.kt @@ -42,6 +42,18 @@ class KtorReadOneToManyKeyValueRepo ( paginationKeyResultSerializer ) + override suspend fun keys(v: Value, pagination: Pagination, reversed: Boolean): PaginationResult = client.uniget( + buildStandardUrl( + baseUrl, + keysRoute, + mapOf( + valueParameterName to valueSerializer.encodeUrlQueryValue(v), + reversedParameterName to Boolean.serializer().encodeUrlQueryValue(reversed) + ) + pagination.asUrlQueryParts + ), + paginationKeyResultSerializer + ) + override suspend fun contains(k: Key): Boolean = client.uniget( buildStandardUrl( baseUrl, diff --git a/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/one_to_many/ConfigureOneToManyReadKeyValueRepoRoutes.kt b/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/one_to_many/ConfigureOneToManyReadKeyValueRepoRoutes.kt index 35c2cd7eb3d..fb872845dc7 100644 --- a/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/one_to_many/ConfigureOneToManyReadKeyValueRepoRoutes.kt +++ b/repos/ktor/server/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/ktor/server/one_to_many/ConfigureOneToManyReadKeyValueRepoRoutes.kt @@ -42,8 +42,17 @@ fun Route.configureOneToManyReadKeyValueRepoRoutes( reversedParameterName, Boolean.serializer() ) ?: false + val value: Value? = call.decodeUrlQueryValue( + valueParameterName, + valueSealizer + ) - call.unianswer( + value ?.also { + call.unianswer( + paginationKeyResult, + originalRepo.keys(value, pagination, reversed) + ) + } ?: call.unianswer( paginationKeyResult, originalRepo.keys(pagination, reversed) )