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 1a181596de..a2819a7be2 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 @@ -1,10 +1,22 @@ package org.jetbrains.exposed.dao.id +/** + * Class representing a wrapper for a stored identity value of type [T]. + * + * The class constructor could be useful, for example, if needing to manually provide an identity value to a column + * default function or when manually inserting into identity columns using any DSL insert functions. + * + * @param table The [IdTable] that stores the identity value. + * @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> { constructor(id: T, table: IdTable) : this(table, id) @Suppress("VariableNaming") var _value: Any? = id + + /** The identity value of type [T] wrapped by this [EntityID] instance. */ val value: T get() { if (_value == null) { invokeOnNoValue() @@ -15,6 +27,7 @@ open class EntityID> protected constructor(val table: IdTable< return _value!! as T } + /** Performs steps when the internal [_value] is accessed without first being initialized. */ protected open fun invokeOnNoValue() {} override fun toString() = value.toString() diff --git a/exposed-core/src/main/kotlin/org/jetbrains/exposed/dao/id/IdTable.kt b/exposed-core/src/main/kotlin/org/jetbrains/exposed/dao/id/IdTable.kt index 6cc93422c0..ea32c70065 100644 --- a/exposed-core/src/main/kotlin/org/jetbrains/exposed/dao/id/IdTable.kt +++ b/exposed-core/src/main/kotlin/org/jetbrains/exposed/dao/id/IdTable.kt @@ -4,10 +4,13 @@ import org.jetbrains.exposed.sql.Column import org.jetbrains.exposed.sql.Table import java.util.* +/** Base class representing a producer of [EntityID] instances. */ interface EntityIDFactory { + /** Returns a new [EntityID] that holds a [value] of type [T], for the specified [table]. */ fun > createEntityID(value: T, table: IdTable): EntityID } +/** Class responsible for locating and providing the appropriate functions to produce [EntityID] instances. */ object EntityIDFunctionProvider { private val factory: EntityIDFactory init { @@ -19,51 +22,55 @@ object EntityIDFunctionProvider { } } + /** Returns a new [EntityID] that holds a [value] of type [T], for the specified [table]. */ fun > createEntityID(value: T, table: IdTable) = factory.createEntityID(value, table) } /** - * Base class for an identity table which could be referenced from another tables. + * Base class for an identity table, which could be referenced from other tables. * - * @param name table name, by default name will be resolved from a class name with "Table" suffix removed (if present) + * @param name Table name. By default, this will be resolved from any class name with a "Table" suffix removed (if present). */ abstract class IdTable>(name: String = "") : Table(name) { + /** The identity column of this [IdTable], for storing values of type [T] wrapped as [EntityID] instances. */ abstract val id: Column> } /** - * Identity table with autoincrement integer primary key + * Identity table with a primary key consisting of an auto-incrementing `Int` value. * - * @param name table name, by default name will be resolved from a class name with "Table" suffix removed (if present) - * @param columnName name for a primary key, "id" by default + * @param name Table name. By default, this will be resolved from any class name with a "Table" suffix removed (if present). + * @param columnName Name for the primary key column. By default, "id" is used. */ open class IntIdTable(name: String = "", columnName: String = "id") : IdTable(name) { + /** The identity column of this [IntIdTable], for storing 4-byte integers wrapped as [EntityID] instances. */ final override val id: Column> = integer(columnName).autoIncrement().entityId() final override val primaryKey = PrimaryKey(id) } /** - * Identity table with autoincrement long primary key + * Identity table with a primary key consisting of an auto-incrementing `Long` value. * - * @param name table name, by default name will be resolved from a class name with "Table" suffix removed (if present) - * @param columnName name for a primary key, "id" by default + * @param name Table name. By default, this will be resolved from any class name with a "Table" suffix removed (if present). + * @param columnName Name for the primary key column. By default, "id" is used. */ open class LongIdTable(name: String = "", columnName: String = "id") : IdTable(name) { + /** The identity column of this [LongIdTable], for storing 8-byte integers wrapped as [EntityID] instances. */ final override val id: Column> = long(columnName).autoIncrement().entityId() final override val primaryKey = PrimaryKey(id) } /** - * Identity table with [UUID] primary key. + * Identity table with a primary key consisting of an auto-generating [UUID] value. * - * [UUID] column type depends on a database. + * **Note** The specific UUID column type used depends on the database. + * The stored identity value will be auto-generated on the client side just before insertion of a new row. * - * Id value will be generated on a client side just before an insert of a new row. - * - * @param name table name, by default name will be resolved from a class name with "Table" suffix removed (if present) - * @param columnName name for a primary key, "id" by default + * @param name Table name. By default, this will be resolved from any class name with a "Table" suffix removed (if present). + * @param columnName Name for the primary key column. By default, "id" is used. */ open class UUIDTable(name: String = "", columnName: String = "id") : IdTable(name) { + /** The identity column of this [UUIDTable], for storing UUIDs wrapped as [EntityID] instances. */ final override val id: Column> = uuid(columnName).autoGenerate().entityId() final override val primaryKey = PrimaryKey(id) } diff --git a/exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/DaoEntityID.kt b/exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/DaoEntityID.kt index 42e677017b..78f85dfe4c 100644 --- a/exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/DaoEntityID.kt +++ b/exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/DaoEntityID.kt @@ -4,6 +4,10 @@ import org.jetbrains.exposed.dao.id.EntityID import org.jetbrains.exposed.dao.id.IdTable import org.jetbrains.exposed.sql.transactions.TransactionManager +/** + * Class representing a wrapper for a stored identity value of type [T], which is managed and cached + * by an [EntityClass] using a data access object pattern. + */ class DaoEntityID>(id: T?, table: IdTable) : EntityID(table, id) { override fun invokeOnNoValue() { TransactionManager.current().entityCache.flushInserts(table) diff --git a/exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/DaoEntityIDFactory.kt b/exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/DaoEntityIDFactory.kt index 6ca4d64b4d..1b3c6ecb67 100644 --- a/exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/DaoEntityIDFactory.kt +++ b/exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/DaoEntityIDFactory.kt @@ -4,6 +4,10 @@ import org.jetbrains.exposed.dao.id.EntityID import org.jetbrains.exposed.dao.id.EntityIDFactory import org.jetbrains.exposed.dao.id.IdTable +/** + * Class representing a producer of [EntityID] instances, which are managed and cached by their respective + * [EntityClass] instances using a data access object pattern. + */ class DaoEntityIDFactory : EntityIDFactory { override fun > createEntityID(value: T, table: IdTable): EntityID { return DaoEntityID(value, table) diff --git a/exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/IntEntity.kt b/exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/IntEntity.kt index ba1524a179..5cf7e12010 100644 --- a/exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/IntEntity.kt +++ b/exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/IntEntity.kt @@ -3,11 +3,26 @@ package org.jetbrains.exposed.dao import org.jetbrains.exposed.dao.id.EntityID import org.jetbrains.exposed.dao.id.IdTable -@Suppress("UnnecessaryAbstractClass") +/** Base class for an [Entity] instance identified by an [id] comprised of a wrapped `Int` value. */ abstract class IntEntity(id: EntityID) : Entity(id) -@Suppress("UnnecessaryAbstractClass") -abstract class IntEntityClass constructor( +/** + * Base class representing the [EntityClass] that manages [IntEntity] instances and + * maintains their relation to the provided [table]. + * + * @param [table] The [IdTable] object that stores rows mapped to entities of this class. + * @param [entityType] The expected [IntEntity] type. This can be left `null` if it is the class of type + * argument [E] provided to this [IntEntityClass] instance. If this `IntEntityClass` is defined as a companion + * object of a custom `IntEntity` class, the parameter will be set to this immediately enclosing class by default. + * @sample org.jetbrains.exposed.sql.tests.shared.DDLTests.testDropTableFlushesCache + * @param [entityCtor] The function invoked to instantiate an [IntEntity] using a provided [EntityID] value. + * If a reference to a specific constructor or a custom function is not passed as an argument, reflection will + * be used to determine the primary constructor of the associated entity class on first access. If this `IntEntityClass` + * is defined as a companion object of a custom `IntEntity` class, the constructor will be set to that of the + * immediately enclosing class by default. + * @sample org.jetbrains.exposed.sql.tests.shared.entities.EntityTests.testExplicitEntityConstructor + */ +abstract class IntEntityClass( table: IdTable, entityType: Class? = null, entityCtor: ((EntityID) -> E)? = null diff --git a/exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/LongEntity.kt b/exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/LongEntity.kt index 94d0388ea4..1c447cf809 100644 --- a/exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/LongEntity.kt +++ b/exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/LongEntity.kt @@ -3,10 +3,25 @@ package org.jetbrains.exposed.dao import org.jetbrains.exposed.dao.id.EntityID import org.jetbrains.exposed.dao.id.IdTable -@Suppress("UnnecessaryAbstractClass") +/** Base class for an [Entity] instance identified by an [id] comprised of a wrapped `Long` value. */ abstract class LongEntity(id: EntityID) : Entity(id) -@Suppress("UnnecessaryAbstractClass") +/** + * Base class representing the [EntityClass] that manages [LongEntity] instances and + * maintains their relation to the provided [table]. + * + * @param [table] The [IdTable] object that stores rows mapped to entities of this class. + * @param [entityType] The expected [LongEntity] type. This can be left `null` if it is the class of type + * argument [E] provided to this [LongEntityClass] instance. If this `LongEntityClass` is defined as a companion + * object of a custom `LongEntity` class, the parameter will be set to this immediately enclosing class by default. + * @sample org.jetbrains.exposed.sql.tests.shared.DDLTests.testDropTableFlushesCache + * @param [entityCtor] The function invoked to instantiate a [LongEntity] using a provided [EntityID] value. + * If a reference to a specific constructor or a custom function is not passed as an argument, reflection will + * be used to determine the primary constructor of the associated entity class on first access. If this `LongEntityClass` + * is defined as a companion object of a custom `LongEntity` class, the constructor will be set to that of the + * immediately enclosing class by default. + * @sample org.jetbrains.exposed.sql.tests.shared.entities.EntityTests.testExplicitEntityConstructor + */ abstract class LongEntityClass( table: IdTable, entityType: Class? = null, diff --git a/exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/UUIDEntity.kt b/exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/UUIDEntity.kt index 4d4696f49b..ff41de8137 100644 --- a/exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/UUIDEntity.kt +++ b/exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/UUIDEntity.kt @@ -4,10 +4,25 @@ import org.jetbrains.exposed.dao.id.EntityID import org.jetbrains.exposed.dao.id.IdTable import java.util.* -@Suppress("UnnecessaryAbstractClass") +/** Base class for an [Entity] instance identified by an [id] comprised of a wrapped `UUID` value. */ abstract class UUIDEntity(id: EntityID) : Entity(id) -@Suppress("UnnecessaryAbstractClass") +/** + * Base class representing the [EntityClass] that manages [UUIDEntity] instances and + * maintains their relation to the provided [table]. + * + * @param [table] The [IdTable] object that stores rows mapped to entities of this class. + * @param [entityType] The expected [UUIDEntity] type. This can be left `null` if it is the class of type + * argument [E] provided to this [UUIDEntityClass] instance. If this `UUIDEntityClass` is defined as a companion + * object of a custom `UUIDEntity` class, the parameter will be set to this immediately enclosing class by default. + * @sample org.jetbrains.exposed.sql.tests.shared.DDLTests.testDropTableFlushesCache + * @param [entityCtor] The function invoked to instantiate a [UUIDEntity] using a provided [EntityID] value. + * If a reference to a specific constructor or a custom function is not passed as an argument, reflection will + * be used to determine the primary constructor of the associated entity class on first access. If this `UUIDEntityClass` + * is defined as a companion object of a custom `UUIDEntity` class, the constructor will be set to that of the + * immediately enclosing class by default. + * @sample org.jetbrains.exposed.sql.tests.shared.entities.EntityTests.testExplicitEntityConstructor + */ abstract class UUIDEntityClass( table: IdTable, entityType: Class? = null, diff --git a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/entities/EntityTests.kt b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/entities/EntityTests.kt index f3b23e1359..e67fc89fda 100644 --- a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/entities/EntityTests.kt +++ b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/entities/EntityTests.kt @@ -1446,7 +1446,7 @@ class EntityTests : DatabaseTestsBase() { } @Test - fun `test explicit entity constructor`() { + fun testExplicitEntityConstructor() { var createBoardCalled = false fun createBoard(id: EntityID): Board { createBoardCalled = true