Skip to content

Commit 47aeefc

Browse files
refactor update function
1 parent 7bbc06f commit 47aeefc

File tree

3 files changed

+34
-54
lines changed

3 files changed

+34
-54
lines changed

ktorm-ksp-compiler/src/main/kotlin/org/ktorm/ksp/compiler/generator/AddFunctionGenerator.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ internal object AddFunctionGenerator {
110110
return CodeBlock.of(code)
111111
}
112112

113-
private fun addValFun(table: TableMetadata, useGeneratedKey: Boolean): CodeBlock {
113+
internal fun addValFun(table: TableMetadata, useGeneratedKey: Boolean): CodeBlock {
114114
if (useGeneratedKey) {
115115
val pk = table.columns.single { it.isPrimaryKey }
116116
val code = """

ktorm-ksp-compiler/src/main/kotlin/org/ktorm/ksp/compiler/generator/UpdateFunctionGenerator.kt

Lines changed: 31 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,20 @@ import org.ktorm.dsl.AliasRemover
2424
import org.ktorm.entity.EntitySequence
2525
import org.ktorm.expression.ColumnAssignmentExpression
2626
import org.ktorm.expression.UpdateExpression
27-
import org.ktorm.ksp.compiler.util.*
27+
import org.ktorm.ksp.compiler.util._type
2828
import org.ktorm.ksp.spi.TableMetadata
29-
import org.ktorm.schema.Column
3029

3130
@OptIn(KotlinPoetKspPreview::class)
3231
internal object UpdateFunctionGenerator {
3332

3433
fun generate(table: TableMetadata): FunSpec {
35-
val kdoc = "" +
36-
"Update the given entity to the database and return the affected record number. " +
37-
"If [isDynamic] is set to true, the generated SQL will include only the non-null columns. "
34+
val kdoc = """
35+
Update the given entity to the database.
36+
37+
@param entity the entity to be updated.
38+
@param isDynamic whether only non-null columns should be updated.
39+
@return the affected record number.
40+
""".trimIndent()
3841

3942
val entityClass = table.entityClass.toClassName()
4043
val tableClass = ClassName(table.entityClass.packageName.asString(), table.tableClassName)
@@ -46,28 +49,13 @@ internal object UpdateFunctionGenerator {
4649
.addParameter(ParameterSpec.builder("isDynamic", typeNameOf<Boolean>()).defaultValue("false").build())
4750
.returns(Int::class.asClassName())
4851
.addCode(AddFunctionGenerator.checkForDml())
49-
.addCode(addValFun())
52+
.addCode(AddFunctionGenerator.addValFun(table, useGeneratedKey = false))
5053
.addCode(addAssignments(table))
51-
.addCode(buildConditions(table))
52-
.addCode(createExpression())
54+
.addCode(createExpression(table))
5355
.addStatement("return database.executeUpdate(expression)")
5456
.build()
5557
}
5658

57-
private fun addValFun(): CodeBlock {
58-
val code = """
59-
fun <T : Any> MutableList<%1T<*>>.addVal(column: %2T<T>, value: T?, isDynamic: Boolean) {
60-
if (!isDynamic || value != null) {
61-
this += %1T(column.asExpression(), column.wrapArgument(value))
62-
}
63-
}
64-
65-
66-
""".trimIndent()
67-
68-
return CodeBlock.of(code, ColumnAssignmentExpression::class.asClassName(), Column::class.asClassName())
69-
}
70-
7159
private fun addAssignments(table: TableMetadata): CodeBlock {
7260
return buildCodeBlock {
7361
addStatement("val assignments = ArrayList<%T<*>>()", ColumnAssignmentExpression::class.asClassName())
@@ -78,14 +66,12 @@ internal object UpdateFunctionGenerator {
7866
}
7967

8068
addStatement(
81-
"assignments.addVal(sourceTable.%N, entity.%N, isDynamic)",
69+
"assignments.addVal(sourceTable.%N, entity.%N)",
8270
column.columnPropertyName,
83-
column.entityProperty.simpleName.asString(),
71+
column.entityProperty.simpleName.asString()
8472
)
8573
}
8674

87-
add("\n")
88-
8975
beginControlFlow("if (assignments.isEmpty())")
9076
addStatement("return 0")
9177
endControlFlow()
@@ -94,20 +80,22 @@ internal object UpdateFunctionGenerator {
9480
}
9581
}
9682

97-
private fun buildConditions(table: TableMetadata): CodeBlock {
83+
private fun createExpression(table: TableMetadata): CodeBlock {
9884
return buildCodeBlock {
99-
add("«val conditions = listOf(")
85+
addStatement(
86+
"val visitor = database.dialect.createExpressionVisitor(%T)",
87+
AliasRemover::class.asClassName()
88+
)
10089

101-
for (column in table.columns) {
102-
if (!column.isPrimaryKey) {
103-
continue
104-
}
90+
add("«val conditions = ")
10591

92+
val primaryKeys = table.columns.filter { it.isPrimaryKey }
93+
for ((i, column) in primaryKeys.withIndex()) {
10694
val condition: String
10795
if (column.entityProperty._type.isMarkedNullable) {
108-
condition = "sourceTable.%N·%M·entity.%N!!,"
96+
condition = "(sourceTable.%N·%M·entity.%N!!)"
10997
} else {
110-
condition = "sourceTable.%N·%M·entity.%N,"
98+
condition = "(sourceTable.%N·%M·entity.%N)"
11199
}
112100

113101
add(
@@ -116,26 +104,18 @@ internal object UpdateFunctionGenerator {
116104
MemberName("org.ktorm.dsl", "eq", true),
117105
column.entityProperty.simpleName.asString()
118106
)
107+
108+
if (i < primaryKeys.lastIndex) {
109+
add("·%M·", MemberName("org.ktorm.dsl", "and", true))
110+
}
119111
}
120112

121-
add(")\n»")
122-
}
123-
}
113+
add("\n»")
124114

125-
private fun createExpression(): CodeBlock {
126-
val code = """
127-
val expression = database.dialect.createExpressionVisitor(%T).visit(
128-
%T(sourceTable.asExpression(), assignments, conditions.%M().asExpression())
115+
addStatement(
116+
"val expression = visitor.visit(%T(sourceTable.asExpression(), assignments, conditions))",
117+
UpdateExpression::class.asClassName()
129118
)
130-
131-
132-
""".trimIndent()
133-
134-
return CodeBlock.of(
135-
code,
136-
AliasRemover::class.asClassName(),
137-
UpdateExpression::class.asClassName(),
138-
MemberName("org.ktorm.dsl", "combineConditions", true)
139-
)
119+
}
140120
}
141121
}

ktorm-ksp-compiler/src/test/kotlin/org/ktorm/ksp/compiler/generator/UpdateFunctionGeneratorTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class UpdateFunctionGeneratorTest : BaseKspTest() {
1010
@Table
1111
data class User(
1212
@PrimaryKey
13-
var id: Int?,
13+
var id: Int,
1414
var username: String,
1515
var age: Int,
1616
)
@@ -32,7 +32,7 @@ class UpdateFunctionGeneratorTest : BaseKspTest() {
3232
@Table
3333
data class User(
3434
@PrimaryKey
35-
var id: Int?,
35+
var id: Int,
3636
var username: String,
3737
var age: Int
3838
)

0 commit comments

Comments
 (0)