mirror of
				https://github.com/InsanusMokrassar/MicroUtils.git
				synced 2025-11-04 14:14:51 +00:00 
			
		
		
		
	
							
								
								
									
										10
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								CHANGELOG.md
									
									
									
									
									
								
							@@ -1,5 +1,15 @@
 | 
				
			|||||||
# Changelog
 | 
					# Changelog
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 0.4.9
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* `Versions`:
 | 
				
			||||||
 | 
					    * `Ktor`: `1.4.2` -> `1.4.3`
 | 
				
			||||||
 | 
					* `Repo`
 | 
				
			||||||
 | 
					    * `Common`
 | 
				
			||||||
 | 
					        * In repos different usages of `BroadcastChannel`s has been replaced with `MutableSharedFlow`
 | 
				
			||||||
 | 
					    * `Exposed`
 | 
				
			||||||
 | 
					        * `asObject` open fun has been added in CRUD realization
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## 0.4.8
 | 
					## 0.4.8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* `Versions`:
 | 
					* `Versions`:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,5 @@
 | 
				
			|||||||
 | 
					apply plugin: 'com.getkeepsafe.dexcount'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
android {
 | 
					android {
 | 
				
			||||||
    compileSdkVersion "$android_compileSdkVersion".toInteger()
 | 
					    compileSdkVersion "$android_compileSdkVersion".toInteger()
 | 
				
			||||||
    buildToolsVersion "$android_buildToolsVersion"
 | 
					    buildToolsVersion "$android_buildToolsVersion"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,7 @@ kotlin_coroutines_version=1.4.2
 | 
				
			|||||||
kotlin_serialisation_core_version=1.0.1
 | 
					kotlin_serialisation_core_version=1.0.1
 | 
				
			||||||
kotlin_exposed_version=0.28.1
 | 
					kotlin_exposed_version=0.28.1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ktor_version=1.4.2
 | 
					ktor_version=1.4.3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
klockVersion=2.0.0
 | 
					klockVersion=2.0.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -28,7 +28,7 @@ appcompat_version=1.2.0
 | 
				
			|||||||
android_minSdkVersion=19
 | 
					android_minSdkVersion=19
 | 
				
			||||||
android_compileSdkVersion=30
 | 
					android_compileSdkVersion=30
 | 
				
			||||||
android_buildToolsVersion=30.0.2
 | 
					android_buildToolsVersion=30.0.2
 | 
				
			||||||
dexcount_version=2.0.0-RC1
 | 
					dexcount_version=2.0.0
 | 
				
			||||||
junit_version=4.12
 | 
					junit_version=4.12
 | 
				
			||||||
test_ext_junit_version=1.1.2
 | 
					test_ext_junit_version=1.1.2
 | 
				
			||||||
espresso_core=3.3.0
 | 
					espresso_core=3.3.0
 | 
				
			||||||
@@ -40,5 +40,5 @@ dokka_version=1.4.10.2
 | 
				
			|||||||
# Project data
 | 
					# Project data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
group=dev.inmo
 | 
					group=dev.inmo
 | 
				
			||||||
version=0.4.8
 | 
					version=0.4.9
 | 
				
			||||||
android_code_version=12
 | 
					android_code_version=13
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,20 +3,18 @@ package dev.inmo.micro_utils.repos.crud
 | 
				
			|||||||
import android.content.ContentValues
 | 
					import android.content.ContentValues
 | 
				
			||||||
import dev.inmo.micro_utils.common.mapNotNullA
 | 
					import dev.inmo.micro_utils.common.mapNotNullA
 | 
				
			||||||
import dev.inmo.micro_utils.repos.*
 | 
					import dev.inmo.micro_utils.repos.*
 | 
				
			||||||
import kotlinx.coroutines.channels.BroadcastChannel
 | 
					import kotlinx.coroutines.flow.*
 | 
				
			||||||
import kotlinx.coroutines.flow.Flow
 | 
					 | 
				
			||||||
import kotlinx.coroutines.flow.asFlow
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
abstract class AbstractMutableAndroidCRUDRepo<ObjectType, IdType, InputValueType>(
 | 
					abstract class AbstractMutableAndroidCRUDRepo<ObjectType, IdType, InputValueType>(
 | 
				
			||||||
    helper: StandardSQLHelper
 | 
					    helper: StandardSQLHelper
 | 
				
			||||||
) : WriteStandardCRUDRepo<ObjectType, IdType, InputValueType>,
 | 
					) : WriteStandardCRUDRepo<ObjectType, IdType, InputValueType>,
 | 
				
			||||||
    AbstractAndroidCRUDRepo<ObjectType, IdType>(helper) {
 | 
					    AbstractAndroidCRUDRepo<ObjectType, IdType>(helper) {
 | 
				
			||||||
    protected val newObjectsChannel = BroadcastChannel<ObjectType>(64)
 | 
					    protected val newObjectsChannel = MutableSharedFlow<ObjectType>(64)
 | 
				
			||||||
    protected val updateObjectsChannel = BroadcastChannel<ObjectType>(64)
 | 
					    protected val updateObjectsChannel = MutableSharedFlow<ObjectType>(64)
 | 
				
			||||||
    protected val deleteObjectsIdsChannel = BroadcastChannel<IdType>(64)
 | 
					    protected val deleteObjectsIdsChannel = MutableSharedFlow<IdType>(64)
 | 
				
			||||||
    override val newObjectsFlow: Flow<ObjectType> = newObjectsChannel.asFlow()
 | 
					    override val newObjectsFlow: Flow<ObjectType> = newObjectsChannel.asSharedFlow()
 | 
				
			||||||
    override val updatedObjectsFlow: Flow<ObjectType> = updateObjectsChannel.asFlow()
 | 
					    override val updatedObjectsFlow: Flow<ObjectType> = updateObjectsChannel.asSharedFlow()
 | 
				
			||||||
    override val deletedObjectsIdsFlow: Flow<IdType> = deleteObjectsIdsChannel.asFlow()
 | 
					    override val deletedObjectsIdsFlow: Flow<IdType> = deleteObjectsIdsChannel.asSharedFlow()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected abstract suspend fun InputValueType.asContentValues(id: IdType? = null): ContentValues
 | 
					    protected abstract suspend fun InputValueType.asContentValues(id: IdType? = null): ContentValues
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -42,7 +40,7 @@ abstract class AbstractMutableAndroidCRUDRepo<ObjectType, IdType, InputValueType
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }.also {
 | 
					        }.also {
 | 
				
			||||||
            it.forEach {
 | 
					            it.forEach {
 | 
				
			||||||
                newObjectsChannel.send(it)
 | 
					                newObjectsChannel.emit(it)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -59,7 +57,7 @@ abstract class AbstractMutableAndroidCRUDRepo<ObjectType, IdType, InputValueType
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        deleted.forEach {
 | 
					        deleted.forEach {
 | 
				
			||||||
            deleteObjectsIdsChannel.send(it)
 | 
					            deleteObjectsIdsChannel.emit(it)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -76,7 +74,7 @@ abstract class AbstractMutableAndroidCRUDRepo<ObjectType, IdType, InputValueType
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return getById(id) ?.also {
 | 
					        return getById(id) ?.also {
 | 
				
			||||||
            updateObjectsChannel.send(it)
 | 
					            updateObjectsChannel.emit(it)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -95,7 +93,7 @@ abstract class AbstractMutableAndroidCRUDRepo<ObjectType, IdType, InputValueType
 | 
				
			|||||||
            getById(it.first)
 | 
					            getById(it.first)
 | 
				
			||||||
        }.also {
 | 
					        }.also {
 | 
				
			||||||
            it.forEach {
 | 
					            it.forEach {
 | 
				
			||||||
                updateObjectsChannel.send(it)
 | 
					                updateObjectsChannel.emit(it)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,10 +8,7 @@ import dev.inmo.micro_utils.pagination.PaginationResult
 | 
				
			|||||||
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.StandardKeyValueRepo
 | 
					import dev.inmo.micro_utils.repos.StandardKeyValueRepo
 | 
				
			||||||
import kotlinx.coroutines.channels.BroadcastChannel
 | 
					import kotlinx.coroutines.flow.*
 | 
				
			||||||
import kotlinx.coroutines.channels.Channel
 | 
					 | 
				
			||||||
import kotlinx.coroutines.flow.Flow
 | 
					 | 
				
			||||||
import kotlinx.coroutines.flow.asFlow
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
private val cache = HashMap<String, KeyValueStore<*>>()
 | 
					private val cache = HashMap<String, KeyValueStore<*>>()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -37,11 +34,11 @@ class KeyValueStore<T : Any> internal constructor (
 | 
				
			|||||||
        null
 | 
					        null
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private val onNewValueChannel = BroadcastChannel<Pair<String, T>>(Channel.BUFFERED)
 | 
					    private val onNewValueChannel = MutableSharedFlow<Pair<String, T>>()
 | 
				
			||||||
    private val onValueRemovedChannel = BroadcastChannel<String>(Channel.BUFFERED)
 | 
					    private val onValueRemovedChannel = MutableSharedFlow<String>()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    override val onNewValue: Flow<Pair<String, T>> = onNewValueChannel.asFlow()
 | 
					    override val onNewValue: Flow<Pair<String, T>> = onNewValueChannel.asSharedFlow()
 | 
				
			||||||
    override val onValueRemoved: Flow<String> = onValueRemovedChannel.asFlow()
 | 
					    override val onValueRemoved: Flow<String> = onValueRemovedChannel.asSharedFlow()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    init {
 | 
					    init {
 | 
				
			||||||
        cachedData ?.let {
 | 
					        cachedData ?.let {
 | 
				
			||||||
@@ -131,7 +128,7 @@ class KeyValueStore<T : Any> internal constructor (
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        toSet.forEach { (k, v) ->
 | 
					        toSet.forEach { (k, v) ->
 | 
				
			||||||
            onNewValueChannel.send(k to v)
 | 
					            onNewValueChannel.emit(k to v)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -139,6 +136,6 @@ class KeyValueStore<T : Any> internal constructor (
 | 
				
			|||||||
        sharedPreferences.edit {
 | 
					        sharedPreferences.edit {
 | 
				
			||||||
            toUnset.forEach { remove(it) }
 | 
					            toUnset.forEach { remove(it) }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        toUnset.forEach { onValueRemovedChannel.send(it) }
 | 
					        toUnset.forEach { onValueRemovedChannel.emit(it) }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,11 +32,11 @@ class AndroidSQLStandardVersionsRepoProxy(
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    override suspend fun getTableVersion(table: String): Int? = database.writableTransaction {
 | 
					    override suspend fun getTableVersion(tableName: String): Int? = database.writableTransaction {
 | 
				
			||||||
        select(
 | 
					        select(
 | 
				
			||||||
            tableName,
 | 
					            this@AndroidSQLStandardVersionsRepoProxy.tableName,
 | 
				
			||||||
            selection = "$tableNameColumnName=?",
 | 
					            selection = "$tableNameColumnName=?",
 | 
				
			||||||
            selectionArgs = arrayOf(table),
 | 
					            selectionArgs = arrayOf(tableName),
 | 
				
			||||||
            limit = limitClause(1)
 | 
					            limit = limitClause(1)
 | 
				
			||||||
        ).use {
 | 
					        ).use {
 | 
				
			||||||
            if (it.moveToFirst()) {
 | 
					            if (it.moveToFirst()) {
 | 
				
			||||||
@@ -47,16 +47,16 @@ class AndroidSQLStandardVersionsRepoProxy(
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    override suspend fun updateTableVersion(table: String, version: Int) {
 | 
					    override suspend fun updateTableVersion(tableName: String, version: Int) {
 | 
				
			||||||
        database.writableTransaction {
 | 
					        database.writableTransaction {
 | 
				
			||||||
            val updated = update(
 | 
					            val updated = update(
 | 
				
			||||||
                tableName,
 | 
					                this@AndroidSQLStandardVersionsRepoProxy.tableName,
 | 
				
			||||||
                contentValuesOf(tableVersionColumnName to version),
 | 
					                contentValuesOf(tableVersionColumnName to version),
 | 
				
			||||||
                "$tableNameColumnName=?",
 | 
					                "$tableNameColumnName=?",
 | 
				
			||||||
                arrayOf(table)
 | 
					                arrayOf(tableName)
 | 
				
			||||||
            ) > 0
 | 
					            ) > 0
 | 
				
			||||||
            if (!updated) {
 | 
					            if (!updated) {
 | 
				
			||||||
                insert(tableName, null, contentValuesOf(tableNameColumnName to table, tableVersionColumnName to version))
 | 
					                insert(this@AndroidSQLStandardVersionsRepoProxy.tableName, null, contentValuesOf(tableNameColumnName to tableName, tableVersionColumnName to version))
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,6 @@ package dev.inmo.micro_utils.repos.exposed
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import dev.inmo.micro_utils.repos.UpdatedValuePair
 | 
					import dev.inmo.micro_utils.repos.UpdatedValuePair
 | 
				
			||||||
import dev.inmo.micro_utils.repos.WriteStandardCRUDRepo
 | 
					import dev.inmo.micro_utils.repos.WriteStandardCRUDRepo
 | 
				
			||||||
import kotlinx.coroutines.channels.BroadcastChannel
 | 
					 | 
				
			||||||
import kotlinx.coroutines.flow.*
 | 
					import kotlinx.coroutines.flow.*
 | 
				
			||||||
import org.jetbrains.exposed.sql.*
 | 
					import org.jetbrains.exposed.sql.*
 | 
				
			||||||
import org.jetbrains.exposed.sql.statements.InsertStatement
 | 
					import org.jetbrains.exposed.sql.statements.InsertStatement
 | 
				
			||||||
@@ -25,8 +24,10 @@ abstract class AbstractExposedWriteCRUDRepo<ObjectType, IdType, InputValueType>(
 | 
				
			|||||||
    override val updatedObjectsFlow: Flow<ObjectType> = updateObjectsChannel.asSharedFlow()
 | 
					    override val updatedObjectsFlow: Flow<ObjectType> = updateObjectsChannel.asSharedFlow()
 | 
				
			||||||
    override val deletedObjectsIdsFlow: Flow<IdType> = deleteObjectsIdsChannel.asSharedFlow()
 | 
					    override val deletedObjectsIdsFlow: Flow<IdType> = deleteObjectsIdsChannel.asSharedFlow()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Deprecated("Will be removed in near major update. Override open fun with the same name instead")
 | 
				
			||||||
    abstract val InsertStatement<Number>.asObject: ObjectType
 | 
					    abstract val InsertStatement<Number>.asObject: ObjectType
 | 
				
			||||||
    abstract val selectByIds: SqlExpressionBuilder.(List<out IdType>) -> Op<Boolean>
 | 
					    protected open fun InsertStatement<Number>.asObject(value: InputValueType): ObjectType = asObject
 | 
				
			||||||
 | 
					    abstract val selectByIds: SqlExpressionBuilder.(List<IdType>) -> Op<Boolean>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected abstract fun insert(value: InputValueType, it: InsertStatement<Number>)
 | 
					    protected abstract fun insert(value: InputValueType, it: InsertStatement<Number>)
 | 
				
			||||||
    protected abstract fun update(id: IdType, value: InputValueType, it: UpdateStatement)
 | 
					    protected abstract fun update(id: IdType, value: InputValueType, it: UpdateStatement)
 | 
				
			||||||
@@ -34,7 +35,7 @@ abstract class AbstractExposedWriteCRUDRepo<ObjectType, IdType, InputValueType>(
 | 
				
			|||||||
    protected open suspend fun onBeforeCreate(value: List<InputValueType>) {}
 | 
					    protected open suspend fun onBeforeCreate(value: List<InputValueType>) {}
 | 
				
			||||||
    private fun createWithoutNotification(value: InputValueType): ObjectType {
 | 
					    private fun createWithoutNotification(value: InputValueType): ObjectType {
 | 
				
			||||||
        return transaction(database) {
 | 
					        return transaction(database) {
 | 
				
			||||||
            insert { insert(value, it) }.asObject
 | 
					            insert { insert(value, it) }.asObject(value)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -42,12 +43,10 @@ abstract class AbstractExposedWriteCRUDRepo<ObjectType, IdType, InputValueType>(
 | 
				
			|||||||
        onBeforeCreate(values)
 | 
					        onBeforeCreate(values)
 | 
				
			||||||
        return transaction(db = database) {
 | 
					        return transaction(db = database) {
 | 
				
			||||||
            values.map { value -> createWithoutNotification(value) }
 | 
					            values.map { value -> createWithoutNotification(value) }
 | 
				
			||||||
        }.also {
 | 
					        }.onEach {
 | 
				
			||||||
            it.forEach {
 | 
					 | 
				
			||||||
            newObjectsChannel.emit(it)
 | 
					            newObjectsChannel.emit(it)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected open suspend fun onBeforeUpdate(value: List<UpdatedValuePair<IdType, InputValueType>>) {}
 | 
					    protected open suspend fun onBeforeUpdate(value: List<UpdatedValuePair<IdType, InputValueType>>) {}
 | 
				
			||||||
    private fun updateWithoutNotification(id: IdType, value: InputValueType): ObjectType? {
 | 
					    private fun updateWithoutNotification(id: IdType, value: InputValueType): ObjectType? {
 | 
				
			||||||
@@ -83,15 +82,11 @@ abstract class AbstractExposedWriteCRUDRepo<ObjectType, IdType, InputValueType>(
 | 
				
			|||||||
        return (
 | 
					        return (
 | 
				
			||||||
            transaction(db = database) {
 | 
					            transaction(db = database) {
 | 
				
			||||||
                values.map { (id, value) -> updateWithoutNotification(id, value) }
 | 
					                values.map { (id, value) -> updateWithoutNotification(id, value) }
 | 
				
			||||||
            }.filter {
 | 
					            }.filterNotNull()
 | 
				
			||||||
                it != null
 | 
					        ).onEach {
 | 
				
			||||||
            } as List<ObjectType>
 | 
					 | 
				
			||||||
        ).also {
 | 
					 | 
				
			||||||
            it.forEach {
 | 
					 | 
				
			||||||
            updateObjectsChannel.emit(it)
 | 
					            updateObjectsChannel.emit(it)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    protected open suspend fun onBeforeDelete(ids: List<IdType>) {}
 | 
					    protected open suspend fun onBeforeDelete(ids: List<IdType>) {}
 | 
				
			||||||
    override suspend fun deleteById(ids: List<IdType>) {
 | 
					    override suspend fun deleteById(ids: List<IdType>) {
 | 
				
			||||||
        onBeforeDelete(ids)
 | 
					        onBeforeDelete(ids)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user