From 408732ccfdd1efca242ee27271a2eb596202cc49 Mon Sep 17 00:00:00 2001 From: tamimattafi <35191844+tamimattafi@users.noreply.github.com> Date: Fri, 19 Apr 2024 18:30:11 +0300 Subject: [PATCH] fix: nested transaction error on iOS Close #16 --- .../kabin/publish/PublishConventions.kt | 2 +- .../kabin/core/database/KabinBaseDatabase.kt | 3 +- .../kabin/core/database/KabinSqlSchema.kt | 6 +-- .../kabin/core/utils/KabinUtils.kt | 37 ++++++++++++------- 4 files changed, 29 insertions(+), 19 deletions(-) diff --git a/convention/publishing/src/main/kotlin/com/attafitamim/kabin/publish/PublishConventions.kt b/convention/publishing/src/main/kotlin/com/attafitamim/kabin/publish/PublishConventions.kt index dca6c73..01496b7 100644 --- a/convention/publishing/src/main/kotlin/com/attafitamim/kabin/publish/PublishConventions.kt +++ b/convention/publishing/src/main/kotlin/com/attafitamim/kabin/publish/PublishConventions.kt @@ -10,7 +10,7 @@ import org.gradle.api.publish.maven.MavenPomScm class PublishConventions : Plugin { - private val version = "0.1.0-alpha06" + private val version = "0.1.0-alpha07" private val group = "com.attafitamim.kabin" override fun apply(project: Project) { diff --git a/library/core/src/commonMain/kotlin/com/attafitamim/kabin/core/database/KabinBaseDatabase.kt b/library/core/src/commonMain/kotlin/com/attafitamim/kabin/core/database/KabinBaseDatabase.kt index 96dee28..0d02147 100644 --- a/library/core/src/commonMain/kotlin/com/attafitamim/kabin/core/database/KabinBaseDatabase.kt +++ b/library/core/src/commonMain/kotlin/com/attafitamim/kabin/core/database/KabinBaseDatabase.kt @@ -11,11 +11,12 @@ abstract class KabinBaseDatabase( ) : KabinDatabase { private val queries = KabinSuspendingQueries(driver) + abstract suspend fun clearTables() final override suspend fun clear() { queries.safeGlobalTransaction(configuration) { clearTables() - }.await() + } } } \ No newline at end of file diff --git a/library/core/src/commonMain/kotlin/com/attafitamim/kabin/core/database/KabinSqlSchema.kt b/library/core/src/commonMain/kotlin/com/attafitamim/kabin/core/database/KabinSqlSchema.kt index c6b4cc2..6da6adc 100644 --- a/library/core/src/commonMain/kotlin/com/attafitamim/kabin/core/database/KabinSqlSchema.kt +++ b/library/core/src/commonMain/kotlin/com/attafitamim/kabin/core/database/KabinSqlSchema.kt @@ -8,7 +8,7 @@ import com.attafitamim.kabin.core.database.configuration.KabinDatabaseConfigurat import com.attafitamim.kabin.core.exceptions.SqlMigrationMissing import com.attafitamim.kabin.core.migration.KabinMigrationStrategy import com.attafitamim.kabin.core.migration.Migration -import com.attafitamim.kabin.core.utils.safeGlobalTransaction +import com.attafitamim.kabin.core.utils.safeGlobalQuery abstract class KabinSqlSchema( val migrations: List, @@ -21,7 +21,7 @@ abstract class KabinSqlSchema( abstract suspend fun createTables(driver: SqlDriver) override fun create(driver: SqlDriver): QueryResult.AsyncValue = - driver.safeGlobalTransaction(configuration) { + driver.safeGlobalQuery(configuration) { createTables(driver) } @@ -30,7 +30,7 @@ abstract class KabinSqlSchema( oldVersion: Long, newVersion: Long, vararg callbacks: AfterVersion - ): QueryResult.AsyncValue = driver.safeGlobalTransaction(configuration) { + ): QueryResult.AsyncValue = driver.safeGlobalQuery(configuration) { when { oldVersion == newVersion -> callbacks.notifyAll(driver) oldVersion > newVersion -> handleMissingMigration(oldVersion, newVersion, driver, callbacks) diff --git a/library/core/src/commonMain/kotlin/com/attafitamim/kabin/core/utils/KabinUtils.kt b/library/core/src/commonMain/kotlin/com/attafitamim/kabin/core/utils/KabinUtils.kt index f640ca5..2bef78c 100644 --- a/library/core/src/commonMain/kotlin/com/attafitamim/kabin/core/utils/KabinUtils.kt +++ b/library/core/src/commonMain/kotlin/com/attafitamim/kabin/core/utils/KabinUtils.kt @@ -24,22 +24,30 @@ suspend inline fun KabinSuspendingQueries.safeTransactionWithResult( body() } -inline fun SqlDriver.safeGlobalTransaction( +inline fun SqlDriver.safeGlobalQuery( configuration: KabinDatabaseConfiguration, - noinline body: suspend TransactionCallbacks.() -> Unit -): QueryResult.AsyncValue = KabinSuspendingQueries(this) - .safeGlobalTransaction(configuration, body) + noinline body: suspend () -> Unit +): QueryResult.AsyncValue = with(KabinSuspendingQueries(this)) { + QueryResult.AsyncValue { + try { + tryToggleForeignKeys(configuration, enabled = false) + tryDifferForeignKeys(configuration, enabled = true) + body() + } finally { + tryToggleForeignKeys(configuration, enabled = true) + tryDifferForeignKeys(configuration, enabled = false) + } + } +} -inline fun KabinSuspendingQueries.safeGlobalTransaction( +suspend inline fun KabinSuspendingQueries.safeGlobalTransaction( configuration: KabinDatabaseConfiguration, noinline body: suspend TransactionCallbacks.() -> Unit -) = QueryResult.AsyncValue { - try { - tryToggleForeignKeys(configuration, enabled = false) - safeTransaction(configuration, body = body) - } finally { - tryToggleForeignKeys(configuration, enabled = true) - } +) = try { + tryToggleForeignKeys(configuration, enabled = false) + safeTransaction(configuration, body = body) +} finally { + tryToggleForeignKeys(configuration, enabled = true) } suspend fun KabinSuspendingQueries.tryToggleForeignKeys( @@ -52,9 +60,10 @@ suspend fun KabinSuspendingQueries.tryToggleForeignKeys( } suspend fun KabinSuspendingQueries.tryDifferForeignKeys( - configuration: KabinDatabaseConfiguration + configuration: KabinDatabaseConfiguration, + enabled: Boolean = true ) = with(configuration.extendedConfig) { if (foreignKeyConstraintsEnabled && deferForeignKeysInsideTransaction) { - deferForeignKeys() + deferForeignKeys(enabled) } } \ No newline at end of file