Merge pull request #287 from InsanusMokrassar/0.19.8

0.19.8
This commit is contained in:
InsanusMokrassar 2023-07-27 01:33:49 +06:00 committed by GitHub
commit 67354b43e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 149 additions and 19 deletions

View File

@ -1,5 +1,20 @@
# Changelog # Changelog
## 0.19.8
* `Versions`:
* `Coroutines`: `1.7.2` -> `1.7.3`
* `Kotlin`: `1.8.20` -> `1.8.22`
* `Compose`: `1.4.1` -> `1.4.3`
* `Okio`: `3.3.0` -> `3.4.0`
* `RecyclerView`: `1.3.0` -> `1.3.1`
* `Fragment`: `1.6.0` -> `1.6.1`
* `Repos`:
* Fixes In `KeyValueRepo.clear()` of almost all inheritors of `KeyValueRepo`
* `Cache`:
* All full caches got `skipStartInvalidate` property. By default, this property is `false` and fully caching repos
will be automatically invalidated on start of their work
## 0.19.7 ## 0.19.7
* `Versions`: * `Versions`:

View File

@ -14,5 +14,5 @@ crypto_js_version=4.1.1
# Project data # Project data
group=dev.inmo group=dev.inmo
version=0.19.7 version=0.19.8
android_code_version=203 android_code_version=204

View File

@ -1,12 +1,12 @@
[versions] [versions]
kt = "1.8.20" kt = "1.8.22"
kt-serialization = "1.5.1" kt-serialization = "1.5.1"
kt-coroutines = "1.7.2" kt-coroutines = "1.7.3"
kslog = "1.1.1" kslog = "1.1.1"
jb-compose = "1.4.1" jb-compose = "1.4.3"
jb-exposed = "0.41.1" jb-exposed = "0.41.1"
jb-dokka = "1.8.20" jb-dokka = "1.8.20"
@ -19,9 +19,9 @@ gh-release = "2.4.1"
koin = "3.4.2" koin = "3.4.2"
okio = "3.3.0" okio = "3.4.0"
ksp = "1.8.20-1.0.11" ksp = "1.8.22-1.0.11"
kotlin-poet = "1.14.2" kotlin-poet = "1.14.2"
versions = "0.47.0" versions = "0.47.0"
@ -30,9 +30,9 @@ android-gradle = "7.4.2"
dexcount = "4.0.0" dexcount = "4.0.0"
android-coreKtx = "1.10.1" android-coreKtx = "1.10.1"
android-recyclerView = "1.3.0" android-recyclerView = "1.3.1"
android-appCompat = "1.6.1" android-appCompat = "1.6.1"
android-fragment = "1.6.0" android-fragment = "1.6.1"
android-espresso = "3.5.1" android-espresso = "3.5.1"
android-test = "1.1.5" android-test = "1.1.5"

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.2-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -38,7 +38,7 @@ fun <Key, Value> ReadKeyValueRepo<Key, Value>.cached(
) = ReadKeyValueCacheRepo(this, kvCache) ) = ReadKeyValueCacheRepo(this, kvCache)
open class KeyValueCacheRepo<Key,Value>( open class KeyValueCacheRepo<Key,Value>(
parentRepo: KeyValueRepo<Key, Value>, override val parentRepo: KeyValueRepo<Key, Value>,
kvCache: KVCache<Key, Value>, kvCache: KVCache<Key, Value>,
scope: CoroutineScope = CoroutineScope(Dispatchers.Default) scope: CoroutineScope = CoroutineScope(Dispatchers.Default)
) : ReadKeyValueCacheRepo<Key,Value>(parentRepo, kvCache), KeyValueRepo<Key,Value>, WriteKeyValueRepo<Key, Value> by parentRepo, CommonCacheRepo { ) : ReadKeyValueCacheRepo<Key,Value>(parentRepo, kvCache), KeyValueRepo<Key,Value>, WriteKeyValueRepo<Key, Value> by parentRepo, CommonCacheRepo {
@ -46,6 +46,11 @@ open class KeyValueCacheRepo<Key,Value>(
protected val onRemoveJob = parentRepo.onValueRemoved.onEach { kvCache.unset(it) }.launchIn(scope) protected val onRemoveJob = parentRepo.onValueRemoved.onEach { kvCache.unset(it) }.launchIn(scope)
override suspend fun invalidate() = kvCache.clear() override suspend fun invalidate() = kvCache.clear()
override suspend fun clear() {
parentRepo.clear()
kvCache.clear()
}
} }
fun <Key, Value> KeyValueRepo<Key, Value>.cached( fun <Key, Value> KeyValueRepo<Key, Value>.cached(

View File

@ -21,6 +21,12 @@ open class SimpleFullKVCache<K, V>(
kvParent.unset(toUnset) kvParent.unset(toUnset)
} }
} }
override suspend fun clear() {
syncMutex.withLock {
kvParent.clear()
}
}
} }
inline fun <K, V> FullKVCache( inline fun <K, V> FullKVCache(

View File

@ -37,6 +37,10 @@ open class SimpleKVCache<K, V>(
override suspend fun unset(toUnset: List<K>) { override suspend fun unset(toUnset: List<K>) {
syncMutex.withLock { makeUnset(toUnset) } syncMutex.withLock { makeUnset(toUnset) }
} }
override suspend fun clear() {
syncMutex.withLock { makeUnset(cacheQueue) }
}
} }
inline fun <K, V> KVCache( inline fun <K, V> KVCache(

View File

@ -39,4 +39,9 @@ open class AutoRecacheKeyValueRepo<Id, RegisteredObject>(
).also { ).also {
kvCache.unsetWithValues(toUnset) kvCache.unsetWithValues(toUnset)
} }
override suspend fun clear() {
originalRepo.clear()
kvCache.clear()
}
} }

View File

@ -1,6 +1,7 @@
package dev.inmo.micro_utils.repos.cache.full package dev.inmo.micro_utils.repos.cache.full
import dev.inmo.micro_utils.common.* import dev.inmo.micro_utils.common.*
import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions
import dev.inmo.micro_utils.pagination.Pagination import dev.inmo.micro_utils.pagination.Pagination
import dev.inmo.micro_utils.pagination.PaginationResult import dev.inmo.micro_utils.pagination.PaginationResult
import dev.inmo.micro_utils.repos.* import dev.inmo.micro_utils.repos.*
@ -84,6 +85,7 @@ open class FullCRUDCacheRepo<ObjectType, IdType, InputValueType>(
override val parentRepo: CRUDRepo<ObjectType, IdType, InputValueType>, override val parentRepo: CRUDRepo<ObjectType, IdType, InputValueType>,
kvCache: FullKVCache<IdType, ObjectType>, kvCache: FullKVCache<IdType, ObjectType>,
scope: CoroutineScope = CoroutineScope(Dispatchers.Default), scope: CoroutineScope = CoroutineScope(Dispatchers.Default),
skipStartInvalidate: Boolean = false,
idGetter: (ObjectType) -> IdType idGetter: (ObjectType) -> IdType
) : FullReadCRUDCacheRepo<ObjectType, IdType>( ) : FullReadCRUDCacheRepo<ObjectType, IdType>(
parentRepo, parentRepo,
@ -97,6 +99,12 @@ open class FullCRUDCacheRepo<ObjectType, IdType, InputValueType>(
idGetter idGetter
), ),
CRUDRepo<ObjectType, IdType, InputValueType> { CRUDRepo<ObjectType, IdType, InputValueType> {
init {
if (!skipStartInvalidate) {
scope.launchSafelyWithoutExceptions { invalidate() }
}
}
override suspend fun invalidate() { override suspend fun invalidate() {
actualizeAll() actualizeAll()
} }
@ -105,12 +113,14 @@ open class FullCRUDCacheRepo<ObjectType, IdType, InputValueType>(
fun <ObjectType, IdType, InputType> CRUDRepo<ObjectType, IdType, InputType>.fullyCached( fun <ObjectType, IdType, InputType> CRUDRepo<ObjectType, IdType, InputType>.fullyCached(
kvCache: FullKVCache<IdType, ObjectType> = FullKVCache(), kvCache: FullKVCache<IdType, ObjectType> = FullKVCache(),
scope: CoroutineScope = CoroutineScope(Dispatchers.Default), scope: CoroutineScope = CoroutineScope(Dispatchers.Default),
skipStartInvalidate: Boolean = false,
idGetter: (ObjectType) -> IdType idGetter: (ObjectType) -> IdType
) = FullCRUDCacheRepo(this, kvCache, scope, idGetter) ) = FullCRUDCacheRepo(this, kvCache, scope, skipStartInvalidate, idGetter)
@Deprecated("Renamed", ReplaceWith("this.fullyCached(kvCache, scope, idGetter)", "dev.inmo.micro_utils.repos.cache.full.fullyCached")) @Deprecated("Renamed", ReplaceWith("this.fullyCached(kvCache, scope, idGetter)", "dev.inmo.micro_utils.repos.cache.full.fullyCached"))
fun <ObjectType, IdType, InputType> CRUDRepo<ObjectType, IdType, InputType>.cached( fun <ObjectType, IdType, InputType> CRUDRepo<ObjectType, IdType, InputType>.cached(
kvCache: FullKVCache<IdType, ObjectType>, kvCache: FullKVCache<IdType, ObjectType>,
scope: CoroutineScope = CoroutineScope(Dispatchers.Default), scope: CoroutineScope = CoroutineScope(Dispatchers.Default),
skipStartInvalidate: Boolean = false,
idGetter: (ObjectType) -> IdType idGetter: (ObjectType) -> IdType
) = fullyCached(kvCache, scope, idGetter) ) = fullyCached(kvCache, scope, skipStartInvalidate, idGetter)

View File

@ -1,6 +1,7 @@
package dev.inmo.micro_utils.repos.cache.full package dev.inmo.micro_utils.repos.cache.full
import dev.inmo.micro_utils.common.* import dev.inmo.micro_utils.common.*
import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions
import dev.inmo.micro_utils.pagination.Pagination import dev.inmo.micro_utils.pagination.Pagination
import dev.inmo.micro_utils.pagination.PaginationResult import dev.inmo.micro_utils.pagination.PaginationResult
import dev.inmo.micro_utils.repos.* import dev.inmo.micro_utils.repos.*
@ -106,15 +107,30 @@ fun <Key, Value> WriteKeyValueRepo<Key, Value>.caching(
open class FullKeyValueCacheRepo<Key,Value>( open class FullKeyValueCacheRepo<Key,Value>(
protected open val parentRepo: KeyValueRepo<Key, Value>, protected open val parentRepo: KeyValueRepo<Key, Value>,
kvCache: FullKVCache<Key, Value>, kvCache: FullKVCache<Key, Value>,
scope: CoroutineScope = CoroutineScope(Dispatchers.Default) scope: CoroutineScope = CoroutineScope(Dispatchers.Default),
skipStartInvalidate: Boolean = false
) : FullWriteKeyValueCacheRepo<Key,Value>(parentRepo, kvCache, scope), ) : FullWriteKeyValueCacheRepo<Key,Value>(parentRepo, kvCache, scope),
KeyValueRepo<Key,Value>, KeyValueRepo<Key,Value>,
ReadKeyValueRepo<Key, Value> by FullReadKeyValueCacheRepo(parentRepo, kvCache) { ReadKeyValueRepo<Key, Value> by FullReadKeyValueCacheRepo(
parentRepo,
kvCache
) {
init {
if (!skipStartInvalidate) {
scope.launchSafelyWithoutExceptions { invalidate() }
}
}
override suspend fun unsetWithValues(toUnset: List<Value>) = parentRepo.unsetWithValues(toUnset) override suspend fun unsetWithValues(toUnset: List<Value>) = parentRepo.unsetWithValues(toUnset)
override suspend fun invalidate() { override suspend fun invalidate() {
kvCache.actualizeAll(parentRepo) kvCache.actualizeAll(parentRepo)
} }
override suspend fun clear() {
parentRepo.clear()
kvCache.clear()
}
} }
fun <Key, Value> KeyValueRepo<Key, Value>.fullyCached( fun <Key, Value> KeyValueRepo<Key, Value>.fullyCached(

View File

@ -1,6 +1,7 @@
package dev.inmo.micro_utils.repos.cache.full package dev.inmo.micro_utils.repos.cache.full
import dev.inmo.micro_utils.common.* import dev.inmo.micro_utils.common.*
import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions
import dev.inmo.micro_utils.pagination.* import dev.inmo.micro_utils.pagination.*
import dev.inmo.micro_utils.pagination.utils.* import dev.inmo.micro_utils.pagination.utils.*
import dev.inmo.micro_utils.repos.* import dev.inmo.micro_utils.repos.*
@ -142,10 +143,17 @@ fun <Key, Value> WriteKeyValuesRepo<Key, Value>.caching(
open class FullKeyValuesCacheRepo<Key,Value>( open class FullKeyValuesCacheRepo<Key,Value>(
protected open val parentRepo: KeyValuesRepo<Key, Value>, protected open val parentRepo: KeyValuesRepo<Key, Value>,
kvCache: FullKVCache<Key, List<Value>>, kvCache: FullKVCache<Key, List<Value>>,
scope: CoroutineScope = CoroutineScope(Dispatchers.Default) scope: CoroutineScope = CoroutineScope(Dispatchers.Default),
skipStartInvalidate: Boolean = false
) : FullWriteKeyValuesCacheRepo<Key, Value>(parentRepo, kvCache, scope), ) : FullWriteKeyValuesCacheRepo<Key, Value>(parentRepo, kvCache, scope),
KeyValuesRepo<Key, Value>, KeyValuesRepo<Key, Value>,
ReadKeyValuesRepo<Key, Value> by FullReadKeyValuesCacheRepo(parentRepo, kvCache) { ReadKeyValuesRepo<Key, Value> by FullReadKeyValuesCacheRepo(parentRepo, kvCache) {
init {
if (!skipStartInvalidate) {
scope.launchSafelyWithoutExceptions { invalidate() }
}
}
override suspend fun clearWithValue(v: Value) { override suspend fun clearWithValue(v: Value) {
doAllWithCurrentPaging { doAllWithCurrentPaging {
keys(v, it).also { keys(v, it).also {

View File

@ -127,7 +127,11 @@ open class MapperKeyValueRepo<FromKey, FromValue, ToKey, ToValue>(
) : KeyValueRepo<FromKey, FromValue>, ) : KeyValueRepo<FromKey, FromValue>,
MapperRepo<FromKey, FromValue, ToKey, ToValue> by mapper, MapperRepo<FromKey, FromValue, ToKey, ToValue> by mapper,
ReadKeyValueRepo<FromKey, FromValue> by MapperReadKeyValueRepo(to, mapper), ReadKeyValueRepo<FromKey, FromValue> by MapperReadKeyValueRepo(to, mapper),
WriteKeyValueRepo<FromKey, FromValue> by MapperWriteKeyValueRepo(to, mapper) WriteKeyValueRepo<FromKey, FromValue> by MapperWriteKeyValueRepo(to, mapper) {
override suspend fun clear() {
to.clear()
}
}
@Suppress("NOTHING_TO_INLINE") @Suppress("NOTHING_TO_INLINE")
inline fun <FromKey, FromValue, ToKey, ToValue> KeyValueRepo<ToKey, ToValue>.withMapper( inline fun <FromKey, FromValue, ToKey, ToValue> KeyValueRepo<ToKey, ToValue>.withMapper(

View File

@ -202,9 +202,14 @@ class FileWriteKeyValueRepo(
@Warning("Files watching will not correctly works on Android Platform with version of API lower than API 26") @Warning("Files watching will not correctly works on Android Platform with version of API lower than API 26")
@Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE") @Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE")
class FileKeyValueRepo( class FileKeyValueRepo(
folder: File, private val folder: File,
filesChangedProcessingScope: CoroutineScope? = null filesChangedProcessingScope: CoroutineScope? = null
) : KeyValueRepo<String, File>, ) : KeyValueRepo<String, File>,
WriteKeyValueRepo<String, File> by FileWriteKeyValueRepo(folder, filesChangedProcessingScope), WriteKeyValueRepo<String, File> by FileWriteKeyValueRepo(folder, filesChangedProcessingScope),
ReadKeyValueRepo<String, File> by FileReadKeyValueRepo(folder) { ReadKeyValueRepo<String, File> by FileReadKeyValueRepo(folder) {
override suspend fun clear() {
withContext(Dispatchers.IO) {
folder.listFiles() ?.forEach { runCatching { it.deleteRecursively() } }
}
}
} }

View File

@ -7,6 +7,7 @@ import dev.inmo.micro_utils.pagination.*
import dev.inmo.micro_utils.pagination.utils.paginate import dev.inmo.micro_utils.pagination.utils.paginate
import dev.inmo.micro_utils.pagination.utils.reverse import dev.inmo.micro_utils.pagination.utils.reverse
import dev.inmo.micro_utils.repos.KeyValueRepo import dev.inmo.micro_utils.repos.KeyValueRepo
import dev.inmo.micro_utils.repos.pagination.maxPagePagination
import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.*
private val cache = HashMap<String, KeyValueStore<*>>() private val cache = HashMap<String, KeyValueStore<*>>()
@ -159,6 +160,24 @@ class KeyValueStore<T : Any> internal constructor (
} }
} }
override suspend fun clear() {
val keys = mutableSetOf<String>()
doWithPagination(maxPagePagination()) {
keys(it).also {
keys.addAll(it.results)
}.nextPageIfNotEmpty()
}
val success = sharedPreferences.edit().apply {
clear()
}.commit()
if (success) {
keys.forEach {
_onValueRemovedFlow.emit(it)
}
}
}
companion object { companion object {
operator fun <T : Any> invoke( operator fun <T : Any> invoke(
context: Context, context: Context,

View File

@ -73,4 +73,18 @@ abstract class AbstractExposedKeyValueRepo<Key, Value>(
_onValueRemoved.emit(it) _onValueRemoved.emit(it)
} }
} }
override suspend fun clear() {
transaction(database) {
val keys = selectAll().map { it.asKey }
deleteAll()
keys
}.also {
it.forEach {
_onValueRemoved.emit(it)
}
}
}
} }

View File

@ -6,6 +6,7 @@ import kotlinx.coroutines.flow.*
import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
import org.jetbrains.exposed.sql.SqlExpressionBuilder.inList import org.jetbrains.exposed.sql.SqlExpressionBuilder.inList
import org.jetbrains.exposed.sql.SqlExpressionBuilder.inSubQuery
import org.jetbrains.exposed.sql.transactions.transaction import org.jetbrains.exposed.sql.transactions.transaction
open class ExposedKeyValueRepo<Key, Value>( open class ExposedKeyValueRepo<Key, Value>(
@ -72,4 +73,18 @@ open class ExposedKeyValueRepo<Key, Value>(
_onValueRemoved.emit(it) _onValueRemoved.emit(it)
} }
} }
override suspend fun clear() {
transaction(database) {
val keys = selectAll().map { it.asKey }
deleteAll()
keys
}.also {
it.forEach {
_onValueRemoved.emit(it)
}
}
}
} }

View File

@ -94,6 +94,10 @@ class MapKeyValueRepo<Key, Value>(
private val map: MutableMap<Key, Value> = mutableMapOf() private val map: MutableMap<Key, Value> = mutableMapOf()
) : KeyValueRepo<Key, Value>, ) : KeyValueRepo<Key, Value>,
ReadKeyValueRepo<Key, Value> by ReadMapKeyValueRepo(map), ReadKeyValueRepo<Key, Value> by ReadMapKeyValueRepo(map),
WriteKeyValueRepo<Key, Value> by WriteMapKeyValueRepo(map) WriteKeyValueRepo<Key, Value> by WriteMapKeyValueRepo(map) {
override suspend fun clear() {
map.clear()
}
}
fun <K, V> MutableMap<K, V>.asKeyValueRepo(): KeyValueRepo<K, V> = MapKeyValueRepo(this) fun <K, V> MutableMap<K, V>.asKeyValueRepo(): KeyValueRepo<K, V> = MapKeyValueRepo(this)