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

generateChangelog optionally creates runOnChange=true and replaceIfExists=true for createView changes #4635

Merged
merged 33 commits into from
Dec 20, 2023

Conversation

mkarg
Copy link
Contributor

@mkarg mkarg commented Aug 9, 2023

Closes #4634

Impact

  • Bug fix (non-breaking change which fixes expected existing functionality)
  • Enhancement/New feature (adds functionality without impacting existing logic)
  • Breaking change (fix or feature that would cause existing functionality to change)

Description

This PR introduces two new options:

  • --run-on-change-types=createView,createProcedure will set runOnChange="true" for each changeSet which contains solely createView and createProcedure changes. For backwards compatibility, the default is an empty list.
  • --replace-if-exists=createView,createProcedure will set replaceIfExists="true" for each createView and createProcedure change. For backwards compatibility, the default is an empty list.

Things to be aware of

N/A

Things to worry about

N/A

Additional Context

N/A

…aceIfExists=true for createView changes

Comma-separated list of change types instead of true/false allows to specify createProcedure besides createView
@mkarg
Copy link
Contributor Author

mkarg commented Aug 10, 2023

Converted to draft to further improve this PR. Finished PR.

…aceIfExists=true for createView changes

New interface ReplaceIfExists instead of list of distinct classes
…aceIfExists=true for createView changes

New interface ReplaceIfExists removes the need for if-instanceof.
…aceIfExists=true for createView changes

Dynamically detects available implementations of ReplaceIfExists.
…aceIfExists=true for createView changes

Validating --replace-if-exists-types and --run-on-change-types
@mkarg mkarg marked this pull request as ready for review August 10, 2023 14:53
@MalloD12 MalloD12 self-requested a review August 23, 2023 20:44
@MalloD12 MalloD12 added sprint2023-58 SafeToBuild Indicates that a particular PR contains changes which are safe to build using GitHub actions labels Aug 23, 2023
@MalloD12 MalloD12 changed the base branch from master to 3.3.x August 23, 2023 21:18
@MalloD12 MalloD12 changed the base branch from 3.3.x to master August 23, 2023 21:18
@filipelautert filipelautert added SafeToBuild Indicates that a particular PR contains changes which are safe to build using GitHub actions and removed SafeToBuild Indicates that a particular PR contains changes which are safe to build using GitHub actions labels Aug 29, 2023
@MalloD12
Copy link
Contributor

Hi @mkarg,

I left two review comments (one it's a very minor thing, though). Could you please look at them?

I was planning to add some integration test to do something like this:

def "Ensure generate changelog set runOnChange and replaceIfExists properties correctly"() {
        given:
        CommandUtil.runUpdate(mysql,"src/test/resources/changelogs/mysql/complete/view.procedure.changelog.xml")

        CommandScope commandScope = new CommandScope(GenerateChangelogCommandStep.COMMAND_NAME)
        commandScope.addArgumentValue(DbUrlConnectionCommandStep.URL_ARG, mysql.getConnectionUrl())
        commandScope.addArgumentValue(DbUrlConnectionCommandStep.USERNAME_ARG, mysql.getUsername())
        commandScope.addArgumentValue(DbUrlConnectionCommandStep.PASSWORD_ARG, mysql.getPassword())
        commandScope.addArgumentValue(GenerateChangelogCommandStep.REPLACEIFEXISTS_TYPES_ARG, "createView")
        commandScope.addArgumentValue(GenerateChangelogCommandStep.RUNONCHANGE_TYPES_ARG, "createView")

        OutputStream outputStream = new ByteArrayOutputStream()
        commandScope.setOutput(outputStream)

        when:
        commandScope.execute()

        then:
        def outputContent = outputStream.toString();
        outputContent.contains(" runOnChange=\"true\">")
        outputContent.contains(" replaceIfExists=\"true\"")

        cleanup:
        CommandUtil.runDropAll(mysql)
}

for which probably better to use String.matches() and use a regular expression to look for the runOnChange on the changeset tag and replaceIfExists in the createView (or createProcedure) tag.

@mkarg
Copy link
Contributor Author

mkarg commented Aug 29, 2023

@MalloD12 I am PTO this week and look into this next week.

@MalloD12
Copy link
Contributor

MalloD12 commented Sep 6, 2023

Hi @mkarg,

Have you had a chance to look at my comments?

Thanks,
Daniel.

@MalloD12 MalloD12 added SafeToBuild Indicates that a particular PR contains changes which are safe to build using GitHub actions and removed SafeToBuild Indicates that a particular PR contains changes which are safe to build using GitHub actions labels Dec 12, 2023
@tati-qalified
Copy link
Contributor

I've manually tested this PR, using both --replace-if-exists-types=createView,createProcedure and --run-on-change-types=createView,createProcedure and all combinations of the following:

  • Database
    • PostgreSQL
    • MySQL
    • DB2
    • Oracle
  • Changelog file type
    • xml
    • yml
    • sql
    • json
  • Command
    • generate-changelog
    • diff-changelog

The point of this was to try being as thorough as possible, with some of the most widely used databases.

Here are the results:

It works as expected for file types xml, yml and json, for all 4 tested databases and both commands.

There are some problems with the sql files for all 4 databases. I'll specify them below.

All databases
None of the changesets are decorated with runOnChange=true, both for generate-changelog and for diff-changelog

PostgreSQL, Oracle, MySQL
The create procedure changesets are created as follows (with the correct SQL syntax for each database):

-- changeset tfernandez:1702560678224-5 splitStatements:true
DROP PROCEDURE IF EXISTS "procedure1";
CREATE OR REPLACE PROCEDURE public.procedure1()
 LANGUAGE plpgsql
AS $procedure$
	BEGIN
		insert into public.entities (id, name) values (1, 'two');
	END;
$procedure$;

The statement DROP PROCEDURE IF EXISTS shouldn't be there. This is true when running either command.

Oracle
Running generate-changelog generates the CREATE VIEW changeset as CREATE OR REPLACE FORCE VIEW "NEWVIEW" ("A") AS SELECT 1 AS A FROM DUAL;.
Running diff-changelog generates it as CREATE OR REPLACE FORCE VIEW NEWVIEW (A) AS SELECT 1 AS A FROM DUAL;.
Note that one uses quotes for the view name and the other one doesn't. Both statements are correct, but this behaviour should be consistent.

PostgreSQL
The CREATE VIEW changesets are generated as follows:

DROP VIEW IF EXISTS "newview";
CREATE VIEW "newview" AS SELECT id,  name
   FROM entities;

The DROP VIEW IF EXISTS statement shouldn't be there. This happens when running either command.


That's all I found. Let me know if there is anything else I can help with.

@filipelautert
Copy link
Collaborator

@MalloD12 can you review @tati-qalified comments? thanks!

@MalloD12
Copy link
Contributor

Thanks @tati-qalified for your very detailed testing. I think these "issues"/inconsistencies are not because of these changes. For example, in the case of runOnChange property looking into CreateViewGenerator or CreateProcedureGenerator we can see none of them have support for runOnChangeand I think that's why we don't see it when generating a SQL output.

Regarding the "drop procedure" statement you are right it shouldn't be there, but again this is an existent piece in the code I would recommend similarly to the previous finding to deal with in a separate issue.

I think the same applies to the other findings.

Again, I would recommend dealing with each of these findings separately, so we don't keep this ticket on hold more time since these findings haven't been introduced with this PR.

What do you think @filipelautert - @rberezen - @tati-qalified?

Thanks,
Daniel.

@rberezen
Copy link
Contributor

@MalloD12, I agree with you on creating a separate issue for the problems described

@tati-qalified
Copy link
Contributor

Sounds good to me

@filipelautert
Copy link
Collaborator

@MalloD12 could you fix the conflicts?
@rberezen could you please finish the review?

# Conflicts:
#	liquibase-integration-tests/src/test/groovy/liquibase/command/core/GenerateChangeLogMySQLIntegrationTest.groovy
#	liquibase-integration-tests/src/test/groovy/liquibase/diffchangelog/DiffChangelogIntegrationTest.groovy
#	liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseDatabaseDiff.java
#	liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseGenerateChangeLogMojo.java
#	liquibase-standard/src/main/java/liquibase/change/ReplaceIfExists.java
#	liquibase-standard/src/main/java/liquibase/command/core/DiffChangelogCommandStep.java
#	liquibase-standard/src/main/java/liquibase/command/core/GenerateChangelogCommandStep.java
#	liquibase-standard/src/main/java/liquibase/integration/commandline/CommandLineUtils.java
@MalloD12
Copy link
Contributor

@MalloD12 could you fix the conflicts? @rberezen could you please finish the review?

@filipelautert done!

@filipelautert filipelautert added this to the 1NEXT milestone Dec 20, 2023
@filipelautert filipelautert merged commit dedd064 into liquibase:master Dec 20, 2023
29 of 30 checks passed
@adrian-velonis1
Copy link
Contributor

Internal documentation ticket: https://datical.atlassian.net/browse/PD-4098

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
DBSQLAnywhere DocNeeded SafeToBuild Indicates that a particular PR contains changes which are safe to build using GitHub actions sprint2023-58 TypeEnhancement
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

generateChangelog should optionally create runOnChange=true and replaceIfExists=true for createView changes
7 participants