diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kv/ReadKeyValueFromKeyValuesRepo.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kv/ReadKeyValueFromKeyValuesRepo.kt new file mode 100644 index 00000000000..1f6582da2b4 --- /dev/null +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kv/ReadKeyValueFromKeyValuesRepo.kt @@ -0,0 +1,69 @@ +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.ReadKeyValueRepo +import dev.inmo.micro_utils.repos.ReadKeyValuesRepo +import dev.inmo.micro_utils.repos.transforms.kvs.ReadKeyValuesFromKeyValueRepo + +open class ReadKeyValueFromKeyValuesRepo( + private val original: ReadKeyValuesRepo +) : ReadKeyValueRepo> { + override suspend fun get(k: Key): List? = original.getAll(k) + + override suspend fun values( + pagination: Pagination, + reversed: Boolean + ): PaginationResult> { + val keys = keys(pagination, reversed) + return keys.changeResults( + keys.results.mapNotNull { + get(it) + } + ) + } + + override suspend fun keys(pagination: Pagination, reversed: Boolean): PaginationResult { + return original.keys(pagination, reversed) + } + + override suspend fun count(): Long { + return original.count() + } + + override suspend fun contains(key: Key): Boolean { + return original.contains(key) + } + + override suspend fun keys(v: List, pagination: Pagination, reversed: Boolean): PaginationResult { + val keys = mutableSetOf() + + doForAllWithNextPaging(FirstPagePagination(count().toInt())) { + original.keys(it).also { + it.results.forEach { + val values = get(it) ?: return@forEach + if (values.containsAll(v) && v.containsAll(values)) { + keys.add(it) + } + } + } + } + + val paginated = keys.paginate( + pagination.optionallyReverse(keys.count(), reversed) + ) + return if (reversed) { + paginated.changeResultsUnchecked(paginated.results.reversed()) + } else { + paginated + } + } +} + +fun ReadKeyValuesRepo.asReadKeyValueRepo() = ReadKeyValueFromKeyValuesRepo(this) diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kvs/ReadKeyValuesFromKeyValueRepo.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kvs/ReadKeyValuesFromKeyValueRepo.kt new file mode 100644 index 00000000000..cb9d752f9c2 --- /dev/null +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/transforms/kvs/ReadKeyValuesFromKeyValueRepo.kt @@ -0,0 +1,74 @@ +package dev.inmo.micro_utils.repos.transforms.kvs + +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.changeResultsUnchecked +import dev.inmo.micro_utils.pagination.emptyPaginationResult +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.ReadKeyValueRepo +import dev.inmo.micro_utils.repos.ReadKeyValuesRepo + +open class ReadKeyValuesFromKeyValueRepo>( + private val original: ReadKeyValueRepo +) : ReadKeyValuesRepo { + override suspend fun get( + k: Key, + pagination: Pagination, + reversed: Boolean + ): PaginationResult { + val iterable = original.get(k) ?: return emptyPaginationResult(pagination) + val paginated = iterable.paginate( + pagination.optionallyReverse(iterable.count(), reversed) + ) + return if (reversed) { + paginated.changeResultsUnchecked(paginated.results.reversed()) + } else { + paginated + } + } + + override suspend fun keys( + pagination: Pagination, + reversed: Boolean + ): PaginationResult = original.keys(pagination, reversed) + + override suspend fun count(): Long = original.count() + + override suspend fun count(k: Key): Long = original.get(k) ?.count() ?.toLong() ?: 0L + + override suspend fun contains(k: Key, v: Value): Boolean = original.get(k) ?.contains(v) == true + + override suspend fun contains(k: Key): Boolean = original.contains(k) + + override suspend fun keys( + v: Value, + pagination: Pagination, + reversed: Boolean + ): PaginationResult { + val keys = mutableSetOf() + + doForAllWithNextPaging(FirstPagePagination(count().toInt())) { + original.keys(it).also { + it.results.forEach { + if (contains(it, v)) { + keys.add(it) + } + } + } + } + + val paginated = keys.paginate( + pagination.optionallyReverse(keys.count(), reversed) + ) + return if (reversed) { + paginated.changeResultsUnchecked(paginated.results.reversed()) + } else { + paginated + } + } +} + +fun > ReadKeyValueRepo.asReadKeyValuesRepo() = ReadKeyValuesFromKeyValueRepo(this)