Skip to content

Commit 975f863

Browse files
committed
Support the expression in the update set clause
1 parent 47c3ab7 commit 975f863

File tree

11 files changed

+125
-28
lines changed

11 files changed

+125
-28
lines changed

doma-criteria/src/main/kotlin/org/seasar/doma/criteria/context/Context.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ interface Context {
1111
sealed class Operand {
1212
data class Param(val value: InParameter<*>) : Operand()
1313
data class Prop(val value: PropertyDef<*>) : Operand()
14+
sealed class Expr : Operand() {
15+
data class Plus(val left: Expr, val right: Expr) : Expr()
16+
data class Prop(val value: Operand.Prop) : Expr()
17+
data class Param(val value: Operand.Param) : Expr()
18+
}
1419
}
1520

1621
sealed class Criterion {

doma-criteria/src/main/kotlin/org/seasar/doma/criteria/context/UpdateContext.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import org.seasar.doma.jdbc.Config
66
class UpdateContext(
77
val config: Config,
88
val entityDef: EntityDef<*>,
9-
val set: MutableMap<Operand.Prop, Operand.Param> = mutableMapOf(),
9+
val set: MutableMap<Operand.Prop, Operand> = mutableMapOf(),
1010
val where: MutableList<Criterion> = mutableListOf()
1111
) : Context {
1212

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.seasar.doma.criteria.declaration
2+
3+
import org.seasar.doma.criteria.context.Operand
4+
import org.seasar.doma.def.PropertyDef
5+
import org.seasar.doma.jdbc.Config
6+
7+
@Declaration
8+
class ExpressionDeclaration(private val config: Config) {
9+
10+
private val support = DeclarationSupport(config)
11+
12+
infix operator fun <PROPERTY> PropertyDef<PROPERTY>.plus(other: PROPERTY?): Operand.Expr {
13+
val prop = support.toProp(this)
14+
val param = support.toParam(this, other)
15+
return Operand.Expr.Plus(Operand.Expr.Prop(prop), Operand.Expr.Param(param))
16+
}
17+
18+
infix operator fun <PROPERTY> PROPERTY?.plus(other: PropertyDef<PROPERTY>): Operand.Expr {
19+
val param = support.toParam(other, this)
20+
val prop = support.toProp(other)
21+
return Operand.Expr.Plus(Operand.Expr.Param(param), Operand.Expr.Prop(prop))
22+
}
23+
}

doma-criteria/src/main/kotlin/org/seasar/doma/criteria/declaration/InsertDeclaration.kt

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,17 @@ import org.seasar.doma.def.PropertyDef
66
@Declaration
77
class InsertDeclaration(private val context: InsertContext) {
88
private val support = DeclarationSupport(context.config)
9-
private val valuesDeclaration = ValuesDeclaration()
9+
private val valuesDeclaration = ValuesDeclaration(context.config)
1010

1111
fun values(block: ValuesDeclaration.(Values) -> Unit) {
12-
valuesDeclaration.block(object : Values {
13-
override fun <PROPERTY> set(propDef: PropertyDef<PROPERTY>, value: PROPERTY?) {
14-
val prop = support.toProp(propDef)
15-
val param = support.toParam(propDef, value)
16-
context.values[prop] = param
17-
}
18-
})
12+
valuesDeclaration.block(Values())
13+
}
14+
15+
inner class Values {
16+
operator fun <PROPERTY> set(propDef: PropertyDef<PROPERTY>, value: PROPERTY?) {
17+
val prop = support.toProp(propDef)
18+
val param = support.toParam(propDef, value)
19+
context.values[prop] = param
20+
}
1921
}
2022
}
Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,31 @@
11
package org.seasar.doma.criteria.declaration
22

3+
import org.seasar.doma.criteria.context.Operand
34
import org.seasar.doma.criteria.context.UpdateContext
45
import org.seasar.doma.def.PropertyDef
56

67
@Declaration
78
class UpdateDeclaration(private val context: UpdateContext) {
89
private val support = DeclarationSupport(context.config)
9-
private val valuesDeclaration = ValuesDeclaration()
10+
private val valuesDeclaration = ValuesDeclaration(context.config)
1011
private val whereDeclaration = WhereDeclaration(context.config) { context.where.add(it) }
1112

1213
fun set(block: ValuesDeclaration.(Values) -> Unit) {
13-
valuesDeclaration.block(object : Values {
14-
override fun <PROPERTY> set(propDef: PropertyDef<PROPERTY>, value: PROPERTY?) {
15-
val prop = support.toProp(propDef)
16-
val param = support.toParam(propDef, value)
17-
context.set[prop] = param
18-
}
19-
})
14+
valuesDeclaration.block(Values())
2015
}
2116

2217
fun where(block: WhereDeclaration.() -> Unit) = whereDeclaration.block()
18+
19+
inner class Values {
20+
operator fun <PROPERTY> set(propDef: PropertyDef<PROPERTY>, value: PROPERTY?) {
21+
val prop = support.toProp(propDef)
22+
val param = support.toParam(propDef, value)
23+
context.set[prop] = param
24+
}
25+
26+
operator fun <PROPERTY> set(propDef: PropertyDef<PROPERTY>, expr: Operand.Expr) {
27+
val prop = support.toProp(propDef)
28+
context.set[prop] = expr
29+
}
30+
}
2331
}

doma-criteria/src/main/kotlin/org/seasar/doma/criteria/declaration/Values.kt

Lines changed: 0 additions & 7 deletions
This file was deleted.
Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
11
package org.seasar.doma.criteria.declaration
22

3+
import org.seasar.doma.criteria.context.Operand
4+
import org.seasar.doma.jdbc.Config
5+
36
@Declaration
4-
class ValuesDeclaration
7+
class ValuesDeclaration(val config: Config) {
8+
private val expressionDeclaration = ExpressionDeclaration(config)
9+
10+
fun expression(block: ExpressionDeclaration.() -> Operand.Expr): Operand.Expr {
11+
return expressionDeclaration.block()
12+
}
13+
}

doma-criteria/src/main/kotlin/org/seasar/doma/criteria/query/BuilderSupport.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,20 @@ class BuilderSupport(
5858
buf.appendParameter(param.value)
5959
}
6060

61+
fun expr(expr: Operand.Expr) {
62+
when (expr) {
63+
is Operand.Expr.Prop -> column(expr.value)
64+
is Operand.Expr.Param -> param(expr.value)
65+
is Operand.Expr.Plus -> {
66+
buf.appendSql("(")
67+
expr(expr.left)
68+
buf.appendSql(" + ")
69+
expr(expr.right)
70+
buf.appendSql(")")
71+
}
72+
}
73+
}
74+
6175
fun visitCriterion(index: Int, c: Criterion) {
6276
when (c) {
6377
is Criterion.Eq -> equality(c.left, c.right, "=")
@@ -92,6 +106,7 @@ class BuilderSupport(
92106
return when (operand) {
93107
is Operand.Param -> operand.value.wrapper.get() == null
94108
is Operand.Prop -> false
109+
is Operand.Expr -> false
95110
}
96111
}
97112

doma-criteria/src/main/kotlin/org/seasar/doma/criteria/query/UpdateBuilder.kt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,14 @@ class UpdateBuilder(
2828
table(context.entityDef)
2929
if (context.set.isNotEmpty()) {
3030
buf.appendSql(" set ")
31-
context.set.forEach { (prop, param) ->
32-
column(prop)
31+
context.set.forEach { (left, right) ->
32+
column(left)
3333
buf.appendSql(" = ")
34-
param(param)
34+
when (right) {
35+
is Operand.Prop -> column(right)
36+
is Operand.Param -> param(right)
37+
is Operand.Expr -> expr(right)
38+
}
3539
buf.appendSql(", ")
3640
}
3741
buf.cutBackSql(2)
@@ -59,6 +63,10 @@ class UpdateBuilder(
5963
support.param(param)
6064
}
6165

66+
private fun expr(expr: Operand.Expr) {
67+
support.expr(expr)
68+
}
69+
6270
private fun visitCriterion(index: Int, c: Criterion) {
6371
support.visitCriterion(index, c)
6472
}

doma-criteria/src/test/kotlin/org/seasar/doma/criteria/SqlDslTest.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.seasar.doma.criteria
22

3+
import java.math.BigDecimal
34
import org.junit.jupiter.api.Assertions.assertEquals
45
import org.junit.jupiter.api.Test
56
import org.seasar.doma.criteria.entity.Dept_
@@ -234,4 +235,21 @@ internal class SqlDslTest {
234235
val expected = """update "CATA"."DEPT" t0_ set t0_.NAME = 'hoge' where t0_.ID = 1"""
235236
assertEquals(expected, sql.formattedSql)
236237
}
238+
239+
@Test
240+
fun update_expression() {
241+
val query = sql {
242+
update(::Emp_) { e ->
243+
set {
244+
it[e.salary] = expression { e.salary + BigDecimal("1") }
245+
}
246+
where {
247+
e.id eq 1
248+
}
249+
}
250+
}
251+
val sql = query.asSql(config)
252+
val expected = """update EMP t0_ set t0_.SALARY = (t0_.SALARY + 1) where t0_.ID = 1"""
253+
assertEquals(expected, sql.formattedSql)
254+
}
237255
}

0 commit comments

Comments
 (0)