diff --git a/documentation-website/Writerside/topics/Breaking-Changes.md b/documentation-website/Writerside/topics/Breaking-Changes.md index ee3e5cefd8..95a30f2e93 100644 --- a/documentation-website/Writerside/topics/Breaking-Changes.md +++ b/documentation-website/Writerside/topics/Breaking-Changes.md @@ -11,6 +11,9 @@ * `ArrayColumnType` now supports multidimensional arrays and includes an additional generic parameter. If it was previously used for one-dimensional arrays with the parameter `T` like `ArrayColumnType`, it should now be defined as `ArrayColumnType>`. For instance, `ArrayColumnType` should now be `ArrayColumnType>`. +* `EntityID` and `CompositeID` no longer implement `Comparable` themselves, to allow their wrapped identity values to be of a type that is not + necessarily `Comparable`. Any use of an entity's `id` with Kotlin comparison operators or `compareTo()` will now require that the wrapped + value be used directly: `entity1.id < entity2.id` will need to become `entity1.id.value < entity2.id.value`. ## 0.55.0 * The `DeleteStatement` property `table` is now deprecated in favor of `targetsSet`, which holds a `ColumnSet` that may be a `Table` or `Join`. diff --git a/exposed-core/api/exposed-core.api b/exposed-core/api/exposed-core.api index 11264621f6..0173d08017 100644 --- a/exposed-core/api/exposed-core.api +++ b/exposed-core/api/exposed-core.api @@ -1,7 +1,5 @@ -public final class org/jetbrains/exposed/dao/id/CompositeID : java/lang/Comparable { +public final class org/jetbrains/exposed/dao/id/CompositeID { public static final field Companion Lorg/jetbrains/exposed/dao/id/CompositeID$Companion; - public synthetic fun compareTo (Ljava/lang/Object;)I - public fun compareTo (Lorg/jetbrains/exposed/dao/id/CompositeID;)I public final fun contains (Lorg/jetbrains/exposed/sql/Column;)Z public fun equals (Ljava/lang/Object;)Z public final fun get (Lorg/jetbrains/exposed/sql/Column;)Ljava/lang/Object; @@ -23,11 +21,9 @@ public class org/jetbrains/exposed/dao/id/CompositeIdTable : org/jetbrains/expos public final fun getId ()Lorg/jetbrains/exposed/sql/Column; } -public class org/jetbrains/exposed/dao/id/EntityID : java/lang/Comparable { +public class org/jetbrains/exposed/dao/id/EntityID { public fun (Ljava/lang/Object;Lorg/jetbrains/exposed/dao/id/IdTable;)V protected fun (Lorg/jetbrains/exposed/dao/id/IdTable;Ljava/lang/Object;)V - public synthetic fun compareTo (Ljava/lang/Object;)I - public fun compareTo (Lorg/jetbrains/exposed/dao/id/EntityID;)I public fun equals (Ljava/lang/Object;)Z public final fun getTable ()Lorg/jetbrains/exposed/dao/id/IdTable; public final fun getValue ()Ljava/lang/Object; diff --git a/exposed-core/src/main/kotlin/org/jetbrains/exposed/dao/id/CompositeID.kt b/exposed-core/src/main/kotlin/org/jetbrains/exposed/dao/id/CompositeID.kt index f7e81112d4..1d06e12e62 100644 --- a/exposed-core/src/main/kotlin/org/jetbrains/exposed/dao/id/CompositeID.kt +++ b/exposed-core/src/main/kotlin/org/jetbrains/exposed/dao/id/CompositeID.kt @@ -3,7 +3,7 @@ package org.jetbrains.exposed.dao.id import org.jetbrains.exposed.sql.Column /** Class representing a mapping of each composite primary key column to its stored identity value. */ -class CompositeID private constructor() : Comparable { +class CompositeID private constructor() { internal val values: MutableMap, Any?> = HashMap() @Suppress("UNCHECKED_CAST") @@ -50,22 +50,6 @@ class CompositeID private constructor() : Comparable { return values == other.values } - override fun compareTo(other: CompositeID): Int { - val compareSize = compareValues(other.values.size, values.size) - if (compareSize != 0) return compareSize - - values.entries.forEach { (column, idValue) -> - if (!other.values.containsKey(column)) return -1 - require(idValue is Comparable<*>) { "This stored identity value must implement Comparable" } - val otherValue = other.values[column] - require(otherValue is Comparable<*>) { "This stored identity value must implement Comparable" } - compareValues(idValue, otherValue).let { - if (it != 0) return it - } - } - return 0 - } - companion object { operator fun invoke(body: (CompositeID) -> Unit): CompositeID { return CompositeID().apply(body).also { diff --git a/exposed-core/src/main/kotlin/org/jetbrains/exposed/dao/id/EntityID.kt b/exposed-core/src/main/kotlin/org/jetbrains/exposed/dao/id/EntityID.kt index 49761a2e86..81669fc1fb 100644 --- a/exposed-core/src/main/kotlin/org/jetbrains/exposed/dao/id/EntityID.kt +++ b/exposed-core/src/main/kotlin/org/jetbrains/exposed/dao/id/EntityID.kt @@ -11,7 +11,7 @@ package org.jetbrains.exposed.dao.id * @sample org.jetbrains.exposed.sql.tests.shared.entities.EntityTestsData.YTable * @sample org.jetbrains.exposed.sql.tests.shared.dml.InsertTests.testInsertWithPredefinedId */ -open class EntityID protected constructor(val table: IdTable, id: T?) : Comparable> { +open class EntityID protected constructor(val table: IdTable, id: T?) { constructor(id: T, table: IdTable) : this(table, id) @Suppress("VariableNaming") @@ -41,10 +41,4 @@ open class EntityID protected constructor(val table: IdTable, id: T? return other._value == _value && other.table == table } - - override fun compareTo(other: EntityID): Int { - require(value is Comparable<*>) { "This stored identity value must implement Comparable" } - require(other.value is Comparable<*>) { "The other stored identity value must implement Comparable" } - return (value as Comparable).compareTo(other.value) - } } diff --git a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Function.kt b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Function.kt index 863bfc23dc..c8e5ccd091 100644 --- a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Function.kt +++ b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Function.kt @@ -167,7 +167,7 @@ class Locate(val expr: Expression, val substring: String) : Func /** * Represents an SQL function that returns the minimum value of [expr] across all non-null input values, or `null` if there are no non-null values. */ -class Min, in S : T?>( +class Min( /** Returns the expression from which the minimum value is obtained. */ val expr: Expression, columnType: IColumnType @@ -182,7 +182,7 @@ class Min, in S : T?>( /** * Represents an SQL function that returns the maximum value of [expr] across all non-null input values, or `null` if there are no non-null values. */ -class Max, in S : T?>( +class Max( /** Returns the expression from which the maximum value is obtained. */ val expr: Expression, columnType: IColumnType diff --git a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/SQLExpressionBuilder.kt b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/SQLExpressionBuilder.kt index 31adcea98d..6a4cbc708f 100644 --- a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/SQLExpressionBuilder.kt +++ b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/SQLExpressionBuilder.kt @@ -66,10 +66,10 @@ fun Expression.locate(substring: String): Locate = Locate(th // General-Purpose Aggregate Functions /** Returns the minimum value of this expression across all non-null input values, or `null` if there are no non-null values. */ -fun , S : T?> ExpressionWithColumnType.min(): Min = Min(this, this.columnType as IColumnType) +fun ExpressionWithColumnType.min(): Min = Min(this, this.columnType as IColumnType) /** Returns the maximum value of this expression across all non-null input values, or `null` if there are no non-null values. */ -fun , S : T?> ExpressionWithColumnType.max(): Max = Max(this, this.columnType as IColumnType) +fun ExpressionWithColumnType.max(): Max = Max(this, this.columnType as IColumnType) /** Returns the average (arithmetic mean) value of this expression across all non-null input values, or `null` if there are no non-null values. */ fun , S : T?> ExpressionWithColumnType.avg(scale: Int = 2): Avg = Avg(this, scale) diff --git a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Table.kt b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Table.kt index 93d0a56f00..bfc5ce10cb 100644 --- a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Table.kt +++ b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Table.kt @@ -1005,15 +1005,11 @@ open class Table(name: String = "") : ColumnSet(), DdlAware { fun Column.autoIncrement(sequence: Sequence): Column = cloneWithAutoInc(sequence).also { replaceColumn(this, it) } - /** - * Make @receiver column an auto-increment column to generate its values in a database. - * **Note:** Only integer and long columns are supported (signed and unsigned types). - * Some databases, like PostgreSQL, support auto-increment via sequences. - * In this case a name should be provided using the [idSeqName] param and Exposed will create a sequence. - * If a sequence already exists in the database just use its name in [idSeqName]. - * - * @param idSeqName an optional parameter to provide a sequence name - */ + @Deprecated( + message = "This function will be removed in future releases.", + replaceWith = ReplaceWith("autoIncrement(idSeqName)"), + level = DeprecationLevel.WARNING + ) fun Column>.autoinc(idSeqName: String? = null): Column> = cloneWithAutoInc(idSeqName).also { replaceColumn(this, it) } @@ -1069,7 +1065,7 @@ open class Table(name: String = "") : ColumnSet(), DdlAware { * @param ref A column from another table which will be used as a "parent". * @sample org.jetbrains.exposed.sql.tests.shared.dml.JoinTests.testJoin04 */ - infix fun , S : T, C : Column> C.references(ref: Column): C = references( + infix fun > C.references(ref: Column): C = references( ref, null, null, @@ -1089,7 +1085,7 @@ open class Table(name: String = "") : ColumnSet(), DdlAware { * @param fkName Optional foreign key constraint name. * @sample org.jetbrains.exposed.sql.tests.sqlite.ForeignKeyConstraintTests.testUpdateAndDeleteRulesReadCorrectlyWhenSpecifiedInChildTable */ - fun , S : T, C : Column> C.references( + fun > C.references( ref: Column, onDelete: ReferenceOption? = null, onUpdate: ReferenceOption? = null, @@ -1147,7 +1143,7 @@ open class Table(name: String = "") : ColumnSet(), DdlAware { * @param fkName Optional foreign key constraint name. * @sample org.jetbrains.exposed.sql.tests.shared.entities.EntityTests.Orders */ - fun > reference( + fun reference( name: String, refColumn: Column, onDelete: ReferenceOption? = null, @@ -1230,7 +1226,7 @@ open class Table(name: String = "") : ColumnSet(), DdlAware { * @param fkName Optional foreign key constraint name. * @sample org.jetbrains.exposed.sql.tests.shared.entities.EntityTests.Posts */ - fun > optReference( + fun optReference( name: String, refColumn: Column, onDelete: ReferenceOption? = null, diff --git a/exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/EntityHook.kt b/exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/EntityHook.kt index 3d6634c56e..7b7ac2c2c3 100644 --- a/exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/EntityHook.kt +++ b/exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/EntityHook.kt @@ -4,7 +4,7 @@ import org.jetbrains.exposed.dao.id.EntityID import org.jetbrains.exposed.sql.Transaction import org.jetbrains.exposed.sql.transactions.TransactionManager import org.jetbrains.exposed.sql.transactions.transactionScope -import java.util.* +import java.util.Deque import java.util.concurrent.ConcurrentLinkedDeque import java.util.concurrent.ConcurrentLinkedQueue diff --git a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/entities/OrderedReferenceTest.kt b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/entities/OrderedReferenceTest.kt index b4e2e352b4..bf5dbd3f5c 100644 --- a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/entities/OrderedReferenceTest.kt +++ b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/entities/OrderedReferenceTest.kt @@ -101,14 +101,14 @@ class OrderedReferenceTest : DatabaseTestsBase() { fun assertRatingsOrdered(current: UserRatingMultiColumn, prev: UserRatingMultiColumn) { assertTrue(current.value <= prev.value) if (current.value == prev.value) { - assertTrue(current.id <= prev.id) + assertTrue(current.id.value <= prev.id.value) } } fun assertNullableRatingsOrdered(current: UserNullableRatingMultiColumn, prev: UserNullableRatingMultiColumn) { assertTrue(current.value <= prev.value) if (current.value == prev.value) { - assertTrue(current.id <= prev.id) + assertTrue(current.id.value <= prev.id.value) } } @@ -140,7 +140,7 @@ class OrderedReferenceTest : DatabaseTestsBase() { fun assertRatingsOrdered(current: UserRatingChainedColumn, prev: UserRatingChainedColumn) { assertTrue(current.value <= prev.value) if (current.value == prev.value) { - assertTrue(current.id <= prev.id) + assertTrue(current.id.value <= prev.id.value) } }