Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementing a ChangeSetService for modification of model objects DAT-16079 #5117

Merged
merged 11 commits into from
Nov 6, 2023
Merged
1 change: 1 addition & 0 deletions liquibase-standard/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@
<param>liquibase.logging.mdc.MdcManager</param>
<param>liquibase.logging.mdc.CustomMdcObject</param>
<param>liquibase.report.ShowSummaryGenerator</param>
<param>liquibase.changeset.ChangeSetService</param>
</services>
</configuration>
<executions>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import liquibase.GlobalConfiguration;
import liquibase.Scope;
import liquibase.change.core.RawSQLChange;
import liquibase.changeset.ChangeSetService;
import liquibase.changeset.ChangeSetServiceFactory;
import liquibase.database.Database;
import liquibase.database.core.Db2zDatabase;
import liquibase.database.core.MSSQLDatabase;
Expand Down Expand Up @@ -202,7 +204,11 @@ public void setSql(String sql) {
*/
@DatabaseChangeProperty(description = "Delimiter to apply to the end of the statement. Defaults to ';', may be set to ''.", exampleValue = "\\nGO")
public String getEndDelimiter() {
return endDelimiter;
if (endDelimiter != null) {
return endDelimiter;
}
ChangeSetService service = ChangeSetServiceFactory.getInstance().createChangeSetService();
return service.getEndDelimiter(getChangeSet());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import liquibase.changelog.filter.DbmsChangeSetFilter;
import liquibase.changelog.filter.LabelChangeSetFilter;
import liquibase.changelog.visitor.ValidatingVisitor;
import liquibase.changeset.ChangeSetService;
import liquibase.changeset.ChangeSetServiceFactory;
import liquibase.database.Database;
import liquibase.database.DatabaseList;
import liquibase.database.ObjectQuotingStrategy;
Expand All @@ -25,8 +27,6 @@
import liquibase.resource.Resource;
import liquibase.resource.ResourceAccessor;
import liquibase.servicelocator.LiquibaseService;
import liquibase.sql.visitor.SqlVisitor;
import liquibase.sql.visitor.SqlVisitorFactory;
import liquibase.util.FileUtil;
import liquibase.util.StringUtil;

Expand Down Expand Up @@ -425,9 +425,7 @@ protected void handleChildNode(ParsedNode node, ResourceAccessor resourceAccesso
}
break;
case "modifyChangeSets":
ModifyChangeSets modifyChangeSets = new ModifyChangeSets(
(String) node.getChildValue(null, "runWith"),
(String) node.getChildValue(null, "runWithSpoolFile"));
ModifyChangeSets modifyChangeSets = createModifyChangeSets(node);
nodeScratch = new HashMap<>();
nodeScratch.put("modifyChangeSets", modifyChangeSets);
for (ParsedNode modifyChildNode : node.getChildren()) {
Expand Down Expand Up @@ -614,6 +612,12 @@ protected void handleChildNode(ParsedNode node, ResourceAccessor resourceAccesso
}
}

private ModifyChangeSets createModifyChangeSets(ParsedNode node) throws ParsedNodeException {
ChangeSetServiceFactory factory = ChangeSetServiceFactory.getInstance();
ChangeSetService service = factory.createChangeSetService();
return service.createModifyChangeSets(node);
}

//
// Handle a mismatched DBMS attribute, if necessary
//
Expand Down Expand Up @@ -976,11 +980,8 @@ public boolean include(String fileName,
this.getPreconditions().addNestedPrecondition(preconditions);
}
for (ChangeSet changeSet : changeLog.getChangeSets()) {
if (changeSet.getRunWith() == null) {
changeSet.setRunWith(modifyChangeSets != null ? modifyChangeSets.getRunWith() : null);
}
if (changeSet.getRunWithSpoolFile() == null) {
changeSet.setRunWithSpoolFile(modifyChangeSets != null ? modifyChangeSets.getRunWithSpool() : null);
if (modifyChangeSets != null) {
modifyChangeSets(modifyChangeSets, changeSet);
}
addChangeSet(changeSet);
}
Expand All @@ -989,8 +990,16 @@ public boolean include(String fileName,
return true;
}

private void modifyChangeSets(ModifyChangeSets modifyChangeSets, ChangeSet changeSet) {
ChangeSetServiceFactory factory = ChangeSetServiceFactory.getInstance();
ChangeSetService service = factory.createChangeSetService();
service.modifyChangeSets(changeSet, modifyChangeSets);
}

protected ChangeSet createChangeSet(ParsedNode node, ResourceAccessor resourceAccessor) throws ParsedNodeException {
ChangeSet changeSet = new ChangeSet(this);
ChangeSetServiceFactory factory = ChangeSetServiceFactory.getInstance();
ChangeSetService service = factory.createChangeSetService();
ChangeSet changeSet = service.createChangeSet(this);
changeSet.setChangeLogParameters(this.getChangeLogParameters());
changeSet.load(node, resourceAccessor);
return changeSet;
Expand Down Expand Up @@ -1042,32 +1051,6 @@ public void clearCheckSums() {
}
}

/**
* Container class to handle the modifyChangeSets tag.
* Other attributes may be added later
*/
private static class ModifyChangeSets {
private final String runWith;
private final String runWithSpool;

/**
* @param runWith The native executor to execute all included change sets with. Can be null
* @param runWithSpool The name of the spool file to be created
*/
public ModifyChangeSets(String runWith, String runWithSpool) {
this.runWith = runWith;
this.runWithSpool = runWithSpool;
}

public String getRunWith() {
return runWith;
}

public String getRunWithSpool() {
return runWithSpool;
}
}

/**
* Holder for the PreconditionContainer for this changelog, plus any nested changelogs.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package liquibase.changelog;

import liquibase.Scope;
import liquibase.parser.core.ParsedNode;
import liquibase.parser.core.ParsedNodeException;

/**
* Container class to handle the modifyChangeSets tag.
* Other attributes may be added later
*/
public class ModifyChangeSets {
private final String runWith;
private final String runWithSpool;

/**
*
* @param node The ParsedNode to use
*
*/
public ModifyChangeSets(ParsedNode node) throws ParsedNodeException {
this.runWith = (String) node.getChildValue(null, "runWith");
this.runWithSpool = (String) node.getChildValue(null, "runWithSpoolFile");
}

/**
*
* @param runWith The native executor to execute all included change sets with. Can be null
* @param runWithSpool The name of the spool file to be created
*
*/
public ModifyChangeSets(String runWith, String runWithSpool) {
this.runWith = runWith;
this.runWithSpool = runWithSpool;
}

public String getRunWith() {
return runWith;
}

public String getRunWithSpool() {
return runWithSpool;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package liquibase.changeset;

import liquibase.changelog.ChangeSet;
import liquibase.changelog.DatabaseChangeLog;
import liquibase.changelog.ModifyChangeSets;
import liquibase.database.ObjectQuotingStrategy;
import liquibase.parser.core.ParsedNode;
import liquibase.parser.core.ParsedNodeException;
import liquibase.plugin.Plugin;

public interface ChangeSetService extends Plugin {
Dismissed Show dismissed Hide dismissed
/**
*
* Return the plugin priority
* @return int
*
*/
int getPriority();

/**
*
* Create a change set with the indicated arguments
*
* @param id
* @param author
* @param alwaysRun
* @param runOnChange
* @param filePath
* @param contextFilter
* @param dbmsList
* @param runWith
* @param runWithSpoolFile
* @param runInTransaction
* @param quotingStrategy
* @param databaseChangeLog
* @return ChangeSet
*
*/
ChangeSet createChangeSet(String id, String author, boolean alwaysRun, boolean runOnChange,
String filePath, String contextFilter, String dbmsList,
String runWith, String runWithSpoolFile, boolean runInTransaction,
ObjectQuotingStrategy quotingStrategy, DatabaseChangeLog databaseChangeLog);

Check notice

Code scanning / CodeQL

Useless parameter Note

The parameter 'quotingStrategy' is never used.

/**
*
* Create a change set with the indicated arguments
*
* @param id
* @param author
* @param alwaysRun
* @param runOnChange
* @param filePath
* @param contextFilter
* @param dbmsList
* @param databaseChangeLog
* @return ChangeSet
*
*/
ChangeSet createChangeSet(String id, String author, boolean alwaysRun, boolean runOnChange,
String filePath, String contextFilter, String dbmsList,
DatabaseChangeLog databaseChangeLog);
/**
*
* Create a change set with the changelog
*
* @param databaseChangeLog
Fixed Show fixed Hide fixed
* @return ChangeSet
*
*/
ChangeSet createChangeSet(DatabaseChangeLog changeLog);

/**
*
* Create the ModifyChangeSets instance which will do the modifications
*
* @param node The ParsedNode that was created during load
* @return ModifyChangeSets The object which will perform the modifications
* @throws ParsedNodeException
*
*/
ModifyChangeSets createModifyChangeSets(ParsedNode node) throws ParsedNodeException;

/**
*
* Given a change set and a ModifyChangeSets instance, perform the modifications
*
* @param changeSet The change set to modify
* @param modifyChangeSets The modifier
*
*/
void modifyChangeSets(ChangeSet changeSet, ModifyChangeSets modifyChangeSets);

/**
*
* Default implementation returns null
*
* @param changeSet
* @return null
*
*/
default String getEndDelimiter(ChangeSet changeSet) {
Dismissed Show dismissed Hide dismissed
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package liquibase.changeset;

import liquibase.plugin.AbstractPluginFactory;

/**
*
* Create the appropriate ChangeSetService instance
*
*/
public class ChangeSetServiceFactory extends AbstractPluginFactory<ChangeSetService> {

private static ChangeSetServiceFactory factory = null;

private ChangeSetServiceFactory() {
}

public static ChangeSetServiceFactory getInstance() {
if (factory == null) {
factory = new ChangeSetServiceFactory();
}
return factory;
}

@Override
protected Class<ChangeSetService> getPluginClass() {
return ChangeSetService.class;
}

@Override
protected int getPriority(ChangeSetService obj, Object... args) {
return obj.getPriority();
}

public ChangeSetService createChangeSetService() {
return getPlugin();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package liquibase.changeset;

import liquibase.changelog.ChangeSet;
import liquibase.changelog.DatabaseChangeLog;
import liquibase.changelog.ModifyChangeSets;
import liquibase.database.ObjectQuotingStrategy;
import liquibase.parser.core.ParsedNode;
import liquibase.parser.core.ParsedNodeException;

/**
*
* The standard OSS implementation of the ChangeSetService
*
*/
public class StandardChangeSetService implements ChangeSetService {
@Override
public int getPriority() {
return PRIORITY_DEFAULT;
}

@Override
public ChangeSet createChangeSet(DatabaseChangeLog changeLog) {
return new ChangeSet(changeLog);
}

@Override
public ChangeSet createChangeSet(String id, String author, boolean alwaysRun, boolean runOnChange, String filePath, String contextFilter, String dbmsList, DatabaseChangeLog databaseChangeLog) {
return new ChangeSet(id, author, alwaysRun, runOnChange, filePath, contextFilter, dbmsList, null, null, true, ObjectQuotingStrategy.LEGACY, databaseChangeLog);
}

@Override
public ChangeSet createChangeSet(String id, String author, boolean alwaysRun, boolean runOnChange,
String filePath, String contextFilter, String dbmsList,
String runWith, String runWithSpoolFile, boolean runInTransaction,
ObjectQuotingStrategy quotingStrategy, DatabaseChangeLog databaseChangeLog) {
return new ChangeSet(id, author, alwaysRun, runOnChange,
DatabaseChangeLog.normalizePath(filePath),
contextFilter, dbmsList, runWith, runWithSpoolFile, runInTransaction,
databaseChangeLog.getObjectQuotingStrategy(), databaseChangeLog);
}
@Override
public ModifyChangeSets createModifyChangeSets(ParsedNode node) throws ParsedNodeException {
return new ModifyChangeSets(
(String) node.getChildValue(null, "runWith"),
(String) node.getChildValue(null, "runWithSpoolFile"));
}

@Override
public void modifyChangeSets(ChangeSet changeSet, ModifyChangeSets modifyChangeSets) {
if (changeSet.getRunWith() == null) {
changeSet.setRunWith(modifyChangeSets != null ? modifyChangeSets.getRunWith() : null);
}
if (changeSet.getRunWithSpoolFile() == null) {
changeSet.setRunWithSpoolFile(modifyChangeSets != null ? modifyChangeSets.getRunWithSpool() : null);
}
}
}