From af03cf81cd2449d41250e1ba5cfbd3c890580aab Mon Sep 17 00:00:00 2001 From: qiaoyuang Date: Mon, 6 Nov 2023 15:52:39 +0800 Subject: [PATCH] Add the new target linuxArm64 and optimize the prefermance of concurrent scenarios --- CHANGELOG.md | 9 +++-- README.md | 2 +- README_CN.md | 2 +- sqllin-driver/build.gradle.kts | 2 ++ sqllin-dsl/build.gradle.kts | 2 ++ .../kotlin/com/ctrip/sqllin/dsl/Database.kt | 36 ++++++++++++------- .../sql/statement/DatabaseExecuteEngine.kt | 30 ++++++++++------ 7 files changed, 55 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 394b185..546e3ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,9 +10,14 @@ ### sqllin-dsl +* Add the new native target support: `linuxArm64` * Add the new API `Database#suspendedScope`, it could be used to ensure concurrency safety([#55](https://github.com/ctripcorp/SQLlin/pull/55)) * Begin with this version, _sqllin-dsl_ depends on _kotlinx.coroutines_ version `1.7.3` -* ***Breaking change***: Remove the public class `DBEntity`, we have deprecated it in version `1.1.1` +* **Breaking change**: Remove the public class `DBEntity`, we have deprecated it in version `1.1.1` + +### sqllin-driver + +* Add the new native target support: `linuxArm64` ### sqllin-processor @@ -46,7 +51,7 @@ a runtime exception. Thanks for [@nbransby](https://github.com/nbransby) ### sqllin-driver * Add the new JVM target -* ***Breaking change***: Remove the public property: `DatabaseConnection#closed` +* **Breaking change**: Remove the public property: `DatabaseConnection#closed` * The Android (<= 9) target supports to set the `journalMode` and `synchronousMode` now ## v1.1.1 / 2023-08-12 diff --git a/README.md b/README.md index c5dafef..929e207 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ SQLlin supports these platforms: - macOS (x64, arm64) - watchOS (x64, arm32, arm64, simulatorArm64, deviceArm64) - tvOS (x64, arm64, simulatorArm64) -- Linux (x64) +- Linux (x64, arm64) - Windows (mingwX64) The architecture design of SQLlin is shown in the figure: diff --git a/README_CN.md b/README_CN.md index 7686022..aeb564d 100644 --- a/README_CN.md +++ b/README_CN.md @@ -34,7 +34,7 @@ SQLlin 支持如下平台: - macOS (x64, arm64) - watchOS (x64, arm32, arm64, simulatorArm64, deviceArm64) - tvOS (x64, arm64, simulatorArm64) -- Linux (x64) +- Linux (x64, arm64) - Windows (mingwX64) SQLlin 的架构设计如下图所示: diff --git a/sqllin-driver/build.gradle.kts b/sqllin-driver/build.gradle.kts index 3e7808f..847126a 100644 --- a/sqllin-driver/build.gradle.kts +++ b/sqllin-driver/build.gradle.kts @@ -52,6 +52,7 @@ kotlin { tvosSimulatorArm64(), linuxX64(), + linuxArm64(), mingwX64(), ).forEach { @@ -92,6 +93,7 @@ kotlin { } tasks.findByName("publishLinuxX64PublicationToMavenRepository")?.enabled = HostManager.hostIsLinux + tasks.findByName("publishLinuxArm64PublicationToMavenRepository")?.enabled = HostManager.hostIsLinux tasks.findByName("publishMingwX64PublicationToMavenRepository")?.enabled = HostManager.hostIsMingw } diff --git a/sqllin-dsl/build.gradle.kts b/sqllin-dsl/build.gradle.kts index e77d7d9..43b1d59 100644 --- a/sqllin-dsl/build.gradle.kts +++ b/sqllin-dsl/build.gradle.kts @@ -54,6 +54,7 @@ kotlin { tvosSimulatorArm64(), linuxX64(), + linuxArm64(), mingwX64(), ).forEach { @@ -94,6 +95,7 @@ kotlin { } tasks.findByName("publishLinuxX64PublicationToMavenRepository")?.enabled = HostManager.hostIsLinux + tasks.findByName("publishLinuxArm64PublicationToMavenRepository")?.enabled = HostManager.hostIsLinux tasks.findByName("publishMingwX64PublicationToMavenRepository")?.enabled = HostManager.hostIsMingw } diff --git a/sqllin-dsl/src/commonMain/kotlin/com/ctrip/sqllin/dsl/Database.kt b/sqllin-dsl/src/commonMain/kotlin/com/ctrip/sqllin/dsl/Database.kt index acdf2a1..4e88466 100644 --- a/sqllin-dsl/src/commonMain/kotlin/com/ctrip/sqllin/dsl/Database.kt +++ b/sqllin-dsl/src/commonMain/kotlin/com/ctrip/sqllin/dsl/Database.kt @@ -69,18 +69,26 @@ public class Database( */ public operator fun invoke(block: Database.() -> T): T { val result = block() - executeAllStatement() + executeAllStatements(prepareForExecution()) return result } - private val statementsMutex by lazy { Mutex() } + private val assembledMutex by lazy { Mutex() } + private val executiveMutex by lazy { Mutex() } - public suspend infix fun suspendedScope(block: suspend Database.() -> T): T = - statementsMutex.withLock { + public suspend infix fun suspendedScope(block: suspend Database.() -> T): T { + val (result, executiveLinkedList) = assembledMutex.withLock { val result = block() - executeAllStatement() - result + val executiveLinkedList = executiveMutex.withLock { + prepareForExecution() + } + result to executiveLinkedList } + executiveMutex.withLock { + executeAllStatements(executiveLinkedList) + } + return result + } /** * Transaction. @@ -96,7 +104,7 @@ public class Database( if (isInTransaction) return false transactionStatementsGroup = TransactionStatementsGroup(databaseConnection) - executeEngine.addStatement(transactionStatementsGroup!!) + executiveEngine.addStatement(transactionStatementsGroup!!) return true } @@ -117,13 +125,13 @@ public class Database( * SQL execute. */ - private val executeEngine = DatabaseExecuteEngine() + private val executiveEngine = DatabaseExecuteEngine() private fun addStatement(statement: SingleStatement) { if (isInTransaction) transactionStatementsGroup!!.addStatement(statement) else - executeEngine.addStatement(statement) + executiveEngine.addStatement(statement) } private fun addSelectStatement(statement: SelectStatement) { @@ -133,7 +141,9 @@ public class Database( addStatement(statement) } - private fun executeAllStatement() = executeEngine.executeAllStatement() + private fun prepareForExecution() = executiveEngine.prepareForExecution() + private fun executeAllStatements(executiveLinkedList: StatementLinkedList) = + executiveEngine executeAllStatement executiveLinkedList /** * Insert. @@ -156,8 +166,8 @@ public class Database( val statement = Update.update(this, databaseConnection, it, clause) it addStatement statement statement - } ?: Update.update(this, databaseConnection, executeEngine, clause).also { - executeEngine addStatement it + } ?: Update.update(this, databaseConnection, executiveEngine, clause).also { + executiveEngine addStatement it } /** @@ -266,7 +276,7 @@ public class Database( private val unionSelectStatementGroupStack by lazy { Stack>() } - private fun getSelectStatementGroup(): StatementContainer = unionSelectStatementGroupStack.top ?: transactionStatementsGroup ?: executeEngine + private fun getSelectStatementGroup(): StatementContainer = unionSelectStatementGroupStack.top ?: transactionStatementsGroup ?: executiveEngine public inline fun Table.UNION(block: Table.(Table) -> Unit): FinalSelectStatement { beginUnion() diff --git a/sqllin-dsl/src/commonMain/kotlin/com/ctrip/sqllin/dsl/sql/statement/DatabaseExecuteEngine.kt b/sqllin-dsl/src/commonMain/kotlin/com/ctrip/sqllin/dsl/sql/statement/DatabaseExecuteEngine.kt index 7d4fd92..0f0a6a7 100644 --- a/sqllin-dsl/src/commonMain/kotlin/com/ctrip/sqllin/dsl/sql/statement/DatabaseExecuteEngine.kt +++ b/sqllin-dsl/src/commonMain/kotlin/com/ctrip/sqllin/dsl/sql/statement/DatabaseExecuteEngine.kt @@ -16,6 +16,8 @@ package com.ctrip.sqllin.dsl.sql.statement +import kotlin.concurrent.Volatile + /** * Collect and execute all SQL statement in 'database {}' block * @author yaqiao @@ -23,25 +25,32 @@ package com.ctrip.sqllin.dsl.sql.statement internal class DatabaseExecuteEngine : StatementContainer { - private var statementLinkedList: StatementLinkedList? = null + @Volatile + private var statementsLinkedList: StatementLinkedList? = null override infix fun changeLastStatement(statement: SingleStatement) { - if (statementLinkedList?.lastStatement is UpdateStatementWithoutWhereClause<*> - || statementLinkedList?.lastStatement is SelectStatement<*>) - statementLinkedList!!.resetLastStatement(statement) + if (statementsLinkedList?.lastStatement is UpdateStatementWithoutWhereClause<*> + || statementsLinkedList?.lastStatement is SelectStatement<*>) + statementsLinkedList!!.resetLastStatement(statement) else throw IllegalStateException("Current statement can't append clause.") } infix fun addStatement(statement: ExecutableStatement) { - if (statementLinkedList != null) - statementLinkedList!!.addStatement(statement) + if (statementsLinkedList != null) + statementsLinkedList!!.addStatement(statement) else - statementLinkedList = StatementLinkedList(statement) + statementsLinkedList = StatementLinkedList(statement) + } + + fun prepareForExecution(): StatementLinkedList { + val executiveLinkedList = statementsLinkedList + statementsLinkedList = null + return executiveLinkedList ?: throw IllegalStateException("The statementsLinkedList can't be null") } - fun executeAllStatement() = statementLinkedList?.run { - forEach { + infix fun executeAllStatement(executiveLinkedList: StatementLinkedList) { + executiveLinkedList.forEach { when (it) { is SingleStatement -> { println("SQL String: ${it.sqlStr}") @@ -50,6 +59,5 @@ internal class DatabaseExecuteEngine : StatementContainer { is TransactionStatementsGroup -> it.execute() } } - statementLinkedList = null - } ?: Unit + } } \ No newline at end of file