mirror of
https://github.com/corda/corda.git
synced 2025-04-19 08:36:39 +00:00
ENT-2530 Corda fails when running against PostgreSQL with uppercase schema namespace. (#1412)
Fix Liquibase quoting strategy for PostgreSQL to follow Corda convention. In Liquibase for Postgres if schema name has uppercase or lowercase characters only then Liquibase would send it without double quotes and effectively make them lowercase. Alter Postgres Liquibase dialect to wrap schema names in double quotes. This allows e.g. schemaName=ALICE be send as "ALICE" by Liquibase. Corda persistence was already wrapping with double quotes, but certain cases in Liquibase were not following this. The result was that SQL run by Liquibase couldn't find schema (e.g. select ALICE.tablename ... in Postgres matched alice schema name not ALICE one). The fix enables one integration test to be run now against standalone databases.
This commit is contained in:
parent
6404dc3391
commit
f2c0beb8d0
@ -86,7 +86,7 @@ class HibernateConfiguration(
|
||||
config.setProperty("hibernate.hbm2ddl.auto","validate")
|
||||
|
||||
databaseConfig.schema?.apply {
|
||||
//preserving case-sensitive schema name for PostgreSQL by wrapping in double quotes, schema without double quotes would be treated as case-insensitive (lower cases)
|
||||
// Enterprise only - preserving case-sensitive schema name for PostgreSQL by wrapping in double quotes, schema without double quotes would be treated as case-insensitive (lower cases)
|
||||
val schemaName = if (jdbcUrl.contains(":postgresql:", ignoreCase = true) && !databaseConfig.schema.startsWith("\"")) {
|
||||
"\"" + databaseConfig.schema + "\""
|
||||
} else {
|
||||
@ -231,4 +231,3 @@ class HibernateConfiguration(
|
||||
|
||||
/** Allow Oracle database drivers ojdbc7.jar and ojdbc8.jar to deserialize classes from oracle.sql.converter package. */
|
||||
fun oracleJdbcDriverSerialFilter(clazz: Class<*>): Boolean = clazz.name.startsWith("oracle.sql.converter.")
|
||||
|
||||
|
@ -17,6 +17,9 @@ import java.io.ByteArrayInputStream
|
||||
import java.io.InputStream
|
||||
import java.io.Writer
|
||||
import javax.sql.DataSource
|
||||
import liquibase.database.core.PostgresDatabase
|
||||
import liquibase.structure.DatabaseObject
|
||||
import liquibase.structure.core.Schema
|
||||
|
||||
class SchemaMigration(
|
||||
val schemas: Set<MappedSchema>,
|
||||
@ -135,6 +138,7 @@ class SchemaMigration(
|
||||
|
||||
private fun getLiquibaseDatabase(conn: JdbcConnection): Database {
|
||||
|
||||
// Enterprise only
|
||||
// The standard MSSQLDatabase in Liquibase does not support sequences for Ms Azure.
|
||||
// this class just overrides that behaviour
|
||||
class AzureDatabase(conn: JdbcConnection) : MSSQLDatabase() {
|
||||
@ -147,9 +151,33 @@ class SchemaMigration(
|
||||
override fun supportsSequences(): Boolean = true
|
||||
}
|
||||
|
||||
// Enterprise only
|
||||
// Postgres - Wrap schema name into double quotes to preserve case sensitivity
|
||||
class PostgresDatabaseFixed(conn: JdbcConnection) : PostgresDatabase() {
|
||||
init {
|
||||
this.connection = conn
|
||||
}
|
||||
|
||||
override fun getPriority(): Int { return super.getPriority() + 1 }
|
||||
|
||||
// For PostgreSQL if a schema name has uppercase or lowercase characters only then Liquibase would add it to generated query
|
||||
// without double quotes and effectively make them lowercase. This is inconsistent with Corda which wraps schema name for PostgreSQL in double quotes.
|
||||
// The overridden method ensures Liquibase wraps schema name into double quotes.
|
||||
override fun mustQuoteObjectName(objectName: String, objectType: Class<out DatabaseObject>?): Boolean {
|
||||
return if (objectType == Schema::class.java)
|
||||
true
|
||||
else
|
||||
super.mustQuoteObjectName(objectName, objectType)
|
||||
}
|
||||
}
|
||||
|
||||
val liquibaseDbImplementation = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(conn)
|
||||
|
||||
return if (liquibaseDbImplementation is MSSQLDatabase) AzureDatabase(conn) else liquibaseDbImplementation
|
||||
return when (liquibaseDbImplementation) {
|
||||
is PostgresDatabase -> PostgresDatabaseFixed(conn) // Enterprise only
|
||||
is MSSQLDatabase -> AzureDatabase(conn) // Enterprise only
|
||||
else -> liquibaseDbImplementation
|
||||
}
|
||||
}
|
||||
|
||||
/** For existing database created before verions 4.0 add Liquibase support - creates DATABASECHANGELOG and DATABASECHANGELOGLOCK tables and mark changesets are executed. */
|
||||
|
@ -58,7 +58,7 @@ class DriverTests : IntegrationTest() {
|
||||
@ClassRule
|
||||
@JvmField
|
||||
val databaseSchemas = IntegrationTestSchemas(DUMMY_BANK_A_NAME.toDatabaseSchemaName(), DUMMY_NOTARY_NAME.toDatabaseSchemaName(),
|
||||
DUMMY_REGULATOR_NAME.toDatabaseSchemaName(), BOB_NAME.toDatabaseSchemaName(), DUMMY_BANK_B_NAME.toDatabaseSchemaName())
|
||||
DUMMY_REGULATOR_NAME.toDatabaseSchemaName(), BOB_NAME.toDatabaseSchemaName(), DUMMY_BANK_B_NAME.toDatabaseSchemaName(), "R3CEV")
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -157,7 +157,6 @@ class DriverTests : IntegrationTest() {
|
||||
|
||||
@Test
|
||||
fun `driver rejects multiple nodes with the same organisation name`() {
|
||||
assumeTrue(!IntegrationTest.isRemoteDatabaseMode()) // Enterprise only - disable test, Liquibase doesn't quote schema name with all uppercase or lowercase letters
|
||||
driver(DriverParameters(startNodesInProcess = true, notarySpecs = emptyList())) {
|
||||
newNode(CordaX500Name(commonName = "Notary", organisation = "R3CEV", locality = "New York", country = "US"))().getOrThrow()
|
||||
assertThatIllegalArgumentException().isThrownBy {
|
||||
|
Loading…
x
Reference in New Issue
Block a user