ReleaseDate extension

Overview

Summary

Enables users to add a releaseDate to each ChangeSet for processing in a installer.

Current Version

1.0.1

Author

Michael Oberwasserlechner

Source

Attached to page

Supported Databases

Should work for all

Liquibase SupportSupports Liquibase 2.0.x. Incompatible with Liquibase 3.0+

Purpose

I use Hibernate as OR-Mapping Framework. While developing a installer and later a in-application upgrader I wanted that the installer should only use the hibernate mapping and only the upgrader should execute the liquibase ChangeSets.

After running the installer I have no information which ChangeSet was already installed by the installer and which one is a real new change coming from a new feature, which was develop after the installer finished.

Usage

Use this extension once per changeset to keep better control over your release cycle and display both to yourself or your installer/updater, which changeSets are already run and which onces are already installed because the date of installation is before the changesets release date.

For other execution methods like LoggingExecutor the release date is included in a sql comment.

Example:

<databaseChangeLog
    xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
    xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd
    http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">

  <changeSet id="create_data_language" author="michael">
    <ext:releaseDate releasedOn="2010-11-30" />

    <createTable tableName="DATA_LANGUAGE" remarks="This table stores the data language definitions.">
      <column name="ID" type="NUMBER(10)">
        <constraints primaryKeyName="PK_DATA_LANGUAGE" primaryKey="true"/>
      </column>
      <column name="ISO_CODE" type="VARCHAR(10)" >
        <constraints nullable="false" unique="true"/>
      </column>
    </createTable>
  </changeSet>

</databaseChangeLog>

XSD:

<?xml version="1.0" encoding="UTF-8"?>

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  targetNamespace="http://www.liquibase.org/xml/ns/dbchangelog-ext"
  xmlns="http://www.liquibase.org/xml/ns/dbchangelog-ext"
  elementFormDefault="qualified">

  <xsd:element name="releaseDate">
    <xsd:complexType>
      <xsd:attribute name="releasedOn" type="xsd:string" use="required" />
      <xsd:attribute name="commentText" type="xsd:string" />
      <xsd:attribute name="parsePattern" type="xsd:string" default="yyyy-MM-dd"/>
      <xsd:attribute name="formatPattern" type="xsd:string" default="MMMMM dd, yyyy" />
    </xsd:complexType>
  </xsd:element>

</xsd:schema>

I process this extension by code within a ReleaseDateChangeSetFilter, which is included in the jar. See the example below.

    Database liquiBaseDatabase = getLiquiBaseDatabase();
    if (liquiBaseDatabase != null) {
      try {

        // create the changeSet filters
        List<ChangeSetFilter> changeSetFilters = new ArrayList<ChangeSetFilter>();

        InstallationStatus installationStatus = this.installationValidationService.getInstallationStatus();
        // ReleaseDateChangeSetFilter - only accepts changeSets witch are released after
        filter.add(new ReleaseDateChangeSetFilter(installationStatus.getFinishedOn()));

        // some other filters
        try {
          filter.add(new ShouldRunChangeSetFilter(liquiBaseDatabase));
        }
        catch (DatabaseException e) {
          logger.warn("Init of ShouldRunChangeSetFilter failed because of:", e);
        }

        filter.add(new ContextChangeSetFilter("production"));
        filter.add(new DbmsChangeSetFilter(liquiBaseDatabase));

        ChangeLogParameters parameters = new ChangeLogParameters(liquiBaseDatabase);

        // parse the changelog file
        ChangeLogParser parser = ChangeLogParserFactory.getInstance().getParser(changelogFileName, resourceAccessor);
        DatabaseChangeLog databaseChangeLog = parser.parse(changelogFileName, parameters, resourceAccessor);

        Iterator<ChangeSet> changeSetIterator = databaseChangeLog.getChangeSets().iterator();
        while (changeSetIterator.hasNext()) {
          ChangeSet changeSet = changeSetIterator.next();
          boolean removeChangeSet = false;
          // ### ChangeSetFilter ###
          if (changeSetFilters != null) {
            for (ChangeSetFilter filter : changeSetFilters) {
              if (!filter.accepts(changeSet)) {
                logger.debug("ChangeSetFilter {} does not accept changeset!", filter);
                removeChangeSet = true;
                break;
              }
            }// for (filters)
          }

          if (removeChangeSet) {
            changeSetIterator.remove();
          }
        } //while
        return databaseChangeLog;
      } catch (LiquibaseException e) {
        logger.error("", e);
      }
    }

Files

  File Modified

Java Archive liquibase-releasedate-1.0.0.jar

Feb 13, 2011 by Michael Oberwasserlechner

Java Archive liquibase-releasedate-1.0.1.jar

Apr 19, 2011 by Michael Oberwasserlechner

ZIP Archive liquibase-releasedate-1.0.1.src.zip

Oct 14, 2013 by Nathan Voxland