Adding the feature of defining the primarykey constraint name (#725)

Minor code improvements
This commit is contained in:
Tapac
2019-12-25 02:12:57 +03:00
parent 391a8bf659
commit 9142e64d7d
3 changed files with 36 additions and 46 deletions

View File

@@ -39,7 +39,8 @@ abstract class IdTable<T:Comparable<T>>(name: String = ""): Table(name) {
* @param columnName name for a primary key, "id" by default
*/
open class IntIdTable(name: String = "", columnName: String = "id") : IdTable<Int>(name) {
override val id: Column<EntityID<Int>> = integer(columnName).autoIncrement().primaryKey().entityId()
override val id: Column<EntityID<Int>> = integer(columnName).autoIncrement().entityId()
override val primaryKey = PrimaryKey(id)
}
/**
@@ -49,7 +50,8 @@ open class IntIdTable(name: String = "", columnName: String = "id") : IdTable<In
* @param columnName name for a primary key, "id" by default
*/
open class LongIdTable(name: String = "", columnName: String = "id") : IdTable<Long>(name) {
override val id: Column<EntityID<Long>> = long(columnName).autoIncrement().primaryKey().entityId()
override val id: Column<EntityID<Long>> = long(columnName).autoIncrement().entityId()
override val primaryKey = PrimaryKey(id)
}
/**
@@ -63,7 +65,8 @@ open class LongIdTable(name: String = "", columnName: String = "id") : IdTable<L
* @param columnName name for a primary key, "id" by default
*/
open class UUIDTable(name: String = "", columnName: String = "id") : IdTable<UUID>(name) {
override val id: Column<EntityID<UUID>> = uuid(columnName).primaryKey()
override val id: Column<EntityID<UUID>> = uuid(columnName)
.autoGenerate()
.entityId()
override val primaryKey = PrimaryKey(id)
}

View File

@@ -37,9 +37,9 @@ class Column<T>(val table: Table, val name: String, override val columnType: ICo
override fun createStatement(): List<String> {
val alterTablePrefix = "ALTER TABLE ${TransactionManager.current().identity(table)} ADD"
val isLastColumnInPK = table.primaryKey.columns.lastOrNull() == this
val isLastColumnInPK = table.primaryKey?.columns?.last() == this
val columnDefinition = when {
isOneColumnPK() && table.isCustomPKNameDefined && isLastColumnInPK && currentDialect !is H2Dialect -> descriptionDdl() + ", ADD ${table.primaryKeyConstraint()}"
isOneColumnPK() && table.isCustomPKNameDefined() && isLastColumnInPK && currentDialect !is H2Dialect -> descriptionDdl() + ", ADD ${table.primaryKeyConstraint()}"
isOneColumnPK() && (currentDialect is H2Dialect || currentDialect is SQLiteDialect) -> descriptionDdl().removeSuffix(" PRIMARY KEY")
!isOneColumnPK() && isLastColumnInPK && currentDialect !is H2Dialect -> descriptionDdl() + ", ADD ${table.primaryKeyConstraint()}"
else -> descriptionDdl()
@@ -55,19 +55,19 @@ class Column<T>(val table: Table, val name: String, override val columnType: ICo
override fun dropStatement() = listOf(TransactionManager.current().let {"ALTER TABLE ${it.identity(table)} DROP COLUMN ${it.identity(this)}" })
internal fun isOneColumnPK() = table.primaryKey.columns.singleOrNull() == this
internal fun isOneColumnPK() = table.primaryKey?.columns?.singleOrNull() == this
fun descriptionDdl(): String = buildString {
val tr = TransactionManager.current()
append(tr.identity(this@Column))
append(" ")
val isPKColumn = table.primaryKey.columns.contains(this@Column)
val isPKColumn = table.primaryKey?.columns?.contains(this@Column) == true
val colType = columnType
val isSQLiteAutoIncColumn = currentDialect is SQLiteDialect && colType.isAutoInc
when {
!isPKColumn && isSQLiteAutoIncColumn -> tr.throwUnsupportedException("Auto-increment could be applied only to primary key column")
isSQLiteAutoIncColumn && !isOneColumnPK() && table.primaryKey.columns.isNotEmpty() -> append(currentDialect.dataTypeProvider.integerType())
isSQLiteAutoIncColumn && !isOneColumnPK() && table.primaryKey != null -> append(currentDialect.dataTypeProvider.integerType())
else -> append(colType.sqlType())
}
@@ -92,7 +92,7 @@ class Column<T>(val table: Table, val name: String, override val columnType: ICo
append(" NOT NULL")
}
if (!table.isCustomPKNameDefined && isOneColumnPK() && !isSQLiteAutoIncColumn) {
if (!table.isCustomPKNameDefined() && isOneColumnPK() && !isSQLiteAutoIncColumn) {
append(" PRIMARY KEY")
}
}

View File

@@ -236,37 +236,27 @@ open class Table(name: String = ""): ColumnSet(), DdlAware {
return newColumn
}
var isCustomPKNameDefined = false
internal fun isCustomPKNameDefined() : Boolean = primaryKey?.let { it.name != "pk_$tableName" } == true
/**
* The primary key class.
*/
inner class PrimaryKey {
val columns: List<Column<*>>
val name: String
/**
* Define the columns in the primary key of the current table. You can also provide the name of primary key constraint
* by passing the "name" argument. Example : PrimaryKey(id1, id2, id3..., name = "CustomPKName")
*
* @param columns list of columns in the primary key
* @param name the primary key constraint name, by default it will be resolved from the table name with "pk_" prefix
*/
constructor(vararg columns: Column<*>, name: String = "") {
this.columns = columns.toList()
* Define the columns in the primary key of the current table. You can also provide the name of primary key constraint
* by passing the "name" argument. Example : PrimaryKey(id1, id2, id3..., name = "CustomPKName")
*
* @param columns list of columns in the primary key
* @param name the primary key constraint name, by default it will be resolved from the table name with "pk_" prefix
*/
inner class PrimaryKey(
vararg val columns: Column<*>,
val name: String = "pk_$tableName"
) {
init {
checkMultipleDeclaration()
for (column in columns) {
column.markPrimaryKey()
}
if (name.isEmpty()) {
this.name = "pk_${tableName}"
} else {
this.name = name
isCustomPKNameDefined = true
}
}
/**
@@ -274,10 +264,7 @@ open class Table(name: String = ""): ColumnSet(), DdlAware {
*
* This constructor must be removed when [primaryKey] method is no longer supported.
*/
internal constructor(columns: List<Column<*>>) {
this.columns = columns
this.name = "pk_${tableName}"
}
internal constructor(columns: List<Column<*>>) : this(*columns.toTypedArray())
/**
* Mark @receiver column as an element of primary key.
@@ -309,14 +296,17 @@ open class Table(name: String = ""): ColumnSet(), DdlAware {
}
/**
* Represents the primary key of the table. It is initialized with existing keys.
* Represents the primary key of the table if present.
* It is initialized with existing keys defined by [Column.primaryKey] function for a backward compatibility,
* but you have to define it explicitly by overriding that val instead.
*/
open val primaryKey by lazy { PrimaryKey(getPrimaryKeyColumns()) }
open val primaryKey: PrimaryKey? by lazy { getPrimaryKeyColumns()?.let { PrimaryKey(it) } }
/**
* Returns the list of columns in the primary key.
* Returns the list of columns in the primary key if present.
*/
private fun getPrimaryKeyColumns(): List<Column<*>> = columns.filter { it.indexInPK != null }.sortedWith(compareBy({ !it.columnType.isAutoInc }, { it.indexInPK }))
private fun getPrimaryKeyColumns(): List<Column<*>>?
= columns.filter { it.indexInPK != null }.sortedWith(compareBy({ !it.columnType.isAutoInc }, { it.indexInPK })).takeIf { it.isNotEmpty() }
/**
* Mark @receiver column as primary key.
@@ -329,7 +319,7 @@ open class Table(name: String = ""): ColumnSet(), DdlAware {
*/
@Deprecated("This function will be no longer supported. Please use the new declarations of primary key by " +
"overriding the primaryKey property in the current table. " +
"Example : object TableName : Table() { override val primaryKey = PrimaryKey(columns, name = \"CustomPKConstraintName\") }")
"Example : object TableName : Table() { override val primaryKey = PrimaryKey(column1, column2, name = \"CustomPKConstraintName\") }")
fun <T> Column<T>.primaryKey(indx: Int? = null): Column<T> {
if (indx != null && table.columns.any { it.indexInPK == indx } ) throw IllegalArgumentException("Table $tableName already contains PK at $indx")
indexInPK = indx ?: table.columns.count { it.indexInPK != null } + 1
@@ -716,7 +706,7 @@ open class Table(name: String = ""): ColumnSet(), DdlAware {
append(TransactionManager.current().identity(this@Table))
if (columns.any()) {
append(columns.joinToString(prefix = " (") { it.descriptionDdl() })
if (isCustomPKNameDefined || columns.none { it.isOneColumnPK() }) {
if (isCustomPKNameDefined() || columns.none { it.isOneColumnPK() }) {
primaryKeyConstraint()?.let {
append(", $it")
}
@@ -749,17 +739,14 @@ open class Table(name: String = ""): ColumnSet(), DdlAware {
}
internal fun primaryKeyConstraint(): String? {
val pkey = primaryKey.columns
if (pkey.isNotEmpty()) {
return primaryKey?.let { primaryKey ->
val tr = TransactionManager.current()
val constraint = tr.db.identifierManager.cutIfNecessaryAndQuote(primaryKey.name)
return pkey.joinToString(
return primaryKey.columns.joinToString(
prefix = "CONSTRAINT $constraint PRIMARY KEY (", postfix = ")") {
tr.identity(it)
}
}
return null
}
override fun dropStatement() : List<String> {