From f4af28059be33ccd7ddd722df9747db6272982f4 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Fri, 17 Feb 2023 13:45:22 +0600 Subject: [PATCH] improvements in ReadKeyValueFromCRUDRepo --- CHANGELOG.md | 3 + gradle/wrapper/gradle-wrapper.properties | 2 +- .../pagination/utils/OptionallyReverse.kt | 29 ++++++++++ .../{IterableExtensions.kt => Paginate.kt} | 56 +++++++++++-------- .../inmo/micro_utils/repos/KeyValueRepo.kt | 20 +++++-- .../repos/transforms/kv/Factories.kt | 3 + .../transforms/kv/ReadKeyValueFromCRUDRepo.kt | 46 +++++++++++++++ 7 files changed, 129 insertions(+), 30 deletions(-) create mode 100644 pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/utils/OptionallyReverse.kt rename pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/utils/{IterableExtensions.kt => Paginate.kt} (51%) create mode 100644 repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kv/ReadKeyValueFromCRUDRepo.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index da1ec448987..724f683db0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ * `Repos`: * `Cache`: * New transformer type: `ReadCRUDFromKeyValueRepo` + * New transformer type: `ReadKeyValueFromCRUDRepo` +* `Pagination`: + * New `paginate` extensions with `reversed` support for `List`/`Set` ## 0.16.9 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ae04661ee73..070cb702f09 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/utils/OptionallyReverse.kt b/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/utils/OptionallyReverse.kt new file mode 100644 index 00000000000..fc4c2a625a6 --- /dev/null +++ b/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/utils/OptionallyReverse.kt @@ -0,0 +1,29 @@ +package dev.inmo.micro_utils.pagination.utils + +fun Iterable.optionallyReverse(reverse: Boolean): Iterable = when (this) { + is List -> optionallyReverse(reverse) + is Set -> optionallyReverse(reverse) + else -> if (reverse) { + reversed() + } else { + this + } +} +fun List.optionallyReverse(reverse: Boolean): List = if (reverse) { + reversed() +} else { + this +} +fun Set.optionallyReverse(reverse: Boolean): Set = if (reverse) { + reversed().toSet() +} else { + this +} + +inline fun Array.optionallyReverse(reverse: Boolean) = if (reverse) { + Array(size) { + get(lastIndex - it) + } +} else { + this +} diff --git a/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/utils/IterableExtensions.kt b/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/utils/Paginate.kt similarity index 51% rename from pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/utils/IterableExtensions.kt rename to pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/utils/Paginate.kt index f31e5b1c3ea..6414e4aa01d 100644 --- a/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/utils/IterableExtensions.kt +++ b/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/utils/Paginate.kt @@ -32,6 +32,24 @@ fun List.paginate(with: Pagination): PaginationResult { ) } +fun List.paginate(with: Pagination, reversed: Boolean): PaginationResult { + val actualPagination = with.optionallyReverse( + size, + reversed + ) + + val firstIndex = maxOf(actualPagination.firstIndex, 0) + val lastIndex = minOf(actualPagination.lastIndexExclusive, size) + if (firstIndex > lastIndex) { + return emptyPaginationResult() + } + + return subList(firstIndex, lastIndex).optionallyReverse(reversed).createPaginationResult( + with, + size.toLong() + ) +} + fun Set.paginate(with: Pagination): PaginationResult { return this.drop(with.firstIndex).take(with.size).createPaginationResult( with, @@ -39,30 +57,20 @@ fun Set.paginate(with: Pagination): PaginationResult { ) } -fun Iterable.optionallyReverse(reverse: Boolean): Iterable = when (this) { - is List -> optionallyReverse(reverse) - is Set -> optionallyReverse(reverse) - else -> if (reverse) { - reversed() - } else { - this - } -} -fun List.optionallyReverse(reverse: Boolean): List = if (reverse) { - reversed() -} else { - this -} -fun Set.optionallyReverse(reverse: Boolean): Set = if (reverse) { - reversed().toSet() -} else { - this -} +fun Set.paginate(with: Pagination, reversed: Boolean): PaginationResult { + val actualPagination = with.optionallyReverse( + size, + reversed + ) -inline fun Array.optionallyReverse(reverse: Boolean) = if (reverse) { - Array(size) { - get(lastIndex - it) + val firstIndex = maxOf(actualPagination.firstIndex, 0) + val lastIndex = minOf(actualPagination.lastIndexExclusive, size) + if (firstIndex > lastIndex) { + return emptyPaginationResult() } -} else { - this + + return this.drop(firstIndex).take(lastIndex - firstIndex).optionallyReverse(reversed).createPaginationResult( + with, + size.toLong() + ) } diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/KeyValueRepo.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/KeyValueRepo.kt index 1faa5c4a546..97298e6d234 100644 --- a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/KeyValueRepo.kt +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/KeyValueRepo.kt @@ -2,6 +2,8 @@ package dev.inmo.micro_utils.repos import dev.inmo.micro_utils.pagination.* import dev.inmo.micro_utils.pagination.utils.doAllWithCurrentPaging +import dev.inmo.micro_utils.pagination.utils.getAllWithNextPaging +import dev.inmo.micro_utils.pagination.utils.paginate import kotlinx.coroutines.flow.Flow /** @@ -17,24 +19,32 @@ interface ReadKeyValueRepo : Repo { suspend fun get(k: Key): Value? /** - * This method should use sorted by [Key]s search and take the [PaginationResult]. By default, it should use + * This method should use sorted by [Key]s search and return the [PaginationResult]. By default, it should use * ascending sort for [Key]s */ suspend fun values(pagination: Pagination, reversed: Boolean = false): PaginationResult /** - * This method should use sorted by [Key]s search and take the [PaginationResult]. By default, it should use + * This method should use sorted by [Key]s search and return the [PaginationResult]. By default, it should use * ascending sort for [Key]s */ suspend fun keys(pagination: Pagination, reversed: Boolean = false): PaginationResult /** - * This method should use sorted by [Key]s search and take the [PaginationResult]. By default, it should use - * ascending sort for [Key]s + * This method should use sorted by [Key]s search and return the [PaginationResult]. By default, it should use + * ascending sort for [Key]s. + * + * **DEFAULT REALIZATION IS NOT OPTIMAL AND HAS BEEN ADDED TO COVER CASES OF DIFFERENT COMMON MAPPINGS AND TRANSFORMATIONS** * * @param v This value should be used to exclude from search the items with different [Value]s */ - suspend fun keys(v: Value, pagination: Pagination, reversed: Boolean = false): PaginationResult + suspend fun keys(v: Value, pagination: Pagination, reversed: Boolean = false): PaginationResult { + return getAllWithNextPaging { + keys(it) + }.filter { + get(it) == v + }.paginate(pagination, reversed) + } /** * @return true if [key] is presented in current collection or false otherwise diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kv/Factories.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kv/Factories.kt index 5edb5476565..a457aa70e80 100644 --- a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kv/Factories.kt +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kv/Factories.kt @@ -2,6 +2,7 @@ package dev.inmo.micro_utils.repos.transforms.kv import dev.inmo.micro_utils.repos.KeyValueRepo import dev.inmo.micro_utils.repos.KeyValuesRepo +import dev.inmo.micro_utils.repos.ReadCRUDRepo import dev.inmo.micro_utils.repos.ReadKeyValueRepo import dev.inmo.micro_utils.repos.ReadKeyValuesRepo import kotlin.js.JsName @@ -10,3 +11,5 @@ import kotlin.jvm.JvmName fun ReadKeyValuesRepo.asReadKeyValueRepo() = ReadKeyValueFromKeyValuesRepo(this) fun KeyValuesRepo.asKeyValueRepo() = KeyValueFromKeyValuesRepo(this) + +fun ReadCRUDRepo.asReadKeyValueRepo() = ReadKeyValueFromCRUDRepo(this) diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kv/ReadKeyValueFromCRUDRepo.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kv/ReadKeyValueFromCRUDRepo.kt new file mode 100644 index 00000000000..7e05e152c8b --- /dev/null +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kv/ReadKeyValueFromCRUDRepo.kt @@ -0,0 +1,46 @@ +package dev.inmo.micro_utils.repos.transforms.kv + +import dev.inmo.micro_utils.pagination.FirstPagePagination +import dev.inmo.micro_utils.pagination.Pagination +import dev.inmo.micro_utils.pagination.PaginationResult +import dev.inmo.micro_utils.pagination.changeResults +import dev.inmo.micro_utils.pagination.changeResultsUnchecked +import dev.inmo.micro_utils.pagination.utils.doForAllWithNextPaging +import dev.inmo.micro_utils.pagination.utils.optionallyReverse +import dev.inmo.micro_utils.pagination.utils.paginate +import dev.inmo.micro_utils.repos.ReadCRUDRepo +import dev.inmo.micro_utils.repos.ReadKeyValueRepo +import dev.inmo.micro_utils.repos.ReadKeyValuesRepo +import dev.inmo.micro_utils.repos.transforms.kvs.ReadKeyValuesFromKeyValueRepo +import kotlin.jvm.JvmInline + +@JvmInline +value class ReadKeyValueFromCRUDRepo( + private val original: ReadCRUDRepo +) : ReadKeyValueRepo { + override suspend fun get(k: Key): Value? = original.getById(k) + + override suspend fun values(pagination: Pagination, reversed: Boolean): PaginationResult = original.getByPagination( + pagination.optionallyReverse(count(), reversed) + ).let { + if (reversed) { + it.changeResultsUnchecked(it.results.reversed()) + } else { + it + } + } + + override suspend fun keys(pagination: Pagination, reversed: Boolean): PaginationResult = original.getIdsByPagination( + pagination.optionallyReverse(count(), reversed) + ).let { + if (reversed) { + it.changeResultsUnchecked(it.results.reversed()) + } else { + it + } + } + + override suspend fun count(): Long = original.count() + + override suspend fun contains(key: Key): Boolean = original.contains(key) +}