Skip to content

Commit

Permalink
Merge branch 'master' into dependabot-maven-jakarta.enterprise-jakart…
Browse files Browse the repository at this point in the history
…a.enterprise.cdi-api-4.1.0
  • Loading branch information
MalloD12 committed May 22, 2024
2 parents 9a39fa0 + 33fbef1 commit e599f20
Show file tree
Hide file tree
Showing 14 changed files with 241 additions and 31 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release-published.yml
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ jobs:
cache: 'maven'
server-id: liquibase
- name: Set up Maven
uses: stCarolas/setup-maven@v4.5
uses: stCarolas/setup-maven@v5
with:
maven-version: ${{ env.MAVEN_VERSION }}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,16 @@ Global Options
supportPropertyEscaping', environment variable:
'LIQUIBASE_SUPPORT_PROPERTY_ESCAPING')
--supports-method-validation-level=PARAM
Controls the level of validation performed on the
supports method of Change classes. Options are
OFF, WARN, FAIL.
DEFAULT: WARN
(defaults file: 'liquibase.
supportsMethodValidationLevel', environment
variable:
'LIQUIBASE_SUPPORTS_METHOD_VALIDATION_LEVEL')
--ui-service=PARAM Changes the default UI Service Logger used by
Liquibase. Options are CONSOLE or LOGGER.
DEFAULT: CONSOLE
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package liquibase.command


import liquibase.Scope
import liquibase.extension.testing.testsystem.DatabaseTestSystem
import liquibase.extension.testing.testsystem.TestSystemFactory
import liquibase.extension.testing.testsystem.spock.LiquibaseIntegrationTest
import liquibase.structure.core.Table
import liquibase.structure.core.UniqueConstraint
import liquibase.util.StringUtil
import spock.lang.Shared
import spock.lang.Specification

import static liquibase.command.util.CommandUtil.takeDatabaseSnapshot

@LiquibaseIntegrationTest
class SnapshotSnowflakeIntegrationTest extends Specification{

@Shared
private DatabaseTestSystem snowflake = Scope.currentScope.getSingleton(TestSystemFactory).getTestSystem("snowflake") as DatabaseTestSystem

def "snapshot table in another schema"() {
def schemaName = StringUtil.randomIdentifier(10).toUpperCase()
when:
snowflake.executeSql("CREATE SCHEMA ${schemaName}")
snowflake.executeSql("""
CREATE TABLE ${schemaName}.TABLE4 (
col1 INTEGER NOT NULL,
col2 INTEGER NOT NULL
);
""")
snowflake.executeSql("ALTER TABLE ${schemaName}.table4 ADD CONSTRAINT UNIQUENESS UNIQUE(col1, col2) ENFORCED;")
// Close the connection to force a new connection to be created using the default schema name (not the schema name from above)
snowflake.getConnection().close()

then:
def snapshot = takeDatabaseSnapshot(snowflake.getDatabaseFromFactory(), schemaName)
snapshot != null
def tables = snapshot.get(Table.class)
tables.size() == 1
tables[0].getName() == "TABLE4"
tables[0].getSchema().getName() == schemaName
def uniqueConstraints = snapshot.get(UniqueConstraint)
uniqueConstraints.size() == 1
uniqueConstraints[0].getTable().getName() == "TABLE4"
uniqueConstraints[0].getName() == "UNIQUENESS"

cleanup:
snowflake.executeSql("DROP SCHEMA ${schemaName}")
}

}
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package liquibase.command.util

import liquibase.CatalogAndSchema
import liquibase.Scope
import liquibase.TagVersionEnum
import liquibase.UpdateSummaryEnum
import liquibase.changelog.ChangeLogHistoryService
import liquibase.changelog.ChangeLogHistoryServiceFactory
import liquibase.command.CommandScope
import liquibase.command.core.*
import liquibase.command.core.helpers.*
Expand All @@ -14,6 +17,7 @@ import liquibase.lockservice.LockServiceFactory
import liquibase.resource.ResourceAccessor
import liquibase.resource.SearchPathResourceAccessor
import liquibase.sdk.resource.MockResourceAccessor
import liquibase.snapshot.DatabaseSnapshot

class CommandUtil {

Expand Down Expand Up @@ -83,6 +87,28 @@ class CommandUtil {
commandScope.execute()
}

/**
* Take a snapshot of the database and the specified schemas.
*/
static DatabaseSnapshot takeDatabaseSnapshot(Database database, String... schema) {
final ChangeLogHistoryService changeLogService = ChangeLogHistoryServiceFactory.getInstance().getChangeLogService(database)
changeLogService.init()
changeLogService.reset()

CatalogAndSchema[] schemas = new CatalogAndSchema[schema.size()]
for(int i = 0; i < schema.size(); i++) {
schemas[i] = new CatalogAndSchema(null, schema[i])
}
CommandScope snapshotCommand = new CommandScope("internalSnapshot")
snapshotCommand
.addArgumentValue(InternalSnapshotCommandStep.DATABASE_ARG, database)
.addArgumentValue(InternalSnapshotCommandStep.SCHEMAS_ARG, schemas)
.addArgumentValue(InternalSnapshotCommandStep.SERIALIZER_FORMAT_ARG, "txt")

def snapshotResults = snapshotCommand.execute()
return (DatabaseSnapshot) snapshotResults.getResult("snapshot")
}

static void runDiff(DatabaseTestSystem db, Database targetDatabase, Database referenceDatabase,
String outputFile) throws CommandExecutionException {
CommandScope commandScope = new CommandScope(DiffCommandStep.COMMAND_NAME)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@
import liquibase.snapshot.SnapshotGenerator;
import liquibase.statement.core.RawSqlStatement;
import liquibase.structure.DatabaseObject;
import liquibase.structure.core.*;
import liquibase.structure.core.Relation;
import liquibase.structure.core.Schema;
import liquibase.structure.core.Table;
import liquibase.structure.core.UniqueConstraint;

import java.sql.SQLException;
import java.util.List;
Expand Down Expand Up @@ -48,7 +51,7 @@ protected List<CachedRow> listConstraints(Table table, DatabaseSnapshot snapshot
String tableName = database.correctObjectName(table.getName(), Table.class);
String constraintName = database.correctObjectName(name, UniqueConstraint.class);

String showSql = "SHOW UNIQUE KEYS IN " + tableName;
String showSql = "SHOW UNIQUE KEYS IN " + database.escapeObjectName(table.getSchema().getCatalogName(), table.getSchema().getName(), tableName, Table.class);
String sql = "SELECT \"column_name\" AS COLUMN_NAME FROM TABLE(result_scan(last_query_id())) WHERE \"constraint_name\"= '" + constraintName +"'";

Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor("jdbc", database)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public class GlobalConfiguration implements AutoloadedConfigurations {
public static final ConfigurationDefinition<String> SEARCH_PATH;

public static final ConfigurationDefinition<UIServiceEnum> UI_SERVICE;
public static final ConfigurationDefinition<SupportsMethodValidationLevelsEnum> SUPPORTS_METHOD_VALIDATION_LEVEL;

static {
ConfigurationDefinition.Builder builder = new ConfigurationDefinition.Builder("liquibase");
Expand Down Expand Up @@ -242,10 +243,16 @@ public class GlobalConfiguration implements AutoloadedConfigurations {
.setDescription("Changes the default UI Service Logger used by Liquibase. Options are CONSOLE or LOGGER.")
.setDefaultValue(UIServiceEnum.CONSOLE)
.build();

SUPPORTS_METHOD_VALIDATION_LEVEL = builder.define("supportsMethodValidationLevel", SupportsMethodValidationLevelsEnum.class)
.setDescription("Controls the level of validation performed on the supports method of Change classes. Options are OFF, WARN, FAIL.")
.setDefaultValue(SupportsMethodValidationLevelsEnum.WARN)
.build();
}

public enum DuplicateFileMode {
WARN,
ERROR,
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package liquibase;

/**
* Enum to control the level of validation to check if a change's supports method is properly implemented.
*/
public enum SupportsMethodValidationLevelsEnum {
OFF,
WARN,
FAIL
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package liquibase.change;

import liquibase.ChecksumVersion;
import liquibase.GlobalConfiguration;
import liquibase.Scope;
import liquibase.SupportsMethodValidationLevelsEnum;
import liquibase.database.Database;
import liquibase.exception.UnexpectedLiquibaseException;
import liquibase.plugin.AbstractPluginFactory;
import liquibase.plugin.Plugin;
import liquibase.servicelocator.ServiceLocator;
import liquibase.util.LiquibaseUtil;
import lombok.Setter;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
Expand All @@ -21,8 +25,15 @@
public class ChangeFactory extends AbstractPluginFactory<Change>{

private final Map<String, ChangeMetaData> cachedMetadata = new ConcurrentHashMap<>();

/**
* Should the change be checked to see if it supports the current database?
*/
@Setter
private boolean performSupportsDatabaseValidation = true;

protected static final String SUPPORTS_METHOD_REQUIRED_MESSAGE = "%s class does not implement the 'supports(Database)' method and may incorrectly override other databases changes causing unexpected behavior. Please report this to the Liquibase developers or if you are developing this change please fix it ;)";

private ChangeFactory() {

}
Expand Down Expand Up @@ -104,6 +115,9 @@ public Change create(String name) {
if (plugins.isEmpty()) {
return null;
} else if (plugins.size() > 1) {
// we only verify supports method if we have more than 1 implementation for this change,
// otherwise there is no use in doing that as we will use the only implementation available
this.verifySupportsMethodImplementation(plugins);
Database database = Scope.getCurrentScope().getDatabase();
if (database != null && performSupportsDatabaseValidation) {
plugins.removeIf(a -> !a.supports(database));
Expand All @@ -120,6 +134,42 @@ public Change create(String name) {
}
}

/**
* Verify if the supports method is implemented in the change if it's not part of the default liquibase changes
*/
private void verifySupportsMethodImplementation(Set<Change> plugins) {
if (GlobalConfiguration.SUPPORTS_METHOD_VALIDATION_LEVEL.getCurrentValue().equals(SupportsMethodValidationLevelsEnum.OFF)) {
return;
}
//we only verify supports method if this is not part of the default liquibase changes
for (Change plugin : plugins) {
String packageName = plugin.getClass().getPackage().getName();
if (packageName.startsWith("liquibase.change")) {
continue;
}

try {
// if the supports method is not implemented in the plugin show the warning according to the defined level
if (plugin.getClass().getMethod("supports", Database.class).getDeclaringClass().getPackage().getName().startsWith("liquibase.change")) {
if (LiquibaseUtil.getBuildVersion().equals(LiquibaseUtil.DEV_VERSION)) {
throw new UnexpectedLiquibaseException(String.format(SUPPORTS_METHOD_REQUIRED_MESSAGE, plugin.getClass().getName()));
}
switch (GlobalConfiguration.SUPPORTS_METHOD_VALIDATION_LEVEL.getCurrentValue()) {
case WARN:
Scope.getCurrentScope().getLog(getClass()).warning(String.format(SUPPORTS_METHOD_REQUIRED_MESSAGE, plugin.getClass().getName()));
break;
case FAIL:
throw new UnexpectedLiquibaseException(String.format(SUPPORTS_METHOD_REQUIRED_MESSAGE, plugin.getClass().getName()));
default:
break;
}
}
} catch (NoSuchMethodException e) {
throw new UnexpectedLiquibaseException(String.format(SUPPORTS_METHOD_REQUIRED_MESSAGE, plugin.getClass().getName()));
}
}
}

public Map<String, Object> getParameters(Change change) {
Map<String, Object> returnMap = new HashMap<>();
ChangeMetaData changeMetaData = getChangeMetaData(change);
Expand All @@ -141,14 +191,4 @@ public static ChangeFactory getInstance() {
return Scope.getCurrentScope().getSingleton(ChangeFactory.class);
}

/**
* Should the change be checked to see if it supports
* the current database?
* Default is true
*
* @param performSupportsDatabaseValidation
*/
public void setPerformSupportsDatabaseValidation(boolean performSupportsDatabaseValidation) {
this.performSupportsDatabaseValidation = performSupportsDatabaseValidation;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ private void warnForMismatchedXsdVersion(String systemId) {
boolean found = versionMatcher.find();
if (found) {
String buildVersion = LiquibaseUtil.getBuildVersion();
if (!buildVersion.equals("DEV")) {
if (!buildVersion.equals(LiquibaseUtil.DEV_VERSION)) {
String xsdVersion = versionMatcher.group("version");
if (!buildVersion.startsWith(xsdVersion)) {
hasWarnedAboutMismatchedXsdVersion = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@

public class LiquibaseUtil {

public static final String DEV_VERSION = "DEV";

private static Properties liquibaseBuildProperties;

/**
* Return the configured build.version. Will always be "DEV" for non-release builds.
* Return the configured build.version. Will always be DEV_VERSION for non-release builds.
*/
public static String getBuildVersion() {
return getBuildInfo("build.version");
Expand All @@ -26,7 +28,7 @@ public static String getBuildVersion() {
*/
public static String getBuildVersionInfo() {
String version = getBuildInfo("build.version");
if (version.equals("DEV")) {
if (version.equals(DEV_VERSION)) {
final String buildCommit = getBuildInfo("build.commit");
if (buildCommit.equals("unknown")) {
version = "[local build]";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import liquibase.exception.ChangeLogParseException
import liquibase.exception.LiquibaseException
import liquibase.sdk.resource.MockResourceAccessor
import liquibase.test.JUnitResourceAccessor
import liquibase.util.LiquibaseUtil
import spock.lang.Specification
import spock.lang.Unroll

Expand Down Expand Up @@ -173,13 +174,13 @@ class XMLChangeLogSAXParserTest extends Specification {
XMLChangeLogSAXParser.computeSchemaVersion(buildVersion) == expected

where:
buildVersion | expected
"DEV" | "latest"
"4.11.0" | "4.11"
"4.11.1" | "4.11"
"4" | "latest" //weird versions go to latest
"" | "latest" //weird versions go to latest
null | "latest" //weird versions go to latest
buildVersion | expected
LiquibaseUtil.DEV_VERSION | "latest"
"4.11.0" | "4.11"
"4.11.1" | "4.11"
"4" | "latest" //weird versions go to latest
"" | "latest" //weird versions go to latest
null | "latest" //weird versions go to latest
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ class LiquibaseUtilTest extends Specification {
LiquibaseUtil.getBuildVersion() == version

where:
version | localBuild | proData | expected
"1.2.3" | false | true | "1.2.3"
"1.2.3" | false | false | "1.2.3"
"DEV" | false | true | "[Core: liquibase/liquibase/test-branch/524/7904bb/2021-09-17 14:06+0000, Pro: other-branch/58/e5195b/2021-09-17T14:04:58Z]"
"DEV" | false | false | "[Core: liquibase/liquibase/test-branch/524/7904bb/2021-09-17 14:06+0000]"
"DEV" | true | true | "[local build]"
"DEV" | true | false | "[local build]"
version | localBuild | proData | expected
"1.2.3" | false | true | "1.2.3"
"1.2.3" | false | false | "1.2.3"
LiquibaseUtil.DEV_VERSION | false | true | "[Core: liquibase/liquibase/test-branch/524/7904bb/2021-09-17 14:06+0000, Pro: other-branch/58/e5195b/2021-09-17T14:04:58Z]"
LiquibaseUtil.DEV_VERSION | false | false | "[Core: liquibase/liquibase/test-branch/524/7904bb/2021-09-17 14:06+0000]"
LiquibaseUtil.DEV_VERSION | true | true | "[local build]"
LiquibaseUtil.DEV_VERSION | true | false | "[local build]"
}

def "getBuildVersionInfo actuallyRead"() {
Expand Down
Loading

0 comments on commit e599f20

Please sign in to comment.