Coverage Summary for Class: LastInsertIdPlugin (com.kotlinorm.plugins)
Class |
Method, %
|
Branch, %
|
Line, %
|
Instruction, %
|
LastInsertIdPlugin |
90%
(9/10)
|
64.5%
(20/31)
|
71%
(22/31)
|
61.7%
(87/141)
|
LastInsertIdPlugin$WhenMappings |
|
Total |
90%
(9/10)
|
64.5%
(20/31)
|
71%
(22/31)
|
61.7%
(87/141)
|
/**
* Copyright 2022-2025 kronos-orm
*
* 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.kotlinorm.plugins
import com.kotlinorm.beans.task.KronosAtomicQueryTask
import com.kotlinorm.beans.task.KronosOperationResult
import com.kotlinorm.beans.task.registerTaskEventPlugin
import com.kotlinorm.beans.task.unregisterTaskEventPlugin
import com.kotlinorm.enums.DBType
import com.kotlinorm.enums.KOperationType
import com.kotlinorm.interfaces.TaskEventPlugin
import com.kotlinorm.orm.insert.InsertClause
import com.kotlinorm.types.ActionTaskEvent
import com.kotlinorm.types.QueryTaskEvent
object LastInsertIdPlugin : TaskEventPlugin {
private var loaded = false
var enabled
get() = loaded
set(value) {
if (value && !loaded) {
registerTaskEventPlugin(LastInsertIdPlugin)
loaded = true
}
if (!value && loaded) {
unregisterTaskEventPlugin(LastInsertIdPlugin)
loaded = false
}
}
val KronosOperationResult.lastInsertId
get() = this.stash["lastInsertId"] as? Long
// Generates the SQL statement needed to obtain the last inserted ID based on the provided database type.
fun lastInsertIdObtainSql(dbType: DBType): String {
return when (dbType) {
DBType.Mysql, DBType.H2, DBType.OceanBase -> "SELECT LAST_INSERT_ID()"
DBType.Oracle -> "SELECT * FROM DUAL"
DBType.Mssql -> "SELECT SCOPE_IDENTITY()"
DBType.Postgres -> "SELECT LASTVAL()"
DBType.DB2 -> "SELECT IDENTITY_VAL_LOCAL() FROM SYSIBM.SYSDUMMY1"
DBType.Sybase -> "SELECT @@IDENTITY"
DBType.SQLite -> "SELECT last_insert_rowid()"
else -> throw UnsupportedOperationException("Unsupported database type: $dbType")
}
}
override val doBeforeQuery: QueryTaskEvent? = null
override val doAfterQuery: QueryTaskEvent? = null
override val doBeforeAction: ActionTaskEvent? = null
override val doAfterAction: ActionTaskEvent = { task, wrapper ->
if (task.operationType == KOperationType.INSERT &&
(task.stash["queryId"] == true || (task.stash["queryId"] == null && enabled))
&& task.stash["useIdentity"] == true // 目前仅支持自增主键
) {
task.stash["lastInsertId"] = (wrapper.forObject(
KronosAtomicQueryTask(lastInsertIdObtainSql(wrapper.dbType)),
kClass = Long::class,
false,
listOf()
) ?: 0L) as Long
}
}
fun InsertClause<*>.withId(): InsertClause<*> {
stash["queryId"] = true
return this
}
}