commonMain.com.ctrip.sqllin.dsl.DatabaseScope.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sqllin-dsl Show documentation
Show all versions of sqllin-dsl Show documentation
SQL DSL APIs for SQLite on Kotlin Multiplatform
/*
* Copyright (C) 2023 Ctrip.com.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.ctrip.sqllin.dsl
import com.ctrip.sqllin.driver.DatabaseConnection
import com.ctrip.sqllin.dsl.sql.Table
import com.ctrip.sqllin.dsl.sql.X
import com.ctrip.sqllin.dsl.sql.clause.*
import com.ctrip.sqllin.dsl.sql.operation.Delete
import com.ctrip.sqllin.dsl.sql.operation.Insert
import com.ctrip.sqllin.dsl.sql.operation.Select
import com.ctrip.sqllin.dsl.sql.operation.Update
import com.ctrip.sqllin.dsl.sql.statement.*
import kotlinx.serialization.KSerializer
import kotlinx.serialization.modules.EmptySerializersModule
import kotlinx.serialization.serializer
import kotlin.concurrent.Volatile
/**
* The database scope, it's used to restrict the scope that write DSL SQL statements
* @author yaqiao
*/
@Suppress("UNCHECKED_CAST")
public class DatabaseScope internal constructor(
private val databaseConnection: DatabaseConnection,
private val enableSimpleSQLLog: Boolean,
) {
/**
* Transaction.
*/
@Volatile
private var transactionStatementsGroup: TransactionStatementsGroup? = null
private inline val isInTransaction
get() = transactionStatementsGroup != null
public fun beginTransaction(): Boolean {
if (isInTransaction)
return false
transactionStatementsGroup = TransactionStatementsGroup(databaseConnection, enableSimpleSQLLog)
executiveEngine.addStatement(transactionStatementsGroup!!)
return true
}
public fun endTransaction() {
transactionStatementsGroup = null
}
public inline fun transaction(block: DatabaseScope.() -> T): T {
beginTransaction()
try {
return block()
} finally {
endTransaction()
}
}
/**
* SQL execute.
*/
private val executiveEngine = DatabaseExecuteEngine(enableSimpleSQLLog)
private fun addStatement(statement: SingleStatement) {
if (isInTransaction)
transactionStatementsGroup!!.addStatement(statement)
else
executiveEngine.addStatement(statement)
}
private fun addSelectStatement(statement: SelectStatement) {
if (unionSelectStatementGroupStack.isNotEmpty())
(unionSelectStatementGroupStack.last() as UnionSelectStatementGroup).addSelectStatement(statement)
else
addStatement(statement)
}
internal fun executeAllStatements() = executiveEngine.executeAllStatement()
/**
* Insert.
*/
public infix fun Table.INSERT(entities: Iterable) {
val statement = Insert.insert(this, databaseConnection, entities)
addStatement(statement)
}
public infix fun Table.INSERT(entity: T): Unit =
INSERT(listOf(entity))
/**
* Update.
*/
public infix fun Table.UPDATE(clause: SetClause): UpdateStatementWithoutWhereClause =
transactionStatementsGroup?.let {
val statement = Update.update(this, databaseConnection, it, clause)
it addStatement statement
statement
} ?: Update.update(this, databaseConnection, executiveEngine, clause).also {
executiveEngine addStatement it
}
/**
* Delete.
*/
public infix fun Table<*>.DELETE(x: X) {
val statement = Delete.deleteAllEntities(this, databaseConnection)
addStatement(statement)
}
public infix fun Table.DELETE(clause: WhereClause) {
val statement = Delete.delete(this, databaseConnection, clause)
addStatement(statement)
}
/**
* Select.
*/
/**
* Select with no any clause.
*/
public inline infix fun Table.SELECT(x: X): FinalSelectStatement =
select(kSerializer(), false)
public inline infix fun Table.SELECT_DISTINCT(x: X): FinalSelectStatement =
select(kSerializer(), true)
public fun Table.select(serializer: KSerializer, isDistinct: Boolean): FinalSelectStatement {
val container = getSelectStatementGroup()
val statement = Select.select(this, isDistinct, serializer, databaseConnection, container)
addSelectStatement(statement)
return statement
}
/**
* Receive the 'WHERE' clause.
*/
public inline infix fun Table.SELECT(clause: WhereClause): WhereSelectStatement =
select(kSerializer(), clause, false)
public inline infix fun Table.SELECT_DISTINCT(clause: WhereClause): WhereSelectStatement =
select(kSerializer(), clause, true)
public fun Table.select(serializer: KSerializer, clause: WhereClause, isDistinct: Boolean): WhereSelectStatement {
val container = getSelectStatementGroup()
val statement = Select.select(this, clause, isDistinct, serializer, databaseConnection, container)
addSelectStatement(statement)
return statement
}
/**
* Receive the 'ORDER BY' clause.
*/
public inline infix fun Table.SELECT(clause: OrderByClause): OrderBySelectStatement =
select(kSerializer(), clause, false)
public inline infix fun Table.SELECT_DISTINCT(clause: OrderByClause): OrderBySelectStatement =
select(kSerializer(), clause, true)
public fun Table.select(serializer: KSerializer, clause: OrderByClause, isDistinct: Boolean): OrderBySelectStatement {
val container = getSelectStatementGroup()
val statement = Select.select(this, clause, isDistinct, serializer, databaseConnection, container)
addSelectStatement(statement)
return statement
}
/**
* Receive the 'LIMIT' clause.
*/
public inline infix fun Table.SELECT(clause: LimitClause): LimitSelectStatement =
select(kSerializer(), clause, false)
public inline infix fun Table.SELECT_DISTINCT(clause: LimitClause): LimitSelectStatement =
select(kSerializer(), clause, true)
public fun Table.select(serializer: KSerializer, clause: LimitClause, isDistinct: Boolean): LimitSelectStatement {
val container = getSelectStatementGroup()
val statement = Select.select(this, clause, isDistinct, serializer, databaseConnection, container)
addSelectStatement(statement)
return statement
}
/**
* Receive the 'GROUP BY' clause.
*/
public inline infix fun Table.SELECT(clause: GroupByClause): GroupBySelectStatement =
select(kSerializer(), clause, false)
public inline infix fun Table.SELECT_DISTINCT(clause: GroupByClause): GroupBySelectStatement =
select(kSerializer(), clause, true)
public fun Table.select(serializer: KSerializer, clause: GroupByClause, isDistinct: Boolean): GroupBySelectStatement {
val container = getSelectStatementGroup()
val statement = Select.select(this, clause, isDistinct, serializer, databaseConnection, container)
addSelectStatement(statement)
return statement
}
public inline fun getKSerializer(): KSerializer = EmptySerializersModule().serializer()
/**
* The 'UNION' clause of Select.
*/
private val unionSelectStatementGroupStack by lazy { ArrayDeque>() }
private fun getSelectStatementGroup(): StatementContainer = unionSelectStatementGroupStack.lastOrNull() ?: transactionStatementsGroup ?: executiveEngine
public inline fun Table.UNION(block: Table.(Table) -> Unit): FinalSelectStatement {
beginUnion()
var selectStatement: SelectStatement? = null
try {
block(this)
selectStatement = createUnionSelectStatement(false)
return selectStatement
} finally {
endUnion(selectStatement)
}
}
public inline fun Table.UNION_ALL(block: Table.(Table) -> Unit): FinalSelectStatement {
beginUnion()
var selectStatement: SelectStatement? = null
try {
block(this)
selectStatement = createUnionSelectStatement(true)
return selectStatement
} finally {
endUnion(selectStatement)
}
}
public fun beginUnion() {
unionSelectStatementGroupStack.add(UnionSelectStatementGroup())
}
public fun createUnionSelectStatement(isUnionAll: Boolean): FinalSelectStatement {
check(unionSelectStatementGroupStack.isNotEmpty()) { "Please invoke the 'beginUnion' before you invoke this function!!!" }
return (unionSelectStatementGroupStack.last() as UnionSelectStatementGroup).unionStatements(isUnionAll)
}
public fun endUnion(selectStatement: SelectStatement?) {
unionSelectStatementGroupStack.removeLast()
selectStatement?.let { addSelectStatement(it) }
}
/**
* Receive the 'JOIN' clause.
*/
public inline infix fun Table.SELECT(clause: JoinClause): JoinStatementWithoutCondition =
select(getKSerializer(), clause, false)
public inline infix fun Table.SELECT_DISTINCT(clause: JoinClause): JoinStatementWithoutCondition =
select(getKSerializer(), clause, true)
public fun Table.select(serializer: KSerializer, clause: JoinClause, isDistinct: Boolean): JoinStatementWithoutCondition {
val container = getSelectStatementGroup()
return Select.select(this, clause, isDistinct, serializer, databaseConnection, container, ::addSelectStatement)
}
/**
* Receive the natural join clause(includes 'NATURAL LEFT OUTER JOIN' and 'NATURAL INNER JOIN').
*/
public inline infix fun Table.SELECT(clause: NaturalJoinClause): JoinSelectStatement =
select(getKSerializer(), clause, false)
public inline infix fun Table.SELECT_DISTINCT(clause: NaturalJoinClause): JoinSelectStatement =
select(getKSerializer(), clause, true)
public fun Table.select(serializer: KSerializer, clause: NaturalJoinClause, isDistinct: Boolean): JoinSelectStatement {
val container = getSelectStatementGroup()
val statement = Select.select(this, clause, isDistinct, serializer, databaseConnection, container)
addSelectStatement(statement)
return statement
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy