From 1cbd04d586435504d7e78fe6901bc4b851959556 Mon Sep 17 00:00:00 2001 From: Viktor Thell Date: Wed, 14 Jun 2023 11:24:46 +0200 Subject: [PATCH] Support Multiple DMBS with one changeset We use this feature in JUnit testing to enable usage of HSQLDB in tests (using Postgres in prod). To not enforce rewriting of the entire liquibase config a flag was added that can be set to change deferrable handling. --- .../change/core/AddForeignKeyConstraintChange.java | 8 ++++++-- .../java/liquibase/database/AbstractJdbcDatabase.java | 5 +++++ .../src/main/java/liquibase/database/Database.java | 3 +++ .../java/liquibase/database/core/HsqlDatabase.java | 6 ++++++ .../java/liquibase/database/core/MockDatabase.java | 5 +++++ .../core/AddForeignKeyConstraintGenerator.java | 10 ++++++++-- 6 files changed, 33 insertions(+), 4 deletions(-) diff --git a/liquibase-standard/src/main/java/liquibase/change/core/AddForeignKeyConstraintChange.java b/liquibase-standard/src/main/java/liquibase/change/core/AddForeignKeyConstraintChange.java index a703a89039..91d1a4a6d0 100644 --- a/liquibase-standard/src/main/java/liquibase/change/core/AddForeignKeyConstraintChange.java +++ b/liquibase-standard/src/main/java/liquibase/change/core/AddForeignKeyConstraintChange.java @@ -278,12 +278,12 @@ public void setOnUpdate(ForeignKeyConstraintType rule) { public SqlStatement[] generateStatements(Database database) { boolean deferrable = false; - if (getDeferrable() != null) { + if (checkDeferrable(database) && getDeferrable() != null) { deferrable = getDeferrable(); } boolean initiallyDeferred = false; - if (getInitiallyDeferred() != null) { + if (checkDeferrable(database) && getInitiallyDeferred() != null) { initiallyDeferred = getInitiallyDeferred(); } @@ -310,6 +310,10 @@ public SqlStatement[] generateStatements(Database database) { }; } + private boolean checkDeferrable(Database database) { + return database.supportsInitiallyDeferrableColumns() || database.failOnDeferrable(); + } + @Override protected Change[] createInverses() { DropForeignKeyConstraintChange inverse = new DropForeignKeyConstraintChange(); diff --git a/liquibase-standard/src/main/java/liquibase/database/AbstractJdbcDatabase.java b/liquibase-standard/src/main/java/liquibase/database/AbstractJdbcDatabase.java index 3c8a985d1c..8f0e6bac55 100644 --- a/liquibase-standard/src/main/java/liquibase/database/AbstractJdbcDatabase.java +++ b/liquibase-standard/src/main/java/liquibase/database/AbstractJdbcDatabase.java @@ -168,6 +168,11 @@ public DatabaseObject[] getContainingObjects() { return null; } + @Override + public boolean failOnDeferrable() { + return true; + } + // ------- DATABASE INFORMATION METHODS ---- // @Override diff --git a/liquibase-standard/src/main/java/liquibase/database/Database.java b/liquibase-standard/src/main/java/liquibase/database/Database.java index a4579076e6..c8707b104a 100644 --- a/liquibase-standard/src/main/java/liquibase/database/Database.java +++ b/liquibase-standard/src/main/java/liquibase/database/Database.java @@ -472,5 +472,8 @@ default String getDisplayName() { String unescapeDataTypeString(String dataTypeString); ValidationErrors validate(); + + boolean failOnDeferrable(); + } diff --git a/liquibase-standard/src/main/java/liquibase/database/core/HsqlDatabase.java b/liquibase-standard/src/main/java/liquibase/database/core/HsqlDatabase.java index aa57c04c2c..141ed27554 100644 --- a/liquibase-standard/src/main/java/liquibase/database/core/HsqlDatabase.java +++ b/liquibase-standard/src/main/java/liquibase/database/core/HsqlDatabase.java @@ -519,4 +519,10 @@ public String getAutoIncrementClause(BigInteger startWith, BigInteger incrementB final String clause = super.getAutoIncrementClause(startWith, incrementBy, generationType, defaultOnNull); return clause.replace(",", ""); //sql doesn't use commas between the values } + + @Override + public boolean failOnDeferrable() { + return false; + } + } diff --git a/liquibase-standard/src/main/java/liquibase/database/core/MockDatabase.java b/liquibase-standard/src/main/java/liquibase/database/core/MockDatabase.java index 2f8883303d..799299b7cb 100644 --- a/liquibase-standard/src/main/java/liquibase/database/core/MockDatabase.java +++ b/liquibase-standard/src/main/java/liquibase/database/core/MockDatabase.java @@ -796,6 +796,11 @@ public ValidationErrors validate() { return new ValidationErrors(); } + @Override + public boolean failOnDeferrable() { + return true; + } + @Override public boolean supportsNotNullConstraintNames() { return false; diff --git a/liquibase-standard/src/main/java/liquibase/sqlgenerator/core/AddForeignKeyConstraintGenerator.java b/liquibase-standard/src/main/java/liquibase/sqlgenerator/core/AddForeignKeyConstraintGenerator.java index 89d029bdc9..ed0a876e27 100644 --- a/liquibase-standard/src/main/java/liquibase/sqlgenerator/core/AddForeignKeyConstraintGenerator.java +++ b/liquibase-standard/src/main/java/liquibase/sqlgenerator/core/AddForeignKeyConstraintGenerator.java @@ -24,8 +24,14 @@ public ValidationErrors validate(AddForeignKeyConstraintStatement addForeignKeyC ValidationErrors validationErrors = new ValidationErrors(); if ((addForeignKeyConstraintStatement.isInitiallyDeferred() || addForeignKeyConstraintStatement.isDeferrable()) && !database.supportsInitiallyDeferrableColumns()) { - validationErrors.checkDisallowedField("initiallyDeferred", addForeignKeyConstraintStatement.isInitiallyDeferred(), database); - validationErrors.checkDisallowedField("deferrable", addForeignKeyConstraintStatement.isDeferrable(), database); + if (database.failOnDeferrable()) { + validationErrors.checkDisallowedField("initiallyDeferred", addForeignKeyConstraintStatement.isInitiallyDeferred(), database); + validationErrors.checkDisallowedField("deferrable", addForeignKeyConstraintStatement.isDeferrable(), database); + } else { + // reset this as it's not supported + addForeignKeyConstraintStatement.setDeferrable(false); + addForeignKeyConstraintStatement.setInitiallyDeferred(false); + } } validationErrors.checkRequiredField("baseColumnNames", addForeignKeyConstraintStatement.getBaseColumnNames());