Skip to content

Commit

Permalink
chore! EXPOSED-655 Join column default fields defaultValueFun, defaul…
Browse files Browse the repository at this point in the history
…tValueInDb, isDatabaseGenerated into one field
  • Loading branch information
obabichevjb committed Nov 27, 2024
1 parent 7e5d03f commit d925535
Show file tree
Hide file tree
Showing 17 changed files with 297 additions and 87 deletions.
14 changes: 14 additions & 0 deletions documentation-website/Writerside/topics/Breaking-Changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,20 @@
-- Starting from version 0.57.0
INSERT INTO TEST DEFAULT VALUES
```

* The fields `defaultValueFun`, `dbDefaultValue`, and `isDatabaseGenerated` have been consolidated into a single field,
`default`, of type `ColumnDefault`. The previous setup with the three separate fields often led to inconsistencies
and confusion regarding their various combinations.

Here’s how you can migrate the common combinations:
- `defaultValueFun != null && dbDefaultValue != null` (knows as `default()`) becomes `DatabaseColumnDefaultExpressionWithValue`
- `dbDefaultValue != null` (knows as `defaultExpression()`) becomes `DatabaseColumnDefaultExpression`
- `defaultValueFun != null` (knows as `clientDefault()`) becomes `ClientColumnDefaultValue`
- `isDatabaseGenerated == true` (knows as `databaseGenerated`) becomes `DatabaseGeneratedColumnDefault`

If it is anticipated that a column will be transformed using `transform()`,
the default value for that column should implement `TransformableColumnDefault`. However, not all defaults need to
implement this interface; it is primarily necessary for columns with in-memory Kotlin values.

## 0.56.0
* If the `distinct` parameter of `groupConcat()` is set to `true`, when using Oracle or SQL Server, this will now fail early with an
Expand Down
64 changes: 59 additions & 5 deletions exposed-core/api/exposed-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,15 @@ public final class org/jetbrains/exposed/sql/CheckConstraint : org/jetbrains/exp
public final class org/jetbrains/exposed/sql/CheckConstraint$Companion {
}

public abstract interface class org/jetbrains/exposed/sql/ClientColumnDefault : org/jetbrains/exposed/sql/ColumnDefault {
}

public final class org/jetbrains/exposed/sql/ClientColumnDefaultValue : org/jetbrains/exposed/sql/ClientColumnDefault, org/jetbrains/exposed/sql/ColumnDefaultValue, org/jetbrains/exposed/sql/TransformableColumnDefault {
public fun <init> (Lkotlin/jvm/functions/Function0;)V
public fun getValue ()Lkotlin/jvm/functions/Function0;
public fun transform (Lkotlin/jvm/functions/Function1;)Lorg/jetbrains/exposed/sql/ColumnDefault;
}

public final class org/jetbrains/exposed/sql/Coalesce : org/jetbrains/exposed/sql/Function {
public fun <init> (Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;Lorg/jetbrains/exposed/sql/Expression;[Lorg/jetbrains/exposed/sql/Expression;)V
public fun toQueryBuilder (Lorg/jetbrains/exposed/sql/QueryBuilder;)V
Expand All @@ -423,32 +432,54 @@ public final class org/jetbrains/exposed/sql/Column : org/jetbrains/exposed/sql/
public synthetic fun compareTo (Ljava/lang/Object;)I
public fun compareTo (Lorg/jetbrains/exposed/sql/Column;)I
public fun createStatement ()Ljava/util/List;
public final fun defaultValueInDb ()Lorg/jetbrains/exposed/sql/Expression;
public final fun descriptionDdl (Z)Ljava/lang/String;
public static synthetic fun descriptionDdl$default (Lorg/jetbrains/exposed/sql/Column;ZILjava/lang/Object;)Ljava/lang/String;
public fun dropStatement ()Ljava/util/List;
public fun equals (Ljava/lang/Object;)Z
public fun getColumnType ()Lorg/jetbrains/exposed/sql/IColumnType;
public fun getDdl ()Ljava/util/List;
public final fun getDefaultValueFun ()Lkotlin/jvm/functions/Function0;
public final fun getDefault ()Lorg/jetbrains/exposed/sql/ColumnDefault;
public final fun getForeignKey ()Lorg/jetbrains/exposed/sql/ForeignKeyConstraint;
public final fun getName ()Ljava/lang/String;
public final fun getReferee ()Lorg/jetbrains/exposed/sql/Column;
public final fun getTable ()Lorg/jetbrains/exposed/sql/Table;
public fun hashCode ()I
public final fun isDatabaseGenerated ()Z
public fun modifyStatement ()Ljava/util/List;
public final fun modifyStatements (Lorg/jetbrains/exposed/sql/ColumnDiff;)Ljava/util/List;
public final fun nameInDatabaseCase ()Ljava/lang/String;
public final fun nameUnquoted ()Ljava/lang/String;
public final fun referee ()Lorg/jetbrains/exposed/sql/Column;
public final fun setDefaultValueFun (Lkotlin/jvm/functions/Function0;)V
public final fun setDefault (Lorg/jetbrains/exposed/sql/ColumnDefault;)V
public final fun setForeignKey (Lorg/jetbrains/exposed/sql/ForeignKeyConstraint;)V
public fun toQueryBuilder (Lorg/jetbrains/exposed/sql/QueryBuilder;)V
public fun toString ()Ljava/lang/String;
public final fun withColumnType (Lorg/jetbrains/exposed/sql/IColumnType;)Lorg/jetbrains/exposed/sql/Column;
}

public abstract interface class org/jetbrains/exposed/sql/ColumnDefault {
}

public abstract interface class org/jetbrains/exposed/sql/ColumnDefaultExpression : org/jetbrains/exposed/sql/ColumnDefault {
public abstract fun getExpression ()Lorg/jetbrains/exposed/sql/Expression;
}

public final class org/jetbrains/exposed/sql/ColumnDefaultKt {
public static final fun clientDefaultValue (Lorg/jetbrains/exposed/sql/Column;)Ljava/lang/Object;
public static final fun clientDefaultValueOrExpression (Lorg/jetbrains/exposed/sql/Column;)Ljava/lang/Object;
public static final fun databaseDefaultExpression (Lorg/jetbrains/exposed/sql/Column;)Lorg/jetbrains/exposed/sql/Expression;
public static final fun defaultValue (Lorg/jetbrains/exposed/sql/Column;)Ljava/lang/Object;
public static final fun hasClientDefault (Lorg/jetbrains/exposed/sql/Column;)Z
public static final fun hasClientDefaultValue (Lorg/jetbrains/exposed/sql/Column;)Z
public static final fun hasDatabaseDefault (Lorg/jetbrains/exposed/sql/Column;)Z
public static final fun hasDefaultValue (Lorg/jetbrains/exposed/sql/Column;)Z
public static final fun isDefaultable (Lorg/jetbrains/exposed/sql/Column;)Z
public static final fun transform (Lorg/jetbrains/exposed/sql/ColumnDefault;Lkotlin/jvm/functions/Function1;)Lorg/jetbrains/exposed/sql/ColumnDefault;
}

public abstract interface class org/jetbrains/exposed/sql/ColumnDefaultValue : org/jetbrains/exposed/sql/ColumnDefault {
public abstract fun getValue ()Lkotlin/jvm/functions/Function0;
}

public final class org/jetbrains/exposed/sql/ColumnDiff {
public static final field Companion Lorg/jetbrains/exposed/sql/ColumnDiff$Companion;
public fun <init> (ZZZZZ)V
Expand Down Expand Up @@ -688,6 +719,21 @@ public final class org/jetbrains/exposed/sql/Database$Companion {
public final fun registerJdbcDriver (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
}

public abstract interface class org/jetbrains/exposed/sql/DatabaseColumnDefault : org/jetbrains/exposed/sql/ColumnDefault {
}

public final class org/jetbrains/exposed/sql/DatabaseColumnDefaultExpression : org/jetbrains/exposed/sql/ColumnDefaultExpression, org/jetbrains/exposed/sql/DatabaseColumnDefault {
public fun <init> (Lorg/jetbrains/exposed/sql/Expression;)V
public fun getExpression ()Lorg/jetbrains/exposed/sql/Expression;
}

public final class org/jetbrains/exposed/sql/DatabaseColumnDefaultExpressionWithValue : org/jetbrains/exposed/sql/ColumnDefaultExpression, org/jetbrains/exposed/sql/ColumnDefaultValue, org/jetbrains/exposed/sql/DatabaseColumnDefault, org/jetbrains/exposed/sql/TransformableColumnDefault {
public fun <init> (Lorg/jetbrains/exposed/sql/Expression;Lkotlin/jvm/functions/Function0;)V
public fun getExpression ()Lorg/jetbrains/exposed/sql/Expression;
public fun getValue ()Lkotlin/jvm/functions/Function0;
public fun transform (Lkotlin/jvm/functions/Function1;)Lorg/jetbrains/exposed/sql/ColumnDefault;
}

public final class org/jetbrains/exposed/sql/DatabaseConfig {
public static final field Companion Lorg/jetbrains/exposed/sql/DatabaseConfig$Companion;
public synthetic fun <init> (Lorg/jetbrains/exposed/sql/SqlLogger;ZLjava/lang/Integer;IIJJIJJZLjava/lang/Long;IZLorg/jetbrains/exposed/sql/vendors/DatabaseDialect;Lorg/jetbrains/exposed/sql/Schema;IZLkotlin/jvm/internal/DefaultConstructorMarker;)V
Expand Down Expand Up @@ -761,6 +807,10 @@ public final class org/jetbrains/exposed/sql/DatabaseConfig$Companion {
public abstract interface class org/jetbrains/exposed/sql/DatabaseConnectionAutoRegistration : kotlin/jvm/functions/Function1 {
}

public final class org/jetbrains/exposed/sql/DatabaseGeneratedColumnDefault : org/jetbrains/exposed/sql/DatabaseColumnDefault {
public fun <init> ()V
}

public final class org/jetbrains/exposed/sql/DatabaseKt {
public static final fun getName (Lorg/jetbrains/exposed/sql/Database;)Ljava/lang/String;
}
Expand Down Expand Up @@ -2712,6 +2762,10 @@ public class org/jetbrains/exposed/sql/Transaction : org/jetbrains/exposed/sql/U
public final class org/jetbrains/exposed/sql/Transaction$Companion {
}

public abstract interface class org/jetbrains/exposed/sql/TransformableColumnDefault : org/jetbrains/exposed/sql/ColumnDefault {
public abstract fun transform (Lkotlin/jvm/functions/Function1;)Lorg/jetbrains/exposed/sql/ColumnDefault;
}

public final class org/jetbrains/exposed/sql/Trim : org/jetbrains/exposed/sql/Function {
public fun <init> (Lorg/jetbrains/exposed/sql/Expression;)V
public final fun getExpr ()Lorg/jetbrains/exposed/sql/Expression;
Expand Down Expand Up @@ -3210,7 +3264,7 @@ public class org/jetbrains/exposed/sql/statements/InsertStatement : org/jetbrain
public final fun getResultedValues ()Ljava/util/List;
public final fun getTable ()Lorg/jetbrains/exposed/sql/Table;
protected fun isColumnValuePreferredFromResultSet (Lorg/jetbrains/exposed/sql/Column;Ljava/lang/Object;)Z
protected final fun isEntityIdClientSideGeneratedUUID (Lorg/jetbrains/exposed/sql/Column;)Z
protected final fun isEntityIdClientSideGeneratedUUID (Lorg/jetbrains/exposed/sql/Column;)Ljava/lang/Boolean;
public final fun isIgnore ()Z
public fun prepareSQL (Lorg/jetbrains/exposed/sql/Transaction;Z)Ljava/lang/String;
public fun prepared (Lorg/jetbrains/exposed/sql/Transaction;Ljava/lang/String;)Lorg/jetbrains/exposed/sql/statements/api/PreparedStatementApi;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ open class CompositeIdTable(name: String = "") : IdTable<CompositeID>(name) {
}
)
return Column(this, "composite_id", EntityIDColumnType(placeholder)).apply {
defaultValueFun = null
default = null
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ class Alias<out T : Table>(val delegate: T, val alias: String) : Table() {
val tableNameWithAlias: String = "${delegate.tableName} $alias"

private fun <T> Column<T>.clone() = Column<T>(this@Alias, name, columnType).also {
it.defaultValueFun = defaultValueFun
it.dbDefaultValue = dbDefaultValue
it.isDatabaseGenerated = isDatabaseGenerated
it.default = default
it.foreignKey = foreignKey
it.extraDefinitions = extraDefinitions
}
Expand Down
38 changes: 13 additions & 25 deletions exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Column.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,10 @@ class Column<T>(
@Suppress("UNCHECKED_CAST")
fun <S : T> referee(): Column<S>? = referee as? Column<S>

/** Returns the function that calculates the default value for this column. */
var defaultValueFun: (() -> T)? = null
internal var dbDefaultValue: Expression<T>? = null

/** Returns the default value for this column on the database-side. */
fun defaultValueInDb() = dbDefaultValue

internal var isDatabaseGenerated: Boolean = false

/** Returns whether this column's value will be generated in the database. */
fun isDatabaseGenerated() = isDatabaseGenerated
/**
* The default value for this column.
*/
var default: ColumnDefault<T>? = null

internal var extraDefinitions = mutableListOf<Any>()

Expand Down Expand Up @@ -121,12 +114,13 @@ class Column<T>(
else -> append(columnType.sqlType())
}

val defaultValue = dbDefaultValue
if (defaultValue != null) {
val expressionSQL = currentDialect.dataTypeProvider.processForDefaultValue(defaultValue)
if (!currentDialect.isAllowedAsColumnDefault(defaultValue)) {
val defaultDatabaseValue = databaseDefaultExpression()

if (defaultDatabaseValue != null) {
val expressionSQL = currentDialect.dataTypeProvider.processForDefaultValue(defaultDatabaseValue)
if (!currentDialect.isAllowedAsColumnDefault(defaultDatabaseValue)) {
val clientDefault = when {
defaultValueFun != null && dbDefaultValue == null -> " Expression will be evaluated on the client."
hasClientDefault() -> " Expression will be evaluated on the client."
!columnType.nullable -> " Column will be created with NULL marker."
else -> ""
}
Expand All @@ -148,7 +142,7 @@ class Column<T>(
append(extraDefinitions.joinToString(separator = " ", prefix = " ") { "$it" })
}

if (columnType.nullable || (defaultValue != null && defaultValueFun == null && !currentDialect.isAllowedAsColumnDefault(defaultValue))) {
if (columnType.nullable || (defaultDatabaseValue != null && !currentDialect.isAllowedAsColumnDefault(defaultDatabaseValue))) {
append(" NULL")
} else if (!isPKColumn || (currentDialect is SQLiteDialect && !isSQLiteAutoIncColumn)) {
append(" NOT NULL")
Expand All @@ -163,14 +157,10 @@ class Column<T>(
val newColumn: Column<R> = Column(table, name, columnType)
newColumn.foreignKey = foreignKey
@Suppress("UNCHECKED_CAST")
newColumn.dbDefaultValue = dbDefaultValue as Expression<R>?
newColumn.isDatabaseGenerated = isDatabaseGenerated
newColumn.default = default as ColumnDefault<R>?
newColumn.extraDefinitions = extraDefinitions
body?.let { newColumn.it() }

if (defaultValueFun != null) {
require(newColumn.defaultValueFun != null) { "defaultValueFun was lost on cloning the column" }
}
return newColumn
}

Expand All @@ -183,9 +173,7 @@ class Column<T>(
columnType = columnType
).also {
it.foreignKey = this.foreignKey
it.defaultValueFun = this.defaultValueFun
it.dbDefaultValue = this.dbDefaultValue
it.isDatabaseGenerated = this.isDatabaseGenerated
it.default = this.default
it.extraDefinitions = this.extraDefinitions
}

Expand Down
Loading

0 comments on commit d925535

Please sign in to comment.