Skip to content

Commit

Permalink
SQLite table ignoring primaryKey override JetBrains#1258
Browse files Browse the repository at this point in the history
  • Loading branch information
Tapac authored and SchweinchenFuntik committed Oct 23, 2021
1 parent ddc77c3 commit a82615c
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 18 deletions.
43 changes: 28 additions & 15 deletions exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Column.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,25 @@ class Column<T>(

fun nameInDatabaseCase(): String = name.inProperCase()

private val isLastColumnInPK: Boolean get() = table.primaryKey?.columns?.last() == this

internal val isPrimaryConstraintWillBeDefined: Boolean get() = when {
currentDialect is SQLiteDialect && columnType.isAutoInc -> false
table.isCustomPKNameDefined() -> isLastColumnInPK
isOneColumnPK() -> false
else -> isLastColumnInPK
}

override fun createStatement(): List<String> {
val alterTablePrefix = "ALTER TABLE ${TransactionManager.current().identity(table)} ADD"
val isLastColumnInPK = table.primaryKey?.columns?.last() == this
val isH2withCustomPKConstraint = currentDialect is H2Dialect && isLastColumnInPK
val columnDefinition = when {
isOneColumnPK() && table.isCustomPKNameDefined() && isLastColumnInPK && currentDialect !is H2Dialect -> descriptionDdl(false) + ", ADD ${table.primaryKeyConstraint()}"
isOneColumnPK() && (currentDialect is H2Dialect || currentDialect is SQLiteDialect) -> descriptionDdl(false).removeSuffix(" PRIMARY KEY")
!isOneColumnPK() && isLastColumnInPK && currentDialect !is H2Dialect -> descriptionDdl(false) + ", ADD ${table.primaryKeyConstraint()}"
isPrimaryConstraintWillBeDefined && isLastColumnInPK && !isH2withCustomPKConstraint -> descriptionDdl(false) + ", ADD ${table.primaryKeyConstraint()}"
isH2withCustomPKConstraint -> descriptionDdl(true)
else -> descriptionDdl(false)
}

val addConstr = if (isLastColumnInPK && currentDialect is H2Dialect) "$alterTablePrefix ${table.primaryKeyConstraint()}" else null
val addConstr = if (isH2withCustomPKConstraint) "$alterTablePrefix ${table.primaryKeyConstraint()}" else null
return listOfNotNull("$alterTablePrefix $columnDefinition", addConstr)
}

Expand All @@ -71,16 +79,21 @@ class Column<T>(
/** Returns the SQL representation of this column. */
fun descriptionDdl(modify: Boolean = false): String = buildString {
val tr = TransactionManager.current()
append(tr.identity(this@Column))
val column = this@Column
append(tr.identity(column))
append(" ")
val isPKColumn = table.primaryKey?.columns?.contains(this@Column) == true
val colType = columnType
val isSQLiteAutoIncColumn = currentDialect is SQLiteDialect && colType.isAutoInc
val isPKColumn = table.primaryKey?.columns?.contains(column) == true
val isSQLiteAutoIncColumn = currentDialect is SQLiteDialect && columnType.isAutoInc

when {
!isPKColumn && isSQLiteAutoIncColumn -> tr.throwUnsupportedException("Auto-increment could be applied only to primary key column")
isSQLiteAutoIncColumn && (!isOneColumnPK() || table.isCustomPKNameDefined()) && table.primaryKey != null -> append(currentDialect.dataTypeProvider.integerType())
else -> append(colType.sqlType())
isSQLiteAutoIncColumn && !isOneColumnPK() -> tr.throwUnsupportedException("Auto-increment could be applied only to a single column primary key")
isSQLiteAutoIncColumn && table.isCustomPKNameDefined() -> {
val rawType = columnType.sqlType().substringBefore("PRIMARY KEY")
val constraintPart = table.primaryKeyConstraint()!!.substringBefore("(")
append("$rawType $constraintPart AUTOINCREMENT")
}
else -> append(columnType.sqlType())
}

val defaultValue = dbDefaultValue
Expand All @@ -89,7 +102,7 @@ class Column<T>(
if (!currentDialect.isAllowedAsColumnDefault(defaultValue)) {
val clientDefault = when {
defaultValueFun != null -> " Expression will be evaluated on the client."
!colType.nullable -> " Column will be created with NULL marker."
!columnType.nullable -> " Column will be created with NULL marker."
else -> ""
}
exposedLogger.error("${currentDialect.name} ${tr.db.version} doesn't support expression '$expressionSQL' as default value.$clientDefault")
Expand All @@ -98,13 +111,13 @@ class Column<T>(
}
}

if (colType.nullable || (defaultValue != null && defaultValueFun == null && !currentDialect.isAllowedAsColumnDefault(defaultValue))) {
if (columnType.nullable || (defaultValue != null && defaultValueFun == null && !currentDialect.isAllowedAsColumnDefault(defaultValue))) {
append(" NULL")
} else if (!isPKColumn || (currentDialect is SQLiteDialect && !colType.isAutoInc)) {
} else if (!isPKColumn || (currentDialect is SQLiteDialect && !isSQLiteAutoIncColumn)) {
append(" NOT NULL")
}

if (!modify && !table.isCustomPKNameDefined() && isOneColumnPK() && !isSQLiteAutoIncColumn) {
if (!modify && isOneColumnPK() && !isPrimaryConstraintWillBeDefined && !isSQLiteAutoIncColumn) {
append(" PRIMARY KEY")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1057,7 +1057,7 @@ open class Table(name: String = "") : ColumnSet(), DdlAware {
if (columns.isNotEmpty()) {
columns.joinTo(this, prefix = " (") { it.descriptionDdl(false) }

if (isCustomPKNameDefined() || columns.none { it.isOneColumnPK() }) {
if (columns.any { it.isPrimaryConstraintWillBeDefined }) {
primaryKeyConstraint()?.let { append(", $it") }
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import org.jetbrains.exposed.dao.id.EntityID
import org.jetbrains.exposed.dao.id.IdTable
import org.jetbrains.exposed.dao.id.IntIdTable
import org.jetbrains.exposed.dao.id.LongIdTable
import org.jetbrains.exposed.exceptions.UnsupportedByDialectException
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.statements.api.ExposedBlob
import org.jetbrains.exposed.sql.tests.DatabaseTestsBase
Expand Down Expand Up @@ -176,7 +177,7 @@ class DDLTests : DatabaseTestsBase() {
override val primaryKey = PrimaryKey(bar, id)
}

withTables(Foo) {
withTables(excludeSettings = listOf(TestDB.SQLITE), Foo) {
Foo.insert {
it[Foo.bar] = 1
}
Expand All @@ -189,6 +190,12 @@ class DDLTests : DatabaseTestsBase() {
assertEquals(1, result[0].second)
assertEquals(2, result[1].second)
}

withDb(TestDB.SQLITE) {
expectException<UnsupportedByDialectException> {
SchemaUtils.create(Foo)
}
}
}

@Test fun testIndices01() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import org.jetbrains.exposed.sql.tests.inProperCase
import org.jetbrains.exposed.sql.tests.shared.assertEqualCollections
import org.jetbrains.exposed.sql.tests.shared.assertEquals
import org.jetbrains.exposed.sql.transactions.TransactionManager
import org.jetbrains.exposed.sql.vendors.SQLiteDialect
import org.jetbrains.exposed.sql.vendors.currentDialect
import org.junit.Test
import java.util.*
Expand Down Expand Up @@ -144,7 +145,14 @@ class CreateTableTests : DatabaseTestsBase() {
val id1ProperName = Book.id.name.inProperCase()
val ddlId1 = Book.id.ddl

assertEquals("ALTER TABLE $tableProperName ADD ${Book.id.descriptionDdl(false)}, ADD CONSTRAINT $pkConstraintName PRIMARY KEY ($id1ProperName)", ddlId1.first())
if (currentDialectTest !is SQLiteDialect) {
assertEquals(
"ALTER TABLE $tableProperName ADD ${Book.id.descriptionDdl(false)}, ADD CONSTRAINT $pkConstraintName PRIMARY KEY ($id1ProperName)",
ddlId1.first()
)
} else {
assertEquals("ALTER TABLE $tableProperName ADD ${Book.id.descriptionDdl(false)}", ddlId1.first())
}
}
}

Expand Down

0 comments on commit a82615c

Please sign in to comment.