diff --git a/CHANGELOG.md b/CHANGELOG.md index 068caa1b3c7..062c40c4bdf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # 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 * `Versions`: diff --git a/gradle.properties b/gradle.properties index 6e4c696e98a..7829fb7f8de 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,5 +14,5 @@ crypto_js_version=4.1.1 # Project data group=dev.inmo -version=0.19.7 -android_code_version=203 +version=0.19.8 +android_code_version=204 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f7937dfe304..c1c1b8b9ec6 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,12 +1,12 @@ [versions] -kt = "1.8.20" +kt = "1.8.22" kt-serialization = "1.5.1" -kt-coroutines = "1.7.2" +kt-coroutines = "1.7.3" kslog = "1.1.1" -jb-compose = "1.4.1" +jb-compose = "1.4.3" jb-exposed = "0.41.1" jb-dokka = "1.8.20" @@ -19,9 +19,9 @@ gh-release = "2.4.1" 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" versions = "0.47.0" @@ -30,9 +30,9 @@ android-gradle = "7.4.2" dexcount = "4.0.0" android-coreKtx = "1.10.1" -android-recyclerView = "1.3.0" +android-recyclerView = "1.3.1" android-appCompat = "1.6.1" -android-fragment = "1.6.0" +android-fragment = "1.6.1" android-espresso = "3.5.1" android-test = "1.1.5" diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 774fae87671..98debb84d51 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.6.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/KeyValueCacheRepo.kt b/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/KeyValueCacheRepo.kt index 53203664e43..aba9a20c00e 100644 --- a/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/KeyValueCacheRepo.kt +++ b/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/KeyValueCacheRepo.kt @@ -38,7 +38,7 @@ fun ReadKeyValueRepo.cached( ) = ReadKeyValueCacheRepo(this, kvCache) open class KeyValueCacheRepo( - parentRepo: KeyValueRepo, + override val parentRepo: KeyValueRepo, kvCache: KVCache, scope: CoroutineScope = CoroutineScope(Dispatchers.Default) ) : ReadKeyValueCacheRepo(parentRepo, kvCache), KeyValueRepo, WriteKeyValueRepo by parentRepo, CommonCacheRepo { @@ -46,6 +46,11 @@ open class KeyValueCacheRepo( protected val onRemoveJob = parentRepo.onValueRemoved.onEach { kvCache.unset(it) }.launchIn(scope) override suspend fun invalidate() = kvCache.clear() + + override suspend fun clear() { + parentRepo.clear() + kvCache.clear() + } } fun KeyValueRepo.cached( diff --git a/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/cache/SimpleFullKVCache.kt b/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/cache/SimpleFullKVCache.kt index a5ee4639b3d..2514b84068b 100644 --- a/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/cache/SimpleFullKVCache.kt +++ b/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/cache/SimpleFullKVCache.kt @@ -21,6 +21,12 @@ open class SimpleFullKVCache( kvParent.unset(toUnset) } } + + override suspend fun clear() { + syncMutex.withLock { + kvParent.clear() + } + } } inline fun FullKVCache( diff --git a/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/cache/SimpleKVCache.kt b/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/cache/SimpleKVCache.kt index e3321a5fca1..75d91874641 100644 --- a/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/cache/SimpleKVCache.kt +++ b/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/cache/SimpleKVCache.kt @@ -37,6 +37,10 @@ open class SimpleKVCache( override suspend fun unset(toUnset: List) { syncMutex.withLock { makeUnset(toUnset) } } + + override suspend fun clear() { + syncMutex.withLock { makeUnset(cacheQueue) } + } } inline fun KVCache( diff --git a/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/fallback/keyvalue/AutoRecacheKeyValueRepo.kt b/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/fallback/keyvalue/AutoRecacheKeyValueRepo.kt index e1864829e3c..42f5d05e574 100644 --- a/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/fallback/keyvalue/AutoRecacheKeyValueRepo.kt +++ b/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/fallback/keyvalue/AutoRecacheKeyValueRepo.kt @@ -39,4 +39,9 @@ open class AutoRecacheKeyValueRepo( ).also { kvCache.unsetWithValues(toUnset) } + + override suspend fun clear() { + originalRepo.clear() + kvCache.clear() + } } diff --git a/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/full/FullCRUDCacheRepo.kt b/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/full/FullCRUDCacheRepo.kt index f5b55e92148..d1868173dbc 100644 --- a/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/full/FullCRUDCacheRepo.kt +++ b/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/full/FullCRUDCacheRepo.kt @@ -1,6 +1,7 @@ package dev.inmo.micro_utils.repos.cache.full 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.PaginationResult import dev.inmo.micro_utils.repos.* @@ -84,6 +85,7 @@ open class FullCRUDCacheRepo( override val parentRepo: CRUDRepo, kvCache: FullKVCache, scope: CoroutineScope = CoroutineScope(Dispatchers.Default), + skipStartInvalidate: Boolean = false, idGetter: (ObjectType) -> IdType ) : FullReadCRUDCacheRepo( parentRepo, @@ -97,6 +99,12 @@ open class FullCRUDCacheRepo( idGetter ), CRUDRepo { + init { + if (!skipStartInvalidate) { + scope.launchSafelyWithoutExceptions { invalidate() } + } + } + override suspend fun invalidate() { actualizeAll() } @@ -105,12 +113,14 @@ open class FullCRUDCacheRepo( fun CRUDRepo.fullyCached( kvCache: FullKVCache = FullKVCache(), scope: CoroutineScope = CoroutineScope(Dispatchers.Default), + skipStartInvalidate: Boolean = false, 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")) fun CRUDRepo.cached( kvCache: FullKVCache, scope: CoroutineScope = CoroutineScope(Dispatchers.Default), + skipStartInvalidate: Boolean = false, idGetter: (ObjectType) -> IdType -) = fullyCached(kvCache, scope, idGetter) +) = fullyCached(kvCache, scope, skipStartInvalidate, idGetter) diff --git a/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/full/FullKeyValueCacheRepo.kt b/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/full/FullKeyValueCacheRepo.kt index 39e96edc1a8..e75d9ef95be 100644 --- a/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/full/FullKeyValueCacheRepo.kt +++ b/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/full/FullKeyValueCacheRepo.kt @@ -1,6 +1,7 @@ package dev.inmo.micro_utils.repos.cache.full 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.PaginationResult import dev.inmo.micro_utils.repos.* @@ -106,15 +107,30 @@ fun WriteKeyValueRepo.caching( open class FullKeyValueCacheRepo( protected open val parentRepo: KeyValueRepo, kvCache: FullKVCache, - scope: CoroutineScope = CoroutineScope(Dispatchers.Default) + scope: CoroutineScope = CoroutineScope(Dispatchers.Default), + skipStartInvalidate: Boolean = false ) : FullWriteKeyValueCacheRepo(parentRepo, kvCache, scope), KeyValueRepo, - ReadKeyValueRepo by FullReadKeyValueCacheRepo(parentRepo, kvCache) { + ReadKeyValueRepo by FullReadKeyValueCacheRepo( + parentRepo, + kvCache +) { + init { + if (!skipStartInvalidate) { + scope.launchSafelyWithoutExceptions { invalidate() } + } + } + override suspend fun unsetWithValues(toUnset: List) = parentRepo.unsetWithValues(toUnset) override suspend fun invalidate() { kvCache.actualizeAll(parentRepo) } + + override suspend fun clear() { + parentRepo.clear() + kvCache.clear() + } } fun KeyValueRepo.fullyCached( diff --git a/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/full/FullKeyValuesCacheRepo.kt b/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/full/FullKeyValuesCacheRepo.kt index 0946cb5c8fe..8d7ea99e5d1 100644 --- a/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/full/FullKeyValuesCacheRepo.kt +++ b/repos/cache/src/commonMain/kotlin/dev/inmo/micro_utils/repos/cache/full/FullKeyValuesCacheRepo.kt @@ -1,6 +1,7 @@ package dev.inmo.micro_utils.repos.cache.full 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.utils.* import dev.inmo.micro_utils.repos.* @@ -142,10 +143,17 @@ fun WriteKeyValuesRepo.caching( open class FullKeyValuesCacheRepo( protected open val parentRepo: KeyValuesRepo, kvCache: FullKVCache>, - scope: CoroutineScope = CoroutineScope(Dispatchers.Default) + scope: CoroutineScope = CoroutineScope(Dispatchers.Default), + skipStartInvalidate: Boolean = false ) : FullWriteKeyValuesCacheRepo(parentRepo, kvCache, scope), KeyValuesRepo, ReadKeyValuesRepo by FullReadKeyValuesCacheRepo(parentRepo, kvCache) { + init { + if (!skipStartInvalidate) { + scope.launchSafelyWithoutExceptions { invalidate() } + } + } + override suspend fun clearWithValue(v: Value) { doAllWithCurrentPaging { keys(v, it).also { diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/mappers/KeyValueMappers.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/mappers/KeyValueMappers.kt index 15b9fb1c078..da1530a9495 100644 --- a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/mappers/KeyValueMappers.kt +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/mappers/KeyValueMappers.kt @@ -127,7 +127,11 @@ open class MapperKeyValueRepo( ) : KeyValueRepo, MapperRepo by mapper, ReadKeyValueRepo by MapperReadKeyValueRepo(to, mapper), - WriteKeyValueRepo by MapperWriteKeyValueRepo(to, mapper) + WriteKeyValueRepo by MapperWriteKeyValueRepo(to, mapper) { + override suspend fun clear() { + to.clear() + } +} @Suppress("NOTHING_TO_INLINE") inline fun KeyValueRepo.withMapper( diff --git a/repos/common/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/FileKeyValueRepo.kt b/repos/common/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/FileKeyValueRepo.kt index 6bc619365fe..6433f7146c2 100644 --- a/repos/common/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/FileKeyValueRepo.kt +++ b/repos/common/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/FileKeyValueRepo.kt @@ -202,9 +202,14 @@ class FileWriteKeyValueRepo( @Warning("Files watching will not correctly works on Android Platform with version of API lower than API 26") @Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE") class FileKeyValueRepo( - folder: File, + private val folder: File, filesChangedProcessingScope: CoroutineScope? = null ) : KeyValueRepo, WriteKeyValueRepo by FileWriteKeyValueRepo(folder, filesChangedProcessingScope), ReadKeyValueRepo by FileReadKeyValueRepo(folder) { + override suspend fun clear() { + withContext(Dispatchers.IO) { + folder.listFiles() ?.forEach { runCatching { it.deleteRecursively() } } + } + } } diff --git a/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/keyvalue/KeyValueStore.kt b/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/keyvalue/KeyValueStore.kt index 6cd00e7f151..34cf52aa862 100644 --- a/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/keyvalue/KeyValueStore.kt +++ b/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/keyvalue/KeyValueStore.kt @@ -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.reverse import dev.inmo.micro_utils.repos.KeyValueRepo +import dev.inmo.micro_utils.repos.pagination.maxPagePagination import kotlinx.coroutines.flow.* private val cache = HashMap>() @@ -159,6 +160,24 @@ class KeyValueStore internal constructor ( } } + override suspend fun clear() { + val keys = mutableSetOf() + 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 { operator fun invoke( context: Context, diff --git a/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/keyvalue/AbstractExposedKeyValueRepo.kt b/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/keyvalue/AbstractExposedKeyValueRepo.kt index cb24c23f14e..591d1b6ce42 100644 --- a/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/keyvalue/AbstractExposedKeyValueRepo.kt +++ b/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/keyvalue/AbstractExposedKeyValueRepo.kt @@ -73,4 +73,18 @@ abstract class AbstractExposedKeyValueRepo( _onValueRemoved.emit(it) } } + + override suspend fun clear() { + transaction(database) { + val keys = selectAll().map { it.asKey } + + deleteAll() + + keys + }.also { + it.forEach { + _onValueRemoved.emit(it) + } + } + } } diff --git a/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/keyvalue/ExposedKeyValueRepo.kt b/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/keyvalue/ExposedKeyValueRepo.kt index 80c57f7cd4b..be470089c71 100644 --- a/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/keyvalue/ExposedKeyValueRepo.kt +++ b/repos/exposed/src/jvmMain/kotlin/dev/inmo/micro_utils/repos/exposed/keyvalue/ExposedKeyValueRepo.kt @@ -6,6 +6,7 @@ import kotlinx.coroutines.flow.* import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.SqlExpressionBuilder.inList +import org.jetbrains.exposed.sql.SqlExpressionBuilder.inSubQuery import org.jetbrains.exposed.sql.transactions.transaction open class ExposedKeyValueRepo( @@ -72,4 +73,18 @@ open class ExposedKeyValueRepo( _onValueRemoved.emit(it) } } + + override suspend fun clear() { + transaction(database) { + val keys = selectAll().map { it.asKey } + + deleteAll() + + keys + }.also { + it.forEach { + _onValueRemoved.emit(it) + } + } + } } diff --git a/repos/inmemory/src/commonMain/kotlin/dev/inmo/micro_utils/repos/MapKeyValueRepo.kt b/repos/inmemory/src/commonMain/kotlin/dev/inmo/micro_utils/repos/MapKeyValueRepo.kt index 328dccee38c..d93bbcc1ca8 100644 --- a/repos/inmemory/src/commonMain/kotlin/dev/inmo/micro_utils/repos/MapKeyValueRepo.kt +++ b/repos/inmemory/src/commonMain/kotlin/dev/inmo/micro_utils/repos/MapKeyValueRepo.kt @@ -94,6 +94,10 @@ class MapKeyValueRepo( private val map: MutableMap = mutableMapOf() ) : KeyValueRepo, ReadKeyValueRepo by ReadMapKeyValueRepo(map), - WriteKeyValueRepo by WriteMapKeyValueRepo(map) + WriteKeyValueRepo by WriteMapKeyValueRepo(map) { + override suspend fun clear() { + map.clear() + } +} fun MutableMap.asKeyValueRepo(): KeyValueRepo = MapKeyValueRepo(this)