diff --git a/exposed-core/api/exposed-core.api b/exposed-core/api/exposed-core.api
index b22cf9689b..227d22c3c0 100644
--- a/exposed-core/api/exposed-core.api
+++ b/exposed-core/api/exposed-core.api
@@ -1814,6 +1814,7 @@ public final class org/jetbrains/exposed/sql/SchemaUtils {
public static synthetic fun dropSchema$default (Lorg/jetbrains/exposed/sql/SchemaUtils;[Lorg/jetbrains/exposed/sql/Schema;ZZILjava/lang/Object;)V
public final fun dropSequence ([Lorg/jetbrains/exposed/sql/Sequence;Z)V
public static synthetic fun dropSequence$default (Lorg/jetbrains/exposed/sql/SchemaUtils;[Lorg/jetbrains/exposed/sql/Sequence;ZILjava/lang/Object;)V
+ public final fun listDatabases ()Ljava/util/List;
public final fun setSchema (Lorg/jetbrains/exposed/sql/Schema;Z)V
public static synthetic fun setSchema$default (Lorg/jetbrains/exposed/sql/SchemaUtils;Lorg/jetbrains/exposed/sql/Schema;ZILjava/lang/Object;)V
public final fun sortTablesByReferences (Ljava/lang/Iterable;)Ljava/util/List;
@@ -2889,7 +2890,9 @@ public final class org/jetbrains/exposed/sql/statements/StatementType : java/lan
public static final field GRANT Lorg/jetbrains/exposed/sql/statements/StatementType;
public static final field INSERT Lorg/jetbrains/exposed/sql/statements/StatementType;
public static final field OTHER Lorg/jetbrains/exposed/sql/statements/StatementType;
+ public static final field PRAGMA Lorg/jetbrains/exposed/sql/statements/StatementType;
public static final field SELECT Lorg/jetbrains/exposed/sql/statements/StatementType;
+ public static final field SHOW Lorg/jetbrains/exposed/sql/statements/StatementType;
public static final field TRUNCATE Lorg/jetbrains/exposed/sql/statements/StatementType;
public static final field UPDATE Lorg/jetbrains/exposed/sql/statements/StatementType;
public final fun getGroup ()Lorg/jetbrains/exposed/sql/statements/StatementGroup;
@@ -3245,6 +3248,7 @@ public abstract interface class org/jetbrains/exposed/sql/vendors/DatabaseDialec
public abstract fun getSupportsTernaryAffectedRowValues ()Z
public abstract fun getSupportsWindowFrameGroupsMode ()Z
public abstract fun isAllowedAsColumnDefault (Lorg/jetbrains/exposed/sql/Expression;)Z
+ public abstract fun listDatabases ()Ljava/lang/String;
public abstract fun modifyColumn (Lorg/jetbrains/exposed/sql/Column;Lorg/jetbrains/exposed/sql/ColumnDiff;)Ljava/util/List;
public abstract fun resetCaches ()V
public abstract fun resetSchemaCaches ()V
@@ -3284,6 +3288,7 @@ public final class org/jetbrains/exposed/sql/vendors/DatabaseDialect$DefaultImpl
public static fun getSupportsTernaryAffectedRowValues (Lorg/jetbrains/exposed/sql/vendors/DatabaseDialect;)Z
public static fun getSupportsWindowFrameGroupsMode (Lorg/jetbrains/exposed/sql/vendors/DatabaseDialect;)Z
public static fun isAllowedAsColumnDefault (Lorg/jetbrains/exposed/sql/vendors/DatabaseDialect;Lorg/jetbrains/exposed/sql/Expression;)Z
+ public static fun listDatabases (Lorg/jetbrains/exposed/sql/vendors/DatabaseDialect;)Ljava/lang/String;
public static fun setSchema (Lorg/jetbrains/exposed/sql/vendors/DatabaseDialect;Lorg/jetbrains/exposed/sql/Schema;)Ljava/lang/String;
public static fun tableColumns (Lorg/jetbrains/exposed/sql/vendors/DatabaseDialect;[Lorg/jetbrains/exposed/sql/Table;)Ljava/util/Map;
}
@@ -3458,6 +3463,7 @@ public class org/jetbrains/exposed/sql/vendors/H2Dialect : org/jetbrains/exposed
public fun getSupportsWindowFrameGroupsMode ()Z
public fun isAllowedAsColumnDefault (Lorg/jetbrains/exposed/sql/Expression;)Z
public final fun isSecondVersion ()Z
+ public fun listDatabases ()Ljava/lang/String;
public fun modifyColumn (Lorg/jetbrains/exposed/sql/Column;Lorg/jetbrains/exposed/sql/ColumnDiff;)Ljava/util/List;
public fun toString ()Ljava/lang/String;
}
@@ -3534,6 +3540,7 @@ public class org/jetbrains/exposed/sql/vendors/OracleDialect : org/jetbrains/exp
public fun getSupportsOnlyIdentifiersInGeneratedKeys ()Z
public fun getSupportsOrderByNullsFirstLast ()Z
public fun isAllowedAsColumnDefault (Lorg/jetbrains/exposed/sql/Expression;)Z
+ public fun listDatabases ()Ljava/lang/String;
public fun modifyColumn (Lorg/jetbrains/exposed/sql/Column;Lorg/jetbrains/exposed/sql/ColumnDiff;)Ljava/util/List;
public fun setSchema (Lorg/jetbrains/exposed/sql/Schema;)Ljava/lang/String;
}
@@ -3552,6 +3559,7 @@ public class org/jetbrains/exposed/sql/vendors/PostgreSQLDialect : org/jetbrains
public fun getSupportsOrderByNullsFirstLast ()Z
public fun getSupportsWindowFrameGroupsMode ()Z
public fun isAllowedAsColumnDefault (Lorg/jetbrains/exposed/sql/Expression;)Z
+ public fun listDatabases ()Ljava/lang/String;
public fun modifyColumn (Lorg/jetbrains/exposed/sql/Column;Lorg/jetbrains/exposed/sql/ColumnDiff;)Ljava/util/List;
public fun setSchema (Lorg/jetbrains/exposed/sql/Schema;)Ljava/lang/String;
}
@@ -3617,6 +3625,7 @@ public class org/jetbrains/exposed/sql/vendors/SQLiteDialect : org/jetbrains/exp
public fun getSupportsMultipleGeneratedKeys ()Z
public fun getSupportsWindowFrameGroupsMode ()Z
public fun isAllowedAsColumnDefault (Lorg/jetbrains/exposed/sql/Expression;)Z
+ public fun listDatabases ()Ljava/lang/String;
}
public final class org/jetbrains/exposed/sql/vendors/SQLiteDialect$Companion : org/jetbrains/exposed/sql/vendors/VendorDialect$DialectNameProvider {
@@ -3665,6 +3674,7 @@ public abstract class org/jetbrains/exposed/sql/vendors/VendorDialect : org/jetb
public fun getSupportsTernaryAffectedRowValues ()Z
public fun getSupportsWindowFrameGroupsMode ()Z
public fun isAllowedAsColumnDefault (Lorg/jetbrains/exposed/sql/Expression;)Z
+ public fun listDatabases ()Ljava/lang/String;
public fun modifyColumn (Lorg/jetbrains/exposed/sql/Column;Lorg/jetbrains/exposed/sql/ColumnDiff;)Ljava/util/List;
protected final fun quoteIdentifierWhenWrongCaseOrNecessary (Ljava/lang/String;Lorg/jetbrains/exposed/sql/Transaction;)Ljava/lang/String;
public fun resetCaches ()V
diff --git a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/SchemaUtils.kt b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/SchemaUtils.kt
index d726d2a441..e1670e4245 100644
--- a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/SchemaUtils.kt
+++ b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/SchemaUtils.kt
@@ -91,6 +91,7 @@ object SchemaUtils {
}
fun sortTablesByReferences(tables: Iterable
) = TableDepthGraph(tables).sorted()
+
fun checkCycle(vararg tables: Table) = TableDepthGraph(tables.toList()).hasCycle()
fun createStatements(vararg tables: Table): List {
@@ -122,7 +123,9 @@ object SchemaUtils {
@Deprecated(
"Will be removed in upcoming releases. Please use overloaded version instead",
- ReplaceWith("createFKey(checkNotNull(reference.foreignKey) { \"${"$"}reference does not reference anything\" })"),
+ ReplaceWith(
+ "createFKey(checkNotNull(reference.foreignKey) { \"${"$"}reference does not reference anything\" })"
+ ),
DeprecationLevel.HIDDEN
)
fun createFKey(reference: Column<*>): List {
@@ -135,9 +138,13 @@ object SchemaUtils {
fun createFKey(foreignKey: ForeignKeyConstraint): List = with(foreignKey) {
val allFromColumnsBelongsToTheSameTable = from.all { it.table == fromTable }
- require(allFromColumnsBelongsToTheSameTable) { "not all referencing columns of $foreignKey belong to the same table" }
+ require(
+ allFromColumnsBelongsToTheSameTable
+ ) { "not all referencing columns of $foreignKey belong to the same table" }
val allTargetColumnsBelongToTheSameTable = target.all { it.table == targetTable }
- require(allTargetColumnsBelongToTheSameTable) { "not all referenced columns of $foreignKey belong to the same table" }
+ require(
+ allTargetColumnsBelongToTheSameTable
+ ) { "not all referenced columns of $foreignKey belong to the same table" }
require(from.size == target.size) { "$foreignKey referencing columns are not in accordance with referenced" }
require(deleteRule != null || updateRule != null) { "$foreignKey has no reference constraint actions" }
require(target.toHashSet().size == target.size) { "not all referenced columns of $foreignKey are unique" }
@@ -255,21 +262,25 @@ object SchemaUtils {
if (dbSupportsAlterTableWithAddColumn) {
// create indexes with new columns
- table.indices.filter { index -> index.columns.any { missingTableColumns.contains(it) } }.forEach { statements.addAll(createIndex(it)) }
+ table.indices.filter { index ->
+ index.columns.any {
+ missingTableColumns.contains(it)
+ }
+ }.forEach { statements.addAll(createIndex(it)) }
// sync existing columns
val dataTypeProvider = currentDialect.dataTypeProvider
val redoColumns = existingTableColumns.mapValues { (col, existingCol) ->
- val columnType = col.columnType
- val incorrectNullability = existingCol.nullable != columnType.nullable
- // Exposed doesn't support changing sequences on columns
- val incorrectAutoInc = existingCol.autoIncrement != columnType.isAutoInc && col.autoIncColumnType?.autoincSeq == null
- val incorrectDefaults = existingCol.defaultDbValue != col.dbDefaultValue?.let {
- dataTypeProvider.dbDefaultToString(col, it)
- }
- val incorrectCaseSensitiveName = existingCol.name.inProperCase() != col.nameUnquoted().inProperCase()
- ColumnDiff(incorrectNullability, incorrectAutoInc, incorrectDefaults, incorrectCaseSensitiveName)
- }.filterValues { it.hasDifferences() }
+ val columnType = col.columnType
+ val incorrectNullability = existingCol.nullable != columnType.nullable
+ // Exposed doesn't support changing sequences on columns
+ val incorrectAutoInc = existingCol.autoIncrement != columnType.isAutoInc && col.autoIncColumnType?.autoincSeq == null
+ val incorrectDefaults = existingCol.defaultDbValue != col.dbDefaultValue?.let {
+ dataTypeProvider.dbDefaultToString(col, it)
+ }
+ val incorrectCaseSensitiveName = existingCol.name.inProperCase() != col.nameUnquoted().inProperCase()
+ ColumnDiff(incorrectNullability, incorrectAutoInc, incorrectDefaults, incorrectCaseSensitiveName)
+ }.filterValues { it.hasDifferences() }
redoColumns.flatMapTo(statements) { (col, changedState) -> col.modifyStatements(changedState) }
@@ -352,7 +363,8 @@ object SchemaUtils {
} catch (exception: ExposedSQLException) {
if (currentDialect.requiresAutoCommitOnCreateDrop && !transaction.connection.autoCommit) {
throw IllegalStateException(
- "${currentDialect.name} requires autoCommit to be enabled for CREATE DATABASE", exception
+ "${currentDialect.name} requires autoCommit to be enabled for CREATE DATABASE",
+ exception
)
} else {
throw exception
@@ -360,6 +372,24 @@ object SchemaUtils {
}
}
+ /**
+ * Returns a list of all databases.
+ *
+ * @return A list of strings representing the names of all databases.
+ */
+ fun listDatabases(): List {
+ val transaction = TransactionManager.current()
+ return with(transaction) {
+ exec(currentDialect.listDatabases()) {
+ val result = mutableListOf()
+ while (it.next()) {
+ result.add(it.getString(1).lowercase())
+ }
+ result
+ } ?: emptyList()
+ }
+ }
+
/**
* Drops databases
*
@@ -380,7 +410,8 @@ object SchemaUtils {
} catch (exception: ExposedSQLException) {
if (currentDialect.requiresAutoCommitOnCreateDrop && !transaction.connection.autoCommit) {
throw IllegalStateException(
- "${currentDialect.name} requires autoCommit to be enabled for DROP DATABASE", exception
+ "${currentDialect.name} requires autoCommit to be enabled for DROP DATABASE",
+ exception
)
} else {
throw exception
@@ -424,7 +455,10 @@ object SchemaUtils {
}
val executedStatements = createStatements + alterStatements
logTimeSpent("Checking mapping consistence", withLogs) {
- val modifyTablesStatements = checkMappingConsistence(tables = tables, withLogs).filter { it !in executedStatements }
+ val modifyTablesStatements = checkMappingConsistence(
+ tables = tables,
+ withLogs
+ ).filter { it !in executedStatements }
execStatements(inBatch, modifyTablesStatements)
commit()
}
@@ -446,7 +480,10 @@ object SchemaUtils {
}
val executedStatements = createStatements + alterStatements
val modifyTablesStatements = logTimeSpent("Checking mapping consistence", withLogs) {
- checkMappingConsistence(tables = tablesToAlter.toTypedArray(), withLogs).filter { it !in executedStatements }
+ checkMappingConsistence(
+ tables = tablesToAlter.toTypedArray(),
+ withLogs
+ ).filter { it !in executedStatements }
}
return executedStatements + modifyTablesStatements
}
@@ -483,12 +520,20 @@ object SchemaUtils {
}
val excessiveIndices =
- currentDialect.existingIndices(*tables).flatMap { it.value }.groupBy { Triple(it.table, it.unique, it.columns.joinToString { it.name }) }
+ currentDialect.existingIndices(*tables).flatMap {
+ it.value
+ }.groupBy { Triple(it.table, it.unique, it.columns.joinToString { it.name }) }
.filter { it.value.size > 1 }
if (excessiveIndices.isNotEmpty()) {
exposedLogger.warn("List of excessive indices:")
excessiveIndices.forEach { (triple, indices) ->
- exposedLogger.warn("\t\t\t'${triple.first.tableName}'.'${triple.third}' -> ${indices.joinToString(", ") { it.indexName }}")
+ exposedLogger.warn(
+ "\t\t\t'${triple.first.tableName}'.'${triple.third}' -> ${
+ indices.joinToString(
+ ", "
+ ) { it.indexName }
+ }"
+ )
}
exposedLogger.info("SQL Queries to remove excessive indices:")
excessiveIndices.forEach {
@@ -543,7 +588,9 @@ object SchemaUtils {
nameDiffers.add(mappedIndex)
}
- notMappedIndices.getOrPut(table.nameInDatabaseCase()) { hashSetOf() }.addAll(existingTableIndices.subtract(mappedIndices))
+ notMappedIndices.getOrPut(table.nameInDatabaseCase()) {
+ hashSetOf()
+ }.addAll(existingTableIndices.subtract(mappedIndices))
missingIndices.addAll(mappedIndices.subtract(existingTableIndices))
}
diff --git a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Transaction.kt b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Transaction.kt
index 462bb5068c..35fcb08b4d 100644
--- a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Transaction.kt
+++ b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Transaction.kt
@@ -108,8 +108,7 @@ open class Transaction(
@Language("sql") stmt: String,
args: Iterable> = emptyList(),
explicitStatementType: StatementType? = null
- ) =
- exec(stmt, args, explicitStatementType) { }
+ ) = exec(stmt, args, explicitStatementType) { }
fun exec(
@Language("sql") stmt: String,
@@ -126,7 +125,7 @@ open class Transaction(
return exec(object : Statement(type, emptyList()) {
override fun PreparedStatementApi.executeInternal(transaction: Transaction): T? {
val result = when (type) {
- StatementType.SELECT, StatementType.EXEC -> executeQuery()
+ StatementType.SELECT, StatementType.EXEC, StatementType.SHOW, StatementType.PRAGMA -> executeQuery()
else -> {
executeUpdate()
resultSet
diff --git a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/statements/Statement.kt b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/statements/Statement.kt
index 677cbf1ed8..3a92361eb4 100644
--- a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/statements/Statement.kt
+++ b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/statements/Statement.kt
@@ -126,5 +126,6 @@ enum class StatementGroup {
enum class StatementType(val group: StatementGroup) {
INSERT(StatementGroup.DML), UPDATE(StatementGroup.DML), DELETE(StatementGroup.DML), SELECT(StatementGroup.DML),
CREATE(StatementGroup.DDL), ALTER(StatementGroup.DDL), TRUNCATE(StatementGroup.DDL), DROP(StatementGroup.DDL),
- GRANT(StatementGroup.DDL), EXEC(StatementGroup.DML), OTHER(StatementGroup.DDL)
+ GRANT(StatementGroup.DDL), EXEC(StatementGroup.DML), OTHER(StatementGroup.DDL),
+ SHOW(StatementGroup.DML), PRAGMA(StatementGroup.DML)
}
diff --git a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/Default.kt b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/Default.kt
index d67bb8ed53..80120c60ec 100644
--- a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/Default.kt
+++ b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/Default.kt
@@ -139,6 +139,7 @@ abstract class DataTypeProvider {
} else {
"'$e'"
}
+
e is LiteralOp<*> -> "$e"
e is Function<*> -> "$e"
currentDialect is MysqlDialect -> "$e"
@@ -980,6 +981,8 @@ interface DatabaseDialect {
fun createDatabase(name: String) = "CREATE DATABASE IF NOT EXISTS ${name.inProperCase()}"
+ fun listDatabases(): String = "SHOW DATABASES"
+
fun dropDatabase(name: String) = "DROP DATABASE IF EXISTS ${name.inProperCase()}"
fun setSchema(schema: Schema): String = "SET SCHEMA ${schema.identifier}"
@@ -1221,6 +1224,7 @@ abstract class VendorDialect(
.append(" WHERE ").append(it)
.toString()
}
+
else -> {
exposedLogger.warn("Index creation with a filter condition is not supported in ${currentDialect.name}")
return null
@@ -1282,6 +1286,7 @@ abstract class VendorDialect(
columns = fieldsList, type = index.indexType, filterCondition = maybeFilterCondition
)
}
+
else -> {
"CREATE INDEX $quotedIndexName ON $quotedTableName $fieldsList$maybeFilterCondition"
}
diff --git a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/H2.kt b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/H2.kt
index 50a0796d8e..10b3bf01ff 100644
--- a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/H2.kt
+++ b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/H2.kt
@@ -262,6 +262,8 @@ open class H2Dialect : VendorDialect(dialectName, H2DataTypeProvider, H2Function
override fun createDatabase(name: String) = "CREATE SCHEMA IF NOT EXISTS ${name.inProperCase()}"
+ override fun listDatabases(): String = "SHOW SCHEMAS"
+
override fun modifyColumn(column: Column<*>, columnDiff: ColumnDiff): List =
super.modifyColumn(column, columnDiff).map { it.replace("MODIFY COLUMN", "ALTER COLUMN") }
diff --git a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/OracleDialect.kt b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/OracleDialect.kt
index 90ec7b6f11..d9dac0d97a 100644
--- a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/OracleDialect.kt
+++ b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/OracleDialect.kt
@@ -333,6 +333,8 @@ open class OracleDialect : VendorDialect(dialectName, OracleDataTypeProvider, Or
override fun createDatabase(name: String): String = "CREATE DATABASE ${name.inProperCase()}"
+ override fun listDatabases(): String = error("This operation is not supported by Oracle dialect")
+
override fun dropDatabase(name: String): String = "DROP DATABASE"
override fun setSchema(schema: Schema): String = "ALTER SESSION SET CURRENT_SCHEMA = ${schema.identifier}"
diff --git a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/PostgreSQL.kt b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/PostgreSQL.kt
index 63dc32ab57..5fe5df1574 100644
--- a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/PostgreSQL.kt
+++ b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/PostgreSQL.kt
@@ -324,6 +324,8 @@ open class PostgreSQLDialect : VendorDialect(dialectName, PostgreSQLDataTypeProv
override fun createDatabase(name: String): String = "CREATE DATABASE ${name.inProperCase()}"
+ override fun listDatabases(): String = "SELECT datname FROM pg_database"
+
override fun dropDatabase(name: String): String = "DROP DATABASE ${name.inProperCase()}"
override fun setSchema(schema: Schema): String = "SET search_path TO ${schema.identifier}"
diff --git a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/SQLiteDialect.kt b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/SQLiteDialect.kt
index cc6f9926d0..481bd73d32 100644
--- a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/SQLiteDialect.kt
+++ b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/SQLiteDialect.kt
@@ -273,6 +273,8 @@ open class SQLiteDialect : VendorDialect(dialectName, SQLiteDataTypeProvider, SQ
override fun createDatabase(name: String) = "ATTACH DATABASE '${name.lowercase()}.db' AS ${name.inProperCase()}"
+ override fun listDatabases(): String = "SELECT name FROM pragma_database_list"
+
override fun dropDatabase(name: String) = "DETACH DATABASE ${name.inProperCase()}"
companion object : DialectNameProvider("sqlite") {
diff --git a/exposed-jodatime/src/test/kotlin/org/jetbrains/exposed/JodaTimeDefaultsTest.kt b/exposed-jodatime/src/test/kotlin/org/jetbrains/exposed/JodaTimeDefaultsTest.kt
index e63120cf7e..f28ddc9134 100644
--- a/exposed-jodatime/src/test/kotlin/org/jetbrains/exposed/JodaTimeDefaultsTest.kt
+++ b/exposed-jodatime/src/test/kotlin/org/jetbrains/exposed/JodaTimeDefaultsTest.kt
@@ -47,7 +47,9 @@ class JodaTimeDefaultsTest : JodaTimeBaseTest() {
val clientDefault by TableWithDBDefault.clientDefault
override fun equals(other: Any?): Boolean {
- return (other as? DBDefault)?.let { id == it.id && field == it.field && equalDateTime(t1, it.t1) && equalDateTime(t2, it.t2) } ?: false
+ return (other as? DBDefault)?.let {
+ id == it.id && field == it.field && equalDateTime(t1, it.t1) && equalDateTime(t2, it.t2)
+ } ?: false
}
override fun hashCode(): Int = id.value.hashCode()
@@ -170,6 +172,7 @@ class JodaTimeDefaultsTest : JodaTimeBaseTest() {
fun Expression<*>.itOrNull() = when {
currentDialectTest.isAllowedAsColumnDefault(this) ->
"DEFAULT ${currentDialectTest.dataTypeProvider.processForDefaultValue(this)} NOT NULL"
+
else -> "NULL"
}
@@ -191,7 +194,10 @@ class JodaTimeDefaultsTest : JodaTimeBaseTest() {
")"
val expected = if (currentDialectTest is OracleDialect || currentDialectTest.h2Mode == H2Dialect.H2CompatibilityMode.Oracle) {
- arrayListOf("CREATE SEQUENCE t_id_seq START WITH 1 MINVALUE 1 MAXVALUE 9223372036854775807", baseExpression)
+ arrayListOf(
+ "CREATE SEQUENCE t_id_seq START WITH 1 MINVALUE 1 MAXVALUE 9223372036854775807",
+ baseExpression
+ )
} else {
arrayListOf(baseExpression)
}
@@ -276,13 +282,13 @@ class JodaTimeDefaultsTest : JodaTimeBaseTest() {
}
@Test
- fun defaultCurrentDateTimeTest() {
+ fun testDefaultCurrentDateTime() {
val testDate = object : IntIdTable("TestDate") {
val time = datetime("time").defaultExpression(CurrentDateTime)
}
withTables(testDate) {
- val duration: Long = 2_00
+ val duration: Long = 1000
val before = currentDateTime()
Thread.sleep(duration)
@@ -378,6 +384,7 @@ class JodaTimeDefaultsTest : JodaTimeBaseTest() {
fun Expression<*>.itOrNull() = when {
currentDialectTest.isAllowedAsColumnDefault(this) ->
"DEFAULT ${currentDialectTest.dataTypeProvider.processForDefaultValue(this)} NOT NULL"
+
else -> "NULL"
}
diff --git a/exposed-tests/src/main/kotlin/org/jetbrains/exposed/sql/tests/DatabaseTestsBase.kt b/exposed-tests/src/main/kotlin/org/jetbrains/exposed/sql/tests/DatabaseTestsBase.kt
index 37de15868e..dbc523a21e 100644
--- a/exposed-tests/src/main/kotlin/org/jetbrains/exposed/sql/tests/DatabaseTestsBase.kt
+++ b/exposed-tests/src/main/kotlin/org/jetbrains/exposed/sql/tests/DatabaseTestsBase.kt
@@ -17,12 +17,12 @@ import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import org.junit.runners.Parameterized.Parameters
import java.math.BigDecimal
-import java.sql.SQLException
import java.util.*
import kotlin.concurrent.thread
val TEST_DIALECTS: HashSet = System.getProperty(
- "exposed.test.dialects", ""
+ "exposed.test.dialects",
+ ""
).split(",").mapTo(HashSet()) { it.trim().uppercase() }
private val registeredOnShutdown = HashSet()
@@ -51,12 +51,11 @@ abstract class DatabaseTestsBase {
}
}
-
@Parameterized.Parameter(0)
lateinit var container: String
@Parameterized.Parameter(1)
- lateinit var dialect: Any
+ lateinit var dialect: TestDB
@Parameterized.Parameter(2)
lateinit var testName: String
@@ -66,40 +65,42 @@ abstract class DatabaseTestsBase {
if (dbSettings !in registeredOnShutdown) {
dbSettings.beforeConnection()
- Runtime.getRuntime().addShutdownHook(thread(false) {
- dbSettings.afterTestFinished()
- registeredOnShutdown.remove(dbSettings)
- })
+ Runtime.getRuntime().addShutdownHook(
+ thread(false) {
+ dbSettings.afterTestFinished()
+ registeredOnShutdown.remove(dbSettings)
+ }
+ )
registeredOnShutdown += dbSettings
dbSettings.db = dbSettings.connect()
}
val database = dbSettings.db!!
- try {
- transaction(database.transactionManager.defaultIsolationLevel, db = database) {
- repetitionAttempts = 1
- registerInterceptor(CurrentTestDBInterceptor)
- currentTestDB = dbSettings
- statement(dbSettings)
- }
- } catch (cause: SQLException) {
- throw cause
- } catch (cause: Throwable) {
- throw IllegalStateException("Failed on ${dbSettings.name}", cause)
+ transaction(database.transactionManager.defaultIsolationLevel, db = database) {
+ repetitionAttempts = 1
+ registerInterceptor(CurrentTestDBInterceptor)
+ currentTestDB = dbSettings
+ statement(dbSettings)
}
}
fun withDb(db: List? = null, excludeSettings: List = emptyList(), statement: Transaction.(TestDB) -> Unit) {
- val enabledInTests = TestDB.enabledDialects()
- val toTest = db?.intersect(enabledInTests) ?: (enabledInTests - excludeSettings)
- Assume.assumeTrue(toTest.isNotEmpty())
- toTest.forEach { dbSettings ->
- @Suppress("TooGenericExceptionCaught") try {
- withDb(dbSettings, statement)
- } catch (cause: Throwable) {
- throw AssertionError("Failed on ${dbSettings.name}", cause)
- }
+ if (db != null && dialect !in db) {
+ Assume.assumeFalse(true)
+ return
+ }
+
+ if (dialect in excludeSettings) {
+ Assume.assumeFalse(true)
+ return
+ }
+
+ if (dialect !in TestDB.enabledDialects()) {
+ Assume.assumeFalse(true)
+ return
}
+
+ withDb(dialect, statement)
}
fun withTables(excludeSettings: List, vararg tables: Table, statement: Transaction.(TestDB) -> Unit) {
@@ -138,20 +139,26 @@ abstract class DatabaseTestsBase {
}
fun withSchemas(excludeSettings: List, vararg schemas: Schema, statement: Transaction.() -> Unit) {
- val toTest = TestDB.enabledDialects() - excludeSettings
- Assume.assumeTrue(toTest.isNotEmpty())
- toTest.forEach { testDB ->
- withDb(testDB) {
- if (currentDialectTest.supportsCreateSchema) {
- SchemaUtils.createSchema(*schemas)
- try {
- statement()
- commit() // Need commit to persist data before drop schemas
- } finally {
- val cascade = it != TestDB.SQLSERVER
- SchemaUtils.dropSchema(*schemas, cascade = cascade)
- commit()
- }
+ if (dialect !in TestDB.enabledDialects()) {
+ Assume.assumeFalse(true)
+ return
+ }
+
+ if (dialect in excludeSettings) {
+ Assume.assumeFalse(true)
+ return
+ }
+
+ withDb(dialect) {
+ if (currentDialectTest.supportsCreateSchema) {
+ SchemaUtils.createSchema(*schemas)
+ try {
+ statement()
+ commit() // Need commit to persist data before drop schemas
+ } finally {
+ val cascade = it != TestDB.SQLSERVER
+ SchemaUtils.dropSchema(*schemas, cascade = cascade)
+ commit()
}
}
}
@@ -180,6 +187,10 @@ abstract class DatabaseTestsBase {
fun Transaction.isOldMySql(version: String = "8.0") = currentDialectTest is MysqlDialect && !db.isVersionCovers(BigDecimal(version))
protected fun prepareSchemaForTest(schemaName: String): Schema = Schema(
- schemaName, defaultTablespace = "USERS", temporaryTablespace = "TEMP ", quota = "20M", on = "USERS"
+ schemaName,
+ defaultTablespace = "USERS",
+ temporaryTablespace = "TEMP ",
+ quota = "20M",
+ on = "USERS"
)
}
diff --git a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/DDLTests.kt b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/DDLTests.kt
index 5aa1ed30f2..925847e4db 100644
--- a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/DDLTests.kt
+++ b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/DDLTests.kt
@@ -495,7 +495,8 @@ class DDLTests : DatabaseTestsBase() {
val testTable = object : Table("TestTable") {
val number = integer("number")
- val blobWithDefault = blob("blobWithDefault").default(defaultBlob)
+ val blobWithDefault = blob("blobWithDefault")
+ .default(defaultBlob)
}
withDb { testDb ->
@@ -506,6 +507,7 @@ class DDLTests : DatabaseTestsBase() {
}
}
else -> {
+ SchemaUtils.drop(testTable)
SchemaUtils.create(testTable)
testTable.insert {
@@ -959,10 +961,14 @@ class DDLTests : DatabaseTestsBase() {
val one = prepareSchemaForTest("one")
val two = prepareSchemaForTest("two")
withSchemas(two, one) {
+ SchemaUtils.drop(TableFromSchemeOne)
SchemaUtils.create(TableFromSchemeOne)
+
if (currentDialectTest is OracleDialect) {
exec("GRANT REFERENCES ON ${TableFromSchemeOne.tableName} to TWO")
}
+
+ SchemaUtils.drop(TableFromSchemeTwo)
SchemaUtils.create(TableFromSchemeTwo)
val idFromOne = TableFromSchemeOne.insertAndGetId { }
diff --git a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/SchemaTests.kt b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/SchemaTests.kt
index f89b185fc4..d7390659e1 100644
--- a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/SchemaTests.kt
+++ b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/SchemaTests.kt
@@ -64,8 +64,10 @@ class SchemaTests : DatabaseTestsBase() {
val firstCatalogName = connection.catalog
+ exec("DROP TABLE IF EXISTS test")
exec("CREATE TABLE test(id INT PRIMARY KEY)")
SchemaUtils.setSchema(schema)
+ exec("DROP TABLE IF EXISTS test")
exec("CREATE TABLE test(id INT REFERENCES $firstCatalogName.test(id))")
val catalogName = connection.catalog
diff --git a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/ddl/CreateDatabaseTest.kt b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/ddl/CreateDatabaseTest.kt
index 1846e38a42..0ed1c5f1b7 100644
--- a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/ddl/CreateDatabaseTest.kt
+++ b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/ddl/CreateDatabaseTest.kt
@@ -3,8 +3,10 @@ package org.jetbrains.exposed.sql.tests.shared.ddl
import org.jetbrains.exposed.sql.SchemaUtils
import org.jetbrains.exposed.sql.tests.DatabaseTestsBase
import org.jetbrains.exposed.sql.tests.TestDB
+import org.jetbrains.exposed.sql.tests.shared.assertTrue
import org.junit.Test
import java.sql.SQLException
+import kotlin.test.assertFailsWith
class CreateDatabaseTest : DatabaseTestsBase() {
@@ -22,6 +24,53 @@ class CreateDatabaseTest : DatabaseTestsBase() {
}
}
+ @Test
+ fun testListDatabasesOracle() {
+ withDb(TestDB.ORACLE) {
+ assertFailsWith {
+ SchemaUtils.listDatabases()
+ }
+ }
+ }
+
+ @Test
+ fun testListDatabasesPostgres() {
+ withDb(TestDB.POSTGRESQL) {
+ connection.autoCommit = true
+ val dbName = "jetbrains"
+ val initial = SchemaUtils.listDatabases()
+ if (dbName in initial) {
+ SchemaUtils.dropDatabase(dbName)
+ }
+
+ SchemaUtils.createDatabase(dbName)
+ val created = SchemaUtils.listDatabases()
+ assertTrue(dbName in created)
+ SchemaUtils.dropDatabase(dbName)
+ val deleted = SchemaUtils.listDatabases()
+ assertTrue(dbName !in deleted)
+ connection.autoCommit = false
+ }
+ }
+
+ @Test
+ fun testListDatabases() {
+ withDb(excludeSettings = listOf(TestDB.ORACLE, TestDB.POSTGRESQL, TestDB.POSTGRESQLNG)) {
+ val dbName = "jetbrains"
+ val initial = SchemaUtils.listDatabases()
+ if (dbName in initial) {
+ SchemaUtils.dropDatabase(dbName)
+ }
+
+ SchemaUtils.createDatabase(dbName)
+ val created = SchemaUtils.listDatabases()
+ assertTrue(dbName in created)
+ SchemaUtils.dropDatabase(dbName)
+ val deleted = SchemaUtils.listDatabases()
+ assertTrue(dbName !in deleted)
+ }
+ }
+
@Test
fun testCreateAndDropDatabaseInPostgresql() {
// PostgreSQL needs auto commit to be "ON" to allow create database statement
diff --git a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/functions/MathFunctionTests.kt b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/functions/MathFunctionTests.kt
index 96964bce9c..a9375dd2ce 100644
--- a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/functions/MathFunctionTests.kt
+++ b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/functions/MathFunctionTests.kt
@@ -105,7 +105,7 @@ class MathFunctionTests : FunctionsTestBase() {
assertExpressionEqual(BigDecimal("11.2"), SqrtFunction(decimalLiteral(BigDecimal("125.44"))))
when (testDb) {
- TestDB.MYSQL, TestDB.MARIADB -> {
+ TestDB.MYSQL, TestDB.MARIADB, TestDB.SQLITE -> {
assertExpressionEqual(null, SqrtFunction(intLiteral(-100)))
}
TestDB.SQLSERVER -> {
@@ -114,7 +114,7 @@ class MathFunctionTests : FunctionsTestBase() {
assertExpressionEqual(null, SqrtFunction(intLiteral(-100)))
}
}
- TestDB.SQLITE, TestDB.POSTGRESQL, TestDB.POSTGRESQLNG, TestDB.ORACLE -> {
+ TestDB.POSTGRESQL, TestDB.POSTGRESQLNG, TestDB.ORACLE -> {
// SQLite, PSQL, Oracle fail to execute sqrt with negative value
expectException {
assertExpressionEqual(null, SqrtFunction(intLiteral(-100)))
diff --git a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/sqlite/ForeignKeyConstraintTests.kt b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/sqlite/ForeignKeyConstraintTests.kt
index dae4a3b481..1ded40692c 100644
--- a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/sqlite/ForeignKeyConstraintTests.kt
+++ b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/sqlite/ForeignKeyConstraintTests.kt
@@ -36,6 +36,7 @@ class ForeignKeyConstraintTests : DatabaseTestsBase() {
}
private fun Transaction.testOnDeleteSetDefault() {
+ SchemaUtils.drop(Category, Item)
SchemaUtils.create(Category, Item)
Category.insert {