Compare commits

..

24 Commits
0.3.1 ... 0.4.1

Author SHA1 Message Date
71ff0232aa fix keyvalue exposed repo initiation 2020-11-16 20:05:22 +06:00
63921cd984 fix of shared flow size in ExposedKeyValueRepo 2020-11-16 19:48:28 +06:00
051e03bed3 start 0.4.1 2020-11-16 19:46:50 +06:00
a051394f4f Merge pull request #17 from InsanusMokrassar/0.4.0
0.4.0
2020-11-14 18:04:59 +06:00
b872babe45 new extensions withMapper 2020-11-14 17:35:11 +06:00
5a9cabc4bd add ReadStandardKeyValueRepo#keys with value parameter 2020-11-14 17:27:26 +06:00
3ba630684a new ReadOneToManyKeyValueRepo#keys 2020-11-14 16:44:28 +06:00
498cd12f94 start 0.4.0 2020-11-14 16:18:42 +06:00
062848f2e4 Merge pull request #16 from InsanusMokrassar/0.3.3
0.3.3
2020-11-12 22:20:11 +06:00
d4b4547718 plus for flows 2020-11-12 22:16:21 +06:00
22cd440dd7 start 0.3.3 2020-11-12 22:10:41 +06:00
6fc64526d4 update renaming of android parts 2020-11-11 16:29:43 +06:00
08075dfafe update min sdk for kotlin parts 2020-11-11 16:17:19 +06:00
efcb25622e fixes in gradle files 2020-11-11 16:06:44 +06:00
5ebf29d1fb Merge pull request #15 from InsanusMokrassar/0.3.2
0.3.2
2020-11-11 13:14:46 +06:00
b7d0ce3c97 formatting fix in keyvalue 2020-11-11 12:56:31 +06:00
e20929aec4 mappers workaround 2020-11-11 12:56:31 +06:00
f74167cc65 start 0.3.2 2020-11-11 12:56:31 +06:00
c55cd5342e update travis
trying to manually install packages in travis
2020-11-11 12:53:34 +06:00
237d89d611 experimentally update extension internalProject 2020-11-10 23:55:11 +06:00
aff9b52f1c update max heap size of jvm for gradle 2020-11-10 21:46:57 +06:00
d8cc6ed06e update max heap size of jvm for gradle 2020-11-10 21:46:19 +06:00
dffafa54c3 update publishing scripts 2020-11-10 20:53:08 +06:00
776a3af497 Merge pull request #14 from InsanusMokrassar/0.3.1
0.3.1
2020-11-10 19:50:57 +06:00
28 changed files with 375 additions and 27 deletions

View File

@@ -1,10 +1,23 @@
language: java
language: android
install: true
os: linux
dist: trusty
jdk: oraclejdk8
android:
components:
- tools
- platform-tools
- build-tools-30.0.2
- android-30
- add-on
- extra
before_script:
- yes | /usr/local/android-sdk/tools/bin/sdkmanager "build-tools;30.0.2"
- yes | /usr/local/android-sdk/tools/bin/sdkmanager "platforms;android-30"
jobs:
include:
- stage: build

View File

@@ -1,5 +1,34 @@
# Changelog
## 0.4.1
* `Repos`:
* Fixed error in `ExposedKeyValueRepo` related to negative size of shared flow
* Fixed error in `ExposedKeyValueRepo` related to avoiding of table initiation
## 0.4.0
* `Repos`:
* `ReadOneToManyKeyValueRepo` got `keys` method with value parameter
* All implementations inside of this library has been updated
* `ReadStandardKeyValueRepo` got `keys` method with value parameter
* All implementations inside of this library has been updated
* New extensions `withMapper`
## 0.3.3
* `Coroutines`:
* New extension `Flow<T>#plus`
## 0.3.2
* `Versions`:
* `Coroutines`: `1.4.1` -> `1.4.2`
* `Repos`:
* `Common`:
* New inline function `mapper` for simplier creating of `MapperRepo` objects
* Extensions `withMapper` for keyvalue repos and onetomany repos
## 0.3.1
**ANDROID PACKAGES**

View File

@@ -12,4 +12,7 @@ function assert_success() {
export RELEASE_MODE=true
project="$1"
assert_success ./gradlew clean "$project:clean" "$project:build" "$project:publishToMavenLocal" "$project:bintrayUpload"
assert_success ./gradlew clean
assert_success ./gradlew "$project:build"
assert_success ./gradlew "$project:publishToMavenLocal"
assert_success ./gradlew "$project:bintrayUpload"

View File

@@ -0,0 +1,8 @@
@file:Suppress("NOTHING_TO_INLINE")
package dev.inmo.micro_utils.coroutines
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.merge
inline operator fun <T> Flow<T>.plus(other: Flow<T>) = merge(this, other)

View File

@@ -12,6 +12,9 @@ android {
release {
minifyEnabled false
}
debug {
debuggable true
}
}
packagingOptions {
@@ -28,4 +31,8 @@ android {
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8.toString()
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
}

View File

@@ -10,11 +10,12 @@ allprojects {
}
internalProject = { name ->
if (releaseMode) {
"$group:$name:$version"
} else {
projectByName("$name")
}
// if (releaseMode) {
// "$group:$name:$version"
// } else {
// projectByName("$name")
// }
projectByName("$name")
}
releaseMode = (project.hasProperty('RELEASE_MODE') && project.property('RELEASE_MODE') == "true") || System.getenv('RELEASE_MODE') == "true"

View File

@@ -5,14 +5,14 @@ kotlin.incremental=true
kotlin.incremental.js=true
android.useAndroidX=true
android.enableJetifier=true
org.gradle.jvmargs=-Xmx4096m
org.gradle.jvmargs=-Xmx3072m
kotlin_version=1.4.10
kotlin_coroutines_version=1.4.1
kotlin_serialisation_core_version=1.0.1
kotlin_exposed_version=0.28.1
ktor_version=1.4.1
ktor_version=1.4.2
klockVersion=1.12.1
@@ -26,7 +26,7 @@ uuidVersion=0.2.2
core_ktx_version=1.3.2
androidx_recycler_version=1.1.0
android_minSdkVersion=24
android_minSdkVersion=19
android_compileSdkVersion=30
android_buildToolsVersion=30.0.2
dexcount_version=2.0.0-RC1
@@ -41,5 +41,5 @@ dokka_version=1.4.0
# Project data
group=dev.inmo
version=0.3.1
android_code_version=1
version=0.4.1
android_code_version=5

View File

@@ -4,7 +4,9 @@ project.group = "$group"
apply from: "$publishGradlePath"
kotlin {
android {}
android {
publishAllLibraryVariants()
}
sourceSets {
commonMain {

View File

@@ -10,7 +10,7 @@ kotlin {
nodejs()
}
android {
publishLibraryVariants("release")
publishAllLibraryVariants()
}
sourceSets {

View File

@@ -13,7 +13,17 @@ bintray {
if (directorySubname == "kotlinMultiplatform") {
it.setPath("${project.name}/${project.version}/${project.name}-${project.version}.module")
} else {
it.setPath("${project.name}-${directorySubname}/${project.version}/${project.name}-${directorySubname}-${project.version}.module")
switch (directorySubname) {
case "androidRelease":
it.setPath("${project.name}-android/${project.version}/${project.name}-android-${project.version}.module")
break
case "androidDebug":
it.setPath("${project.name}-android-debug/${project.version}/${project.name}-android-debug-${project.version}.module")
break
default:
it.setPath("${project.name}-${directorySubname}/${project.version}/${project.name}-${directorySubname}-${project.version}.module")
break
}
}
} else {
if (directorySubname == "kotlinMultiplatform" && it.getName() == "pom-default.xml") {

View File

@@ -6,4 +6,16 @@ interface MapperRepo<FromKey, FromValue, ToKey, ToValue> {
suspend fun ToKey.toInnerKey() = this as FromKey
suspend fun ToValue.toInnerValue() = this as FromValue
}
}
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> mapper(
crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
) = object : MapperRepo<FromKey, FromValue, ToKey, ToValue> {
override suspend fun FromKey.toOutKey(): ToKey = keyFromToTo()
override suspend fun FromValue.toOutValue(): ToValue = valueFromToTo()
override suspend fun ToKey.toInnerKey(): FromKey = keyToToFrom()
override suspend fun ToValue.toInnerValue(): FromValue = valueToToFrom()
}

View File

@@ -6,6 +6,7 @@ import kotlinx.coroutines.flow.Flow
interface ReadOneToManyKeyValueRepo<Key, Value> : Repo {
suspend fun get(k: Key, pagination: Pagination, reversed: Boolean = false): PaginationResult<Value>
suspend fun keys(pagination: Pagination, reversed: Boolean = false): PaginationResult<Key>
suspend fun keys(v: Value, pagination: Pagination, reversed: Boolean = false): PaginationResult<Key>
suspend fun contains(k: Key): Boolean
suspend fun contains(k: Key, v: Value): Boolean
suspend fun count(k: Key): Long

View File

@@ -8,6 +8,7 @@ interface ReadStandardKeyValueRepo<Key, Value> : Repo {
suspend fun get(k: Key): Value?
suspend fun values(pagination: Pagination, reversed: Boolean = false): PaginationResult<Value>
suspend fun keys(pagination: Pagination, reversed: Boolean = false): PaginationResult<Key>
suspend fun keys(v: Value, pagination: Pagination, reversed: Boolean = false): PaginationResult<Key>
suspend fun contains(key: Key): Boolean
suspend fun count(): Long
}

View File

@@ -44,6 +44,23 @@ open class MapperReadStandardKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
)
}
override suspend fun keys(
v: FromValue,
pagination: Pagination,
reversed: Boolean
): PaginationResult<FromKey> = to.keys(
v.toOutValue(),
pagination,
reversed
).let {
PaginationResult(
it.page,
it.pagesNumber,
it.results.map { it.toInnerKey() },
it.size
)
}
override suspend fun contains(key: FromKey): Boolean = to.contains(
key.toOutKey()
)
@@ -51,6 +68,21 @@ open class MapperReadStandardKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
override suspend fun count(): Long = to.count()
}
@Suppress("NOTHING_TO_INLINE")
inline fun <FromKey, FromValue, ToKey, ToValue> ReadStandardKeyValueRepo<ToKey, ToValue>.withMapper(
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
): ReadStandardKeyValueRepo<FromKey, FromValue> = MapperReadStandardKeyValueRepo(this, mapper)
@Suppress("NOTHING_TO_INLINE")
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> ReadStandardKeyValueRepo<ToKey, ToValue>.withMapper(
crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
): ReadStandardKeyValueRepo<FromKey, FromValue> = withMapper(
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
)
open class MapperWriteStandardKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
private val to: WriteStandardKeyValueRepo<ToKey, ToValue>,
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
@@ -75,6 +107,21 @@ open class MapperWriteStandardKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
)
}
@Suppress("NOTHING_TO_INLINE")
inline fun <FromKey, FromValue, ToKey, ToValue> WriteStandardKeyValueRepo<ToKey, ToValue>.withMapper(
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
): WriteStandardKeyValueRepo<FromKey, FromValue> = MapperWriteStandardKeyValueRepo(this, mapper)
@Suppress("NOTHING_TO_INLINE")
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> WriteStandardKeyValueRepo<ToKey, ToValue>.withMapper(
crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
): WriteStandardKeyValueRepo<FromKey, FromValue> = withMapper(
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
)
open class MapperStandardKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
private val to: StandardKeyValueRepo<ToKey, ToValue>,
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
@@ -82,3 +129,18 @@ open class MapperStandardKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
MapperRepo<FromKey, FromValue, ToKey, ToValue> by mapper,
ReadStandardKeyValueRepo<FromKey, FromValue> by MapperReadStandardKeyValueRepo(to, mapper),
WriteStandardKeyValueRepo<FromKey, FromValue> by MapperWriteStandardKeyValueRepo(to, mapper)
@Suppress("NOTHING_TO_INLINE")
inline fun <FromKey, FromValue, ToKey, ToValue> StandardKeyValueRepo<ToKey, ToValue>.withMapper(
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
): StandardKeyValueRepo<FromKey, FromValue> = MapperStandardKeyValueRepo(this, mapper)
@Suppress("NOTHING_TO_INLINE")
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> StandardKeyValueRepo<ToKey, ToValue>.withMapper(
crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
): StandardKeyValueRepo<FromKey, FromValue> = withMapper(
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
)

View File

@@ -42,6 +42,23 @@ open class MapperReadOneToManyKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
)
}
override suspend fun keys(
v: FromValue,
pagination: Pagination,
reversed: Boolean
): PaginationResult<FromKey> = 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())
@@ -49,6 +66,21 @@ open class MapperReadOneToManyKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
override suspend fun count(k: FromKey): Long = to.count(k.toOutKey())
}
@Suppress("NOTHING_TO_INLINE")
inline fun <FromKey, FromValue, ToKey, ToValue> ReadOneToManyKeyValueRepo<ToKey, ToValue>.withMapper(
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
): ReadOneToManyKeyValueRepo<FromKey, FromValue> = MapperReadOneToManyKeyValueRepo(this, mapper)
@Suppress("NOTHING_TO_INLINE")
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> ReadOneToManyKeyValueRepo<ToKey, ToValue>.withMapper(
crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
): ReadOneToManyKeyValueRepo<FromKey, FromValue> = withMapper(
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
)
open class MapperWriteOneToManyKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
private val to: WriteOneToManyKeyValueRepo<ToKey, ToValue>,
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
@@ -78,6 +110,21 @@ open class MapperWriteOneToManyKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
override suspend fun clear(k: FromKey) = to.clear(k.toOutKey())
}
@Suppress("NOTHING_TO_INLINE")
inline fun <FromKey, FromValue, ToKey, ToValue> WriteOneToManyKeyValueRepo<ToKey, ToValue>.withMapper(
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
): WriteOneToManyKeyValueRepo<FromKey, FromValue> = MapperWriteOneToManyKeyValueRepo(this, mapper)
@Suppress("NOTHING_TO_INLINE")
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> WriteOneToManyKeyValueRepo<ToKey, ToValue>.withMapper(
crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
): WriteOneToManyKeyValueRepo<FromKey, FromValue> = withMapper(
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
)
open class MapperOneToManyKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
private val to: OneToManyKeyValueRepo<ToKey, ToValue>,
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
@@ -85,3 +132,18 @@ open class MapperOneToManyKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
MapperRepo<FromKey, FromValue, ToKey, ToValue> by mapper,
ReadOneToManyKeyValueRepo<FromKey, FromValue> by MapperReadOneToManyKeyValueRepo(to, mapper),
WriteOneToManyKeyValueRepo<FromKey, FromValue> by MapperWriteOneToManyKeyValueRepo(to, mapper)
@Suppress("NOTHING_TO_INLINE")
inline fun <FromKey, FromValue, ToKey, ToValue> OneToManyKeyValueRepo<ToKey, ToValue>.withMapper(
mapper: MapperRepo<FromKey, FromValue, ToKey, ToValue>
): OneToManyKeyValueRepo<FromKey, FromValue> = MapperOneToManyKeyValueRepo(this, mapper)
@Suppress("NOTHING_TO_INLINE")
inline fun <reified FromKey, reified FromValue, reified ToKey, reified ToValue> OneToManyKeyValueRepo<ToKey, ToValue>.withMapper(
crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey },
crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue },
crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey },
crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue },
): OneToManyKeyValueRepo<FromKey, FromValue> = withMapper(
mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom)
)

View File

@@ -96,6 +96,20 @@ class KeyValueStore<T : Any> internal constructor (
}
}
override suspend fun keys(v: T, pagination: Pagination, reversed: Boolean): PaginationResult<String> {
val resultPagination = if (reversed) pagination.reverse(count()) else pagination
return sharedPreferences.all.mapNotNull { (k, value) -> if (value == v) k else null }.paginate(
resultPagination
).let {
PaginationResult(
it.page,
it.pagesNumber,
it.results.let { if (reversed) it.reversed() else it },
it.size
)
}
}
override suspend fun contains(key: String): Boolean = sharedPreferences.contains(key)
override suspend fun count(): Long = sharedPreferences.all.size.toLong()

View File

@@ -169,6 +169,33 @@ class OneToManyAndroidRepo<Key, Value>(
)
}
override suspend fun keys(
v: Value,
pagination: Pagination,
reversed: Boolean
): PaginationResult<Key> = 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<Key>().also {
if (c.moveToFirst()) {
do {
it.add(c.getString(idColumnName).asKey())
} while (c.moveToNext())
}
}
}
}.createPaginationResult(
pagination,
count
)
}
override suspend fun remove(toRemove: Map<Key, List<Value>>) {
helper.writableTransaction {
toRemove.flatMap { (k, vs) ->

View File

@@ -2,6 +2,7 @@ package dev.inmo.micro_utils.repos.exposed.keyvalue
import dev.inmo.micro_utils.repos.StandardKeyValueRepo
import dev.inmo.micro_utils.repos.exposed.ColumnAllocator
import dev.inmo.micro_utils.repos.exposed.initTable
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.*
import org.jetbrains.exposed.sql.*
@@ -18,8 +19,8 @@ open class ExposedKeyValueRepo<Key, Value>(
valueColumnAllocator,
tableName
) {
private val _onNewValue = MutableSharedFlow<Pair<Key, Value>>(Channel.BUFFERED)
private val _onValueRemoved = MutableSharedFlow<Key>(Channel.BUFFERED)
private val _onNewValue = MutableSharedFlow<Pair<Key, Value>>()
private val _onValueRemoved = MutableSharedFlow<Key>()
override val onNewValue: Flow<Pair<Key, Value>> = _onNewValue.asSharedFlow()
override val onValueRemoved: Flow<Key> = _onValueRemoved.asSharedFlow()

View File

@@ -2,8 +2,7 @@ package dev.inmo.micro_utils.repos.exposed.keyvalue
import dev.inmo.micro_utils.pagination.*
import dev.inmo.micro_utils.repos.ReadStandardKeyValueRepo
import dev.inmo.micro_utils.repos.exposed.ColumnAllocator
import dev.inmo.micro_utils.repos.exposed.ExposedRepo
import dev.inmo.micro_utils.repos.exposed.*
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.transactions.transaction
@@ -17,6 +16,8 @@ open class ExposedReadKeyValueRepo<Key, Value>(
protected val valueColumn: Column<Value> = valueColumnAllocator()
override val primaryKey: PrimaryKey = PrimaryKey(keyColumn, valueColumn)
init { initTable() }
override suspend fun get(k: Key): Value? = transaction(database) {
select { keyColumn.eq(k) }.limit(1).firstOrNull() ?.getOrNull(valueColumn)
}
@@ -33,6 +34,16 @@ open class ExposedReadKeyValueRepo<Key, Value>(
}
}.createPaginationResult(pagination, count())
override suspend fun keys(v: Value, pagination: Pagination, reversed: Boolean): PaginationResult<Key> = transaction(database) {
select { valueColumn.eq(v) }.let {
it.count() to it.paginate(pagination, keyColumn to if (reversed) SortOrder.DESC else SortOrder.ASC).map {
it[keyColumn]
}
}
}.let { (count, list) ->
list.createPaginationResult(pagination, count)
}
override suspend fun values(pagination: Pagination, reversed: Boolean): PaginationResult<Value> = transaction(database) {
selectAll().paginate(pagination, keyColumn to if (reversed) SortOrder.DESC else SortOrder.ASC).map {
it[valueColumn]

View File

@@ -39,6 +39,21 @@ open class ExposedReadOneToManyKeyValueRepo<Key, Value>(
count()
)
override suspend fun keys(
v: Value,
pagination: Pagination,
reversed: Boolean
): PaginationResult<Key> = 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()
}

View File

@@ -39,6 +39,18 @@ class ReadMapKeyValueRepo<Key, Value>(
}
}
override suspend fun keys(v: Value, pagination: Pagination, reversed: Boolean): PaginationResult<Key> {
val keys: List<Key> = map.mapNotNull { (k, value) -> if (v == value) k else null }
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(key: Key): Boolean = map.containsKey(key)
override suspend fun count(): Long = map.size.toLong()

View File

@@ -32,6 +32,18 @@ class MapReadOneToManyKeyValueRepo<Key, Value>(
}
}
override suspend fun keys(v: Value, pagination: Pagination, reversed: Boolean): PaginationResult<Key> {
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

View File

@@ -6,6 +6,7 @@ import dev.inmo.micro_utils.ktor.common.buildStandardUrl
import dev.inmo.micro_utils.pagination.*
import dev.inmo.micro_utils.repos.ReadStandardKeyValueRepo
import dev.inmo.micro_utils.repos.ktor.common.key_value.*
import dev.inmo.micro_utils.repos.ktor.common.valueParameterName
import io.ktor.client.HttpClient
import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.serializer
@@ -50,6 +51,18 @@ class KtorReadStandardKeyValueRepo<Key, Value> (
PaginationResult.serializer(keySerializer)
)
override suspend fun keys(v: Value, pagination: Pagination, reversed: Boolean): PaginationResult<Key> = client.uniget(
buildStandardUrl(
baseUrl,
keysRoute,
mapOf(
valueParameterName to valueSerializer.encodeUrlQueryValue(v),
reversedParameterName to Boolean.serializer().encodeUrlQueryValue(reversed)
) + pagination.asUrlQueryParts
),
PaginationResult.serializer(keySerializer)
)
override suspend fun contains(key: Key): Boolean = client.uniget(
buildStandardUrl(
baseUrl,

View File

@@ -5,7 +5,10 @@ import dev.inmo.micro_utils.ktor.client.uniget
import dev.inmo.micro_utils.ktor.common.buildStandardUrl
import dev.inmo.micro_utils.pagination.*
import dev.inmo.micro_utils.repos.ReadOneToManyKeyValueRepo
import dev.inmo.micro_utils.repos.ktor.common.keyParameterName
import dev.inmo.micro_utils.repos.ktor.common.one_to_many.*
import dev.inmo.micro_utils.repos.ktor.common.reversedParameterName
import dev.inmo.micro_utils.repos.ktor.common.valueParameterName
import io.ktor.client.HttpClient
import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.serializer
@@ -42,6 +45,18 @@ class KtorReadOneToManyKeyValueRepo<Key, Value> (
paginationKeyResultSerializer
)
override suspend fun keys(v: Value, pagination: Pagination, reversed: Boolean): PaginationResult<Key> = 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,

View File

@@ -0,0 +1,5 @@
package dev.inmo.micro_utils.repos.ktor.common
const val keyParameterName = "key"
const val valueParameterName = "value"
const val reversedParameterName = "reversed"

View File

@@ -1,5 +1,8 @@
package dev.inmo.micro_utils.repos.ktor.common.one_to_many
const val keyParameterName = "key"
const val valueParameterName = "value"
const val reversedParameterName = "reversed"
@Deprecated("Replaced", ReplaceWith("keyParameterName", "dev.inmo.micro_utils.repos.ktor.common.keyParameterName"))
const val keyParameterName = dev.inmo.micro_utils.repos.ktor.common.keyParameterName
@Deprecated("Replaced", ReplaceWith("valueParameterName", "dev.inmo.micro_utils.repos.ktor.common.valueParameterName"))
const val valueParameterName = dev.inmo.micro_utils.repos.ktor.common.valueParameterName
@Deprecated("Replaced", ReplaceWith("reversedParameterName", "dev.inmo.micro_utils.repos.ktor.common.reversedParameterName"))
const val reversedParameterName = dev.inmo.micro_utils.repos.ktor.common.reversedParameterName

View File

@@ -1,11 +1,11 @@
package dev.inmo.micro_utils.repos.ktor.server.key_value
import dev.inmo.micro_utils.ktor.server.decodeUrlQueryValueOrSendError
import dev.inmo.micro_utils.ktor.server.unianswer
import dev.inmo.micro_utils.ktor.server.*
import dev.inmo.micro_utils.pagination.PaginationResult
import dev.inmo.micro_utils.pagination.extractPagination
import dev.inmo.micro_utils.repos.ReadStandardKeyValueRepo
import dev.inmo.micro_utils.repos.ktor.common.key_value.*
import dev.inmo.micro_utils.repos.ktor.common.valueParameterName
import io.ktor.application.call
import io.ktor.routing.Route
import io.ktor.routing.get
@@ -49,10 +49,11 @@ fun <K, V> Route.configureReadStandartKeyValueRepoRoutes (
reversedParameterName,
Boolean.serializer()
) ?: return@get
val value = call.decodeUrlQueryValue(valueParameterName, valueSerializer)
call.unianswer(
PaginationResult.serializer(keySerializer),
originalRepo.keys(parination, reversed)
value ?.let { originalRepo.keys(value, parination, reversed) } ?: originalRepo.keys(parination, reversed)
)
}

View File

@@ -4,7 +4,11 @@ import dev.inmo.micro_utils.ktor.server.*
import dev.inmo.micro_utils.pagination.PaginationResult
import dev.inmo.micro_utils.pagination.extractPagination
import dev.inmo.micro_utils.repos.ReadOneToManyKeyValueRepo
import dev.inmo.micro_utils.repos.ktor.common.*
import dev.inmo.micro_utils.repos.ktor.common.keyParameterName
import dev.inmo.micro_utils.repos.ktor.common.one_to_many.*
import dev.inmo.micro_utils.repos.ktor.common.valueParameterName
import dev.inmo.micro_utils.repos.ktor.common.reversedParameterName
import io.ktor.application.call
import io.ktor.routing.Route
import io.ktor.routing.get
@@ -42,10 +46,14 @@ fun <Key, Value> Route.configureOneToManyReadKeyValueRepoRoutes(
reversedParameterName,
Boolean.serializer()
) ?: false
val value: Value? = call.decodeUrlQueryValue(
valueParameterName,
valueSealizer
)
call.unianswer(
paginationKeyResult,
originalRepo.keys(pagination, reversed)
value ?.let { originalRepo.keys(value, pagination, reversed) } ?: originalRepo.keys(pagination, reversed)
)
}