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

Liquibase offline mode doesn't support rollbackSQL <tag> operation #2219

Closed
msimko81 opened this issue Nov 17, 2021 · 4 comments · Fixed by #2222
Closed

Liquibase offline mode doesn't support rollbackSQL <tag> operation #2219

msimko81 opened this issue Nov 17, 2021 · 4 comments · Fixed by #2222

Comments

@msimko81
Copy link

msimko81 commented Nov 17, 2021

Environment

Liquibase Version:
4.6.1 (but also affecting previous versions)
Liquibase Integration & Version:
CLI & Java API
Database Vendor & Version:
MS SQL Server (but also affecting others)
Operating System Type & Version:
Ubuntu Linux (but also affecting others)

Description

The liquibase offline mode doesn't support rollbackSQL <tag> functionality. The reason is the tag value is not persisted in the databasechangelog.csv as a result of updateSQL operation. The tag column only contains empty values, also for changeset containing tagDatabase command.

Steps To Reproduce

Assume the following changelog.xml:

<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.6.xsd">
    <changeSet id="create-table-sample" author="miro">
        <createTable tableName="sample">
            <column name="id" type="uniqueidentifier">
                <constraints nullable="false"/>
            </column>
            <column name="data" type="varchar(255)"/>
        </createTable>
    </changeSet>
    <changeSet id="release-1.0" author="miro">
        <tagDatabase tag="1.0"/>
    </changeSet>
</databaseChangeLog>
  1. apply the above changelog using the offline mode: liquibase --changeLogFile=changelog.xml --url=offline:mssql updateSQL
  2. try to perform rollbackSQL <tag> operation: liquibase --changeLogFile=changelog.xml --url=offline:mssql rollbackSQL 1.0

Actual Behavior

  1. The first step produces liquibasechangelog.csv with two entries. The second one, with id release-1.0, contains empty tag. However, the tag of this entry shall be 1.0 (as is the state of the database table in corresponding online mode case).
  2. The rollbackSQL operation fails with the error message: Unexpected error running Liquibase: Could not find tag '1.0' in the database.

Note: if I manually change the CSV file generated by the first step and specify the tag for the second entry (to mimic the online mode behaviour), the second operation is successful and behaves as expected.

Expected/Desired Behavior

The tag value shall be populated in offline mode (i.e. present in liquibasechangelog.csv) in order to enable rollbackSQL <tag> operation.

Additional Context

The problem has been reported several times, but no answer up to date.
See e.g.
https://forum.liquibase.org/t/how-to-generate-a-sql-file-with-rollbacksql-with-offline-mode/3283
https://forum.liquibase.org/t/not-able-to-generate-rollback-scripts-by-tag-in-offline-mode/3909

@msimko81 msimko81 changed the title Liquibase offline mode doesn't support rollback tag Liquibase offline mode doesn't support rollbackSQL <tag> operation Nov 17, 2021
@msimko81
Copy link
Author

msimko81 commented Nov 17, 2021

I dug to the source code. Here is a proposed quick fix (the required functionality was copied from MarkChangeSetRanGenerator and slightly changed):

Index: liquibase/changelog/OfflineChangeLogHistoryService.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/liquibase/changelog/OfflineChangeLogHistoryService.java b/liquibase/changelog/OfflineChangeLogHistoryService.java
--- a/liquibase/changelog/OfflineChangeLogHistoryService.java	
+++ b/liquibase/changelog/OfflineChangeLogHistoryService.java	(date 1637162835865)
@@ -3,7 +3,9 @@
import liquibase.ContextExpression;
import liquibase.Labels;
import liquibase.Scope;
+import liquibase.change.Change;
import liquibase.change.CheckSum;
+import liquibase.change.core.TagDatabaseChange;
import liquibase.changelog.ChangeSet.ExecType;
import liquibase.GlobalConfiguration;
import liquibase.database.Database;
@@ -244,6 +246,14 @@
                csvWriter.writeNext(line);
            }

+            String tag = "";
+            for (Change change : changeSet.getChanges()) {
+                if (change instanceof TagDatabaseChange) {
+                    TagDatabaseChange tagChange = (TagDatabaseChange) change;
+                    tag = tagChange.getTag();
+                }
+            }
+
            String[] newLine = new String[Columns.values().length];
            newLine[Columns.ID.ordinal()] = changeSet.getId();
            newLine[Columns.AUTHOR.ordinal()] = changeSet.getAuthor();
@@ -254,7 +264,7 @@
            newLine[Columns.MD5SUM.ordinal()] = changeSet.generateCheckSum().toString();
            newLine[Columns.DESCRIPTION.ordinal()] = changeSet.getDescription();
            newLine[Columns.COMMENTS.ordinal()] = changeSet.getComments();
-            newLine[Columns.TAG.ordinal()] = "";
+            newLine[Columns.TAG.ordinal()] = tag;
            newLine[Columns.LIQUIBASE.ordinal()] = LiquibaseUtil.getBuildVersion().replaceAll("SNAPSHOT", "SNP");

            newLine[Columns.CONTEXTS.ordinal()] = (changeSet.getContexts() == null) ? null : changeSet.getContexts().toString();

msimko81 pushed a commit to msimko81/liquibase that referenced this issue Nov 17, 2021
Fix for the `OfflineChangeLogHistoryService` - populate tag to the changelog.

liquibase#2219
@msimko81
Copy link
Author

Opened pull request: #2222

@molivasdat
Copy link
Contributor

Hi @msimko81 Thanks for alerting us to this issue. And thanks for creating a fix for it. We will add this to the list of issues that we are processing.

@molivasdat molivasdat added this to To Do in Conditioning++ via automation Nov 30, 2021
@nvoxland nvoxland moved this from To Do to Code Review in Conditioning++ Dec 22, 2021
@suryaaki2 suryaaki2 moved this from Code Review to Ready for Handoff (In JIRA) in Conditioning++ Dec 28, 2021
@yodzhubeiskyi
Copy link
Contributor

Fixed by #2222

Conditioning++ automation moved this from Ready for Handoff (In JIRA) to Done Feb 14, 2022
@nvoxland nvoxland added this to the v4.8.0 milestone Feb 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Development

Successfully merging a pull request may close this issue.

4 participants