From 07a65e0bb5b4efcb838ad82888864d8a61850a67 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Sun, 22 Nov 2020 23:19:16 +0600 Subject: [PATCH] fixes --- .../repos/DatabaseCoroutineContext.kt | 4 +-- .../micro_utils/repos/DatabaseTransactions.kt | 34 ++++++++++++++++++- .../AndroidSQLStandardVersionsRepoProxy.kt | 10 +++--- 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/DatabaseCoroutineContext.kt b/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/DatabaseCoroutineContext.kt index 8a2932eb0fe..b99835e5972 100644 --- a/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/DatabaseCoroutineContext.kt +++ b/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/DatabaseCoroutineContext.kt @@ -1,6 +1,6 @@ package dev.inmo.micro_utils.repos -import kotlinx.coroutines.newSingleThreadContext +import kotlinx.coroutines.Dispatchers import kotlin.coroutines.CoroutineContext -val DatabaseCoroutineContext: CoroutineContext = newSingleThreadContext("db-context") +val DatabaseCoroutineContext: CoroutineContext = Dispatchers.IO diff --git a/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/DatabaseTransactions.kt b/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/DatabaseTransactions.kt index 2f2c5e21f1e..6d7821d20ca 100644 --- a/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/DatabaseTransactions.kt +++ b/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/DatabaseTransactions.kt @@ -3,10 +3,42 @@ package dev.inmo.micro_utils.repos import android.database.sqlite.SQLiteDatabase import dev.inmo.micro_utils.coroutines.safely import kotlinx.coroutines.* +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock import java.util.concurrent.Executors import kotlin.coroutines.CoroutineContext import kotlin.coroutines.coroutineContext +private object ContextsPool { + private val contexts = mutableListOf() + private val mutex = Mutex(locked = false) + private val freeContexts = mutableListOf() + + suspend fun acquireContext(): CoroutineContext { + return mutex.withLock { + freeContexts.removeFirstOrNull() ?: Executors.newSingleThreadExecutor().asCoroutineDispatcher().also { + contexts.add(it) + } + } + } + + suspend fun freeContext(context: CoroutineContext) { + return mutex.withLock { + if (context in contexts && context !in freeContexts) { + freeContexts.add(context) + } + } + } + + suspend fun use(block: suspend (CoroutineContext) -> T): T = acquireContext().let { + try { + block(it) + } finally { + freeContext(it) + } + } +} + class TransactionContext( val databaseContext: CoroutineContext ): CoroutineContext.Element { @@ -20,7 +52,7 @@ suspend fun SQLiteDatabase.transaction(block: suspend SQLiteDatabase.() -> T withContext(it.databaseContext) { block() } - } ?: Executors.newSingleThreadExecutor().asCoroutineDispatcher().let { context -> + } ?: ContextsPool.use { context -> withContext(TransactionContext(context) + context) { beginTransaction() safely( diff --git a/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/versions/AndroidSQLStandardVersionsRepoProxy.kt b/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/versions/AndroidSQLStandardVersionsRepoProxy.kt index 81d31449a9b..d52d9e9ddad 100644 --- a/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/versions/AndroidSQLStandardVersionsRepoProxy.kt +++ b/repos/common/src/main/kotlin/dev/inmo/micro_utils/repos/versions/AndroidSQLStandardVersionsRepoProxy.kt @@ -32,11 +32,11 @@ class AndroidSQLStandardVersionsRepoProxy( } } - override suspend fun getTableVersion(tableName: String): Int? = database.writableTransaction { + override suspend fun getTableVersion(table: String): Int? = database.writableTransaction { select( tableName, selection = "$tableNameColumnName=?", - selectionArgs = arrayOf(tableName), + selectionArgs = arrayOf(table), limit = limitClause(1) ).use { if (it.moveToFirst()) { @@ -47,16 +47,16 @@ class AndroidSQLStandardVersionsRepoProxy( } } - override suspend fun updateTableVersion(tableName: String, version: Int) { + override suspend fun updateTableVersion(table: String, version: Int) { database.writableTransaction { val updated = update( tableName, contentValuesOf(tableVersionColumnName to version), "$tableNameColumnName=?", - arrayOf(version.toString()) + arrayOf(table) ) > 0 if (!updated) { - insert(tableName, null, contentValuesOf(tableNameColumnName to tableName, tableVersionColumnName to version)) + insert(tableName, null, contentValuesOf(tableNameColumnName to table, tableVersionColumnName to version)) } } }