Skip to content

Commit

Permalink
feat: EXPOSED-296 Add ability to check if a Sequence exists in a data…
Browse files Browse the repository at this point in the history
…base
  • Loading branch information
joc-a committed Apr 11, 2024
1 parent cf247fa commit 23b19e9
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 0 deletions.
6 changes: 6 additions & 0 deletions exposed-core/api/exposed-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -1992,6 +1992,7 @@ public final class org/jetbrains/exposed/sql/Sequence {
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Boolean;Ljava/lang/Long;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun createStatement ()Ljava/util/List;
public final fun dropStatement ()Ljava/util/List;
public final fun exists ()Z
public final fun getCache ()Ljava/lang/Long;
public final fun getCycle ()Ljava/lang/Boolean;
public final fun getDdl ()Ljava/util/List;
Expand Down Expand Up @@ -3161,6 +3162,7 @@ public abstract class org/jetbrains/exposed/sql/statements/api/ExposedDatabaseMe
public abstract fun columns ([Lorg/jetbrains/exposed/sql/Table;)Ljava/util/Map;
public abstract fun existingIndices ([Lorg/jetbrains/exposed/sql/Table;)Ljava/util/Map;
public abstract fun existingPrimaryKeys ([Lorg/jetbrains/exposed/sql/Table;)Ljava/util/Map;
public abstract fun existingSequences ()Ljava/util/List;
public abstract synthetic fun getCurrentScheme ()Ljava/lang/String;
public final fun getDatabase ()Ljava/lang/String;
public abstract fun getDatabaseDialectName ()Ljava/lang/String;
Expand Down Expand Up @@ -3430,6 +3432,7 @@ public abstract interface class org/jetbrains/exposed/sql/vendors/DatabaseDialec
public abstract fun dropSchema (Lorg/jetbrains/exposed/sql/Schema;Z)Ljava/lang/String;
public abstract fun existingIndices ([Lorg/jetbrains/exposed/sql/Table;)Ljava/util/Map;
public abstract fun existingPrimaryKeys ([Lorg/jetbrains/exposed/sql/Table;)Ljava/util/Map;
public abstract fun existingSequences ()Ljava/util/List;
public abstract fun getDataTypeProvider ()Lorg/jetbrains/exposed/sql/vendors/DataTypeProvider;
public abstract fun getDatabase ()Ljava/lang/String;
public abstract fun getDefaultReferenceOption ()Lorg/jetbrains/exposed/sql/ReferenceOption;
Expand Down Expand Up @@ -3460,6 +3463,7 @@ public abstract interface class org/jetbrains/exposed/sql/vendors/DatabaseDialec
public abstract fun resetSchemaCaches ()V
public abstract fun resolveRefOptionFromJdbc (I)Lorg/jetbrains/exposed/sql/ReferenceOption;
public abstract fun schemaExists (Lorg/jetbrains/exposed/sql/Schema;)Z
public abstract fun sequenceExists (Lorg/jetbrains/exposed/sql/Sequence;)Z
public abstract fun setSchema (Lorg/jetbrains/exposed/sql/Schema;)Ljava/lang/String;
public abstract fun supportsSelectForUpdate ()Z
public abstract fun tableColumns ([Lorg/jetbrains/exposed/sql/Table;)Ljava/util/Map;
Expand Down Expand Up @@ -3892,6 +3896,7 @@ public abstract class org/jetbrains/exposed/sql/vendors/VendorDialect : org/jetb
public fun dropSchema (Lorg/jetbrains/exposed/sql/Schema;Z)Ljava/lang/String;
public fun existingIndices ([Lorg/jetbrains/exposed/sql/Table;)Ljava/util/Map;
public fun existingPrimaryKeys ([Lorg/jetbrains/exposed/sql/Table;)Ljava/util/Map;
public fun existingSequences ()Ljava/util/List;
protected fun fillConstraintCacheForTables (Ljava/util/List;)V
public final fun filterCondition (Lorg/jetbrains/exposed/sql/Index;)Ljava/lang/String;
protected final fun getAllTableNamesCache ()Ljava/util/Map;
Expand Down Expand Up @@ -3930,6 +3935,7 @@ public abstract class org/jetbrains/exposed/sql/vendors/VendorDialect : org/jetb
public fun resetSchemaCaches ()V
public fun resolveRefOptionFromJdbc (I)Lorg/jetbrains/exposed/sql/ReferenceOption;
public fun schemaExists (Lorg/jetbrains/exposed/sql/Schema;)Z
public fun sequenceExists (Lorg/jetbrains/exposed/sql/Sequence;)Z
public fun setSchema (Lorg/jetbrains/exposed/sql/Schema;)Ljava/lang/String;
public fun supportsSelectForUpdate ()Z
public fun tableColumns ([Lorg/jetbrains/exposed/sql/Table;)Ljava/util/Map;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,6 @@ class Sequence(

return listOf(dropSequenceDDL)
}

fun exists(): Boolean = currentDialect.sequenceExists(this)
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ abstract class ExposedDatabaseMetadata(val database: String) {
/** Returns a map with the [PrimaryKeyMetadata] in each of the specified [tables]. */
abstract fun existingPrimaryKeys(vararg tables: Table): Map<Table, PrimaryKeyMetadata?>

abstract fun existingSequences(): List<String>

/**
* Returns a map with the [ForeignKeyConstraint] of all the defined columns in each of the specified [tables],
* with the table name used as the key.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ interface DatabaseDialect {
/** Checks if the specified schema exists. */
fun schemaExists(schema: Schema): Boolean

fun sequenceExists(sequence: Sequence): Boolean

fun checkTableMapping(table: Table): Boolean = true

/** Returns a map with the column metadata of all the defined columns in each of the specified [tables]. */
Expand All @@ -103,6 +105,8 @@ interface DatabaseDialect {
/** Returns a map with the primary key metadata in each of the specified [tables]. */
fun existingPrimaryKeys(vararg tables: Table): Map<Table, PrimaryKeyMetadata?> = emptyMap()

fun existingSequences(): List<String>

/** Returns `true` if the dialect supports `SELECT FOR UPDATE` statements, `false` otherwise. */
fun supportsSelectForUpdate(): Boolean

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ abstract class VendorDialect(
return allSchemas.any { it == schema.identifier.inProperCase() }
}

override fun sequenceExists(sequence: Sequence): Boolean {
val allSequences = existingSequences()
return allSequences.any { it == sequence.identifier.inProperCase() }
}

override fun tableColumns(vararg tables: Table): Map<Table, List<ColumnMetadata>> =
TransactionManager.current().connection.metadata { columns(*tables) }

Expand All @@ -116,6 +121,9 @@ abstract class VendorDialect(
override fun existingPrimaryKeys(vararg tables: Table): Map<Table, PrimaryKeyMetadata?> =
TransactionManager.current().db.metadata { existingPrimaryKeys(*tables) }

override fun existingSequences(): List<String> =
TransactionManager.current().db.metadata { existingSequences() }

private val supportsSelectForUpdate: Boolean by lazy {
TransactionManager.current().db.metadata { supportsSelectForUpdate }
}
Expand Down
1 change: 1 addition & 0 deletions exposed-jdbc/api/exposed-jdbc.api
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public final class org/jetbrains/exposed/sql/statements/jdbc/JdbcDatabaseMetadat
public fun columns ([Lorg/jetbrains/exposed/sql/Table;)Ljava/util/Map;
public fun existingIndices ([Lorg/jetbrains/exposed/sql/Table;)Ljava/util/Map;
public fun existingPrimaryKeys ([Lorg/jetbrains/exposed/sql/Table;)Ljava/util/Map;
public fun existingSequences ()Ljava/util/List;
public synthetic fun getCurrentScheme ()Ljava/lang/String;
public fun getDatabaseDialectName ()Ljava/lang/String;
public fun getDatabaseProductVersion ()Ljava/lang/String;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,43 @@ class JdbcDatabaseMetadataImpl(database: String, val metadata: DatabaseMetaData)
}
}

@Suppress("MagicNumber")
override fun existingSequences(): List<String> {
val sequences = mutableListOf<String>()

when (currentDialect) {
is OracleDialect -> {
TransactionManager.current().exec("SELECT SEQUENCE_NAME FROM USER_SEQUENCES") { rs ->
while (rs.next()) {
sequences.add(rs.getString("SEQUENCE_NAME"))
}
}
}
is SQLServerDialect -> {
TransactionManager.current().exec("SELECT name FROM sys.sequences") { rs ->
while (rs.next()) {
sequences.add(rs.getString("name"))
}
}
}
is H2Dialect -> {
TransactionManager.current().exec("SELECT SEQUENCE_NAME FROM INFORMATION_SCHEMA.SEQUENCES ") { rs ->
while (rs.next()) {
sequences.add(rs.getString("SEQUENCE_NAME"))
}
}
}
else -> {
val rs = metadata.getTables(null, null, null, arrayOf("SEQUENCE"))
while (rs.next()) {
sequences.add(rs.getString(3))
}
}
}

return sequences
}

@Synchronized
override fun tableConstraints(tables: List<Table>): Map<String, List<ForeignKeyConstraint>> {
val allTables = SchemaUtils.sortTablesByReferences(tables).associateBy { it.nameInDatabaseCaseUnquoted() }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.tests.DatabaseTestsBase
import org.jetbrains.exposed.sql.tests.currentDialectTest
import org.jetbrains.exposed.sql.tests.shared.assertEquals
import org.jetbrains.exposed.sql.tests.shared.assertTrue
import org.junit.Test
import kotlin.test.assertNotNull

Expand Down Expand Up @@ -132,6 +133,21 @@ class SequencesTests : DatabaseTestsBase() {
}
}

@Test
fun testSequenceExists() {
withDb {
if (currentDialectTest.supportsCreateSequence) {
try {
SchemaUtils.createSequence(myseq)

assertTrue(myseq.exists())
} finally {
SchemaUtils.dropSequence(myseq)
}
}
}
}

private object Developer : Table() {
val id = integer("id")
var name = varchar("name", 25)
Expand Down

0 comments on commit 23b19e9

Please sign in to comment.