Skip to content

Commit

Permalink
Support update { it[column] = nullableValue }
Browse files Browse the repository at this point in the history
Key change is UpdateBuilder#setWithEntityIdValue, which now accepts
column: Column<out EntityID<S>?>, value: S?
previous signature was
column: Column<out EntityID<S>>, value: S?

A downside is that "[optionalReferenceColumn] = null" can't decide between
"null as ColumnType?" and "null as EntityID<ColumnType>?"

update {
  // it[optionalReferenceColumn] = null // <- does not work
  // Workaround: specify null type explicitly to call the proper overload
  it[optionalReferenceColumn] = null as EntityID<ColumnType>?
  // The following works as well:
  // it[optionalReferenceColumn] = null as ColumnType?
}

fixes JetBrains#1275
  • Loading branch information
vlsi committed Jun 19, 2021
1 parent 2c616ec commit 4018470
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ open class BatchUpdateStatement(val table: IdTable<*>) : UpdateStatement(table,
data.add(id to values)
}

override fun <T, S : T?> update(column: Column<T>, value: Expression<S>) = error("Expressions unsupported in batch update")
override fun <T> update(column: Column<T>, value: Expression<out T>) = error("Expressions unsupported in batch update")

override fun prepareSQL(transaction: Transaction): String =
"${super.prepareSQL(transaction)} WHERE ${transaction.identity(table.id)} = ?"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,32 +24,32 @@ abstract class UpdateBuilder<out T>(type: StatementType, targets: List<Table>) :
}

@JvmName("setWithEntityIdExpression")
operator fun <S, ID : EntityID<S>, E : Expression<S>> set(column: Column<ID>, value: E) {
operator fun <S : Comparable<S>> set(column: Column<out EntityID<S>?>, value: Expression<out S?>) {
require(!values.containsKey(column)) { "$column is already initialized" }
column.columnType.validateValueBeforeUpdate(value)
values[column] = value
}

@JvmName("setWithEntityIdValue")
operator fun <S : Comparable<S>, ID : EntityID<S>, E : S?> set(column: Column<ID>, value: E) {
operator fun <S : Comparable<S>> set(column: Column<out EntityID<S>?>, value: S?) {
require(!values.containsKey(column)) { "$column is already initialized" }
column.columnType.validateValueBeforeUpdate(value)
values[column] = value
}

open operator fun <T, S : T, E : Expression<S>> set(column: Column<T>, value: E) = update(column, value)
open operator fun <S> set(column: Column<S>, value: Expression<out S>) = update(column, value)

open operator fun <S> set(column: CompositeColumn<S>, value: S) {
column.getRealColumnsWithValues(value).forEach { (realColumn, itsValue) -> set(realColumn as Column<Any?>, itsValue) }
}

open fun <T, S : T?> update(column: Column<T>, value: Expression<S>) {
open fun <S> update(column: Column<S>, value: Expression<out S>) {
require(!values.containsKey(column)) { "$column is already initialized" }
column.columnType.validateValueBeforeUpdate(value)
values[column] = value
}

open fun <T, S : T?> update(column: Column<T>, value: SqlExpressionBuilder.() -> Expression<S>) {
open fun <S> update(column: Column<S>, value: SqlExpressionBuilder.() -> Expression<out S>) {
require(!values.containsKey(column)) { "$column is already initialized" }
val expression = SqlExpressionBuilder.value()
column.columnType.validateValueBeforeUpdate(expression)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,17 @@ class DDLTests : DatabaseTestsBase() {
assertEquals(2L, Table2.selectAll().count())

Table2.update {
it[table1] = null
}

Table2.update {
// = null can't decide between "null as Int?" and "null as EntityID<Int?>"
// it[table1] = null
it[table1] = null as Int?
}
Table2.update {
// = null can't decide between "null as Int?" and "null as EntityID<Int>?"
// it[table1] = null
it[table1] = null as EntityID<Int>?
}

Table1.deleteAll()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,13 @@ class InsertTests : DatabaseTestsBase() {
}

verify("exp3")

tbl.insert {
it[string] = expression(" _exp4_ ")
it[nullableInt] = LiteralOp(IntegerColumnType(), null as Int?)
}

verify("exp4")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,29 @@ class EntityTests : DatabaseTestsBase() {
}
}

@Test
fun testOptionalReference() {
withTables(EntityTestsData.XTable, EntityTestsData.YTable) {
val y = EntityTestsData.YEntity.new { }
EntityTestsData.XTable.insert {
it[y1] = y.id
}
EntityTestsData.XTable.insert {
// = null can't decide between "null as String?" and "null as EntityId<String>?"
// it[EntityTestsData.XTable.y1] = null
it[y1] = null as String?
}
EntityTestsData.XTable.insert {
// = null can't decide between "null as String?" and "null as EntityID<String>?"
// it[EntityTestsData.XTable.y1] = null
it[y1] = null as EntityID<String>?
}
EntityTestsData.XTable.insert {
it[y1] = "42"
}
}
}

object Boards : IntIdTable(name = "board") {
val name = varchar("name", 255).index(isUnique = true)
}
Expand Down

0 comments on commit 4018470

Please sign in to comment.