stefano
01/09/2024, 7:30 PMcase
in a select over which komapper blows up with
java.lang.UnsupportedOperationException: null
at org.komapper.core.dsl.expression.LiteralExpression.getColumnName(LiteralExpression.kt:14) ~[komapper-core-1.16.0.jar:na]
because I'm returning more than 3 columns in the query so it's switching to a Record
return type instead of a tuple. How can I set an as <name>
alias to an expression in a select? Or is there a more idiomatic solution?stefano
01/09/2024, 7:34 PMval o = Meta.order
val query = QueryDsl
.from(o)
.where {
o.date between LocalDate.parse("2023-01-01")..LocalDate.parse("2023-12-15")
or { o.date between LocalDate.parse("2022-01-01")..LocalDate.parse("2022-12-15") }
}
.select(
o.id,
o.clientId,
o.revenue,
case(
When(
{ o.date between LocalDate.parse("2023-01-01")..LocalDate.parse("2023-12-15")
},
literal("current"),
),
When(
{ o.date between LocalDate.parse("2022-01-01")..LocalDate.parse("2022-12-15") },
literal("previous"),
)
).alias("period")
)
stefano
01/09/2024, 7:36 PMalias()
but the error is still there...stefano
01/09/2024, 8:08 PMAliasExpression
doesn't use the provided column name to resolve columnName
, but rather delegate to the original expression:
internal data class AliasExpression<T : Any, S : Any>(
val expression: ColumnExpression<T, S>,
val alias: String,
val alwaysQuoteAlias: Boolean,
) : ColumnExpression<T, S> by expression
Not sure if this is intended, from my limited point of view it doesn't seem to make too much sense?stefano
01/09/2024, 8:12 PMColumnExpression
🫤dave08
01/09/2024, 8:35 PMstefano
01/09/2024, 8:45 PMstefano
01/09/2024, 8:45 PMToshihiro Nakamura
01/09/2024, 11:14 PMval period = case(
When(
{
o.date between LocalDate.parse("2023-01-01")..LocalDate.parse("2023-12-15")
},
literal("current"),
),
When(
{ o.date between LocalDate.parse("2022-01-01")..LocalDate.parse("2022-12-15") },
literal("previous"),
)
)
val query = QueryDsl
.from(o)
.where {
o.date between LocalDate.parse("2023-01-01")..LocalDate.parse("2023-12-15")
or { o.date between LocalDate.parse("2022-01-01")..LocalDate.parse("2022-12-15") }
}
.select(
o.id,
o.clientId,
o.revenue,
period
)
val list = db.runQuery(query)
list.forEach { record ->
println(record[o.id])
println(record[o.clientId])
println(record[o.revenue])
println(record[period])
}
Toshihiro Nakamura
01/09/2024, 11:19 PM@KomapperProjection
to map to a class.
First, create a class as follows:
@KomapperEntity
@KomapperProjection
data class OrderDto(
@KomapperId
val id: Int,
val clientId: String,
val revenue: Int,
val period: String,
)
Then, you can write your query as follows:
val query = QueryDsl
.from(o)
.where {
o.date between LocalDate.parse("2023-01-01")..LocalDate.parse("2023-12-15")
or { o.date between LocalDate.parse("2022-01-01")..LocalDate.parse("2022-12-15") }
}
.selectAsOrderDto(
id = o.id,
clientId = o.clientId,
revenue = o.revenue,
period = case(
When(
{
o.date between LocalDate.parse("2023-01-01")..LocalDate.parse("2023-12-15")
},
literal("current"),
),
When(
{ o.date between LocalDate.parse("2022-01-01")..LocalDate.parse("2022-12-15") },
literal("previous"),
)
)
)
val list: List<OrderDto> = db.runQuery(query)
list.forEach { orderDto ->
println(orderDto.id)
println(orderDto.clientId)
println(orderDto.revenue)
println(orderDto.date)
}
stefano
01/10/2024, 10:25 AM