Versioning

Iciql supports an optional, simple versioning mechanism. There are two parts to the mechanism.

  1. You must supply an implementation of com.iciql.DbUpgrader to your com.iciql.Db instance.
  2. One or more of your table model classes must specify the IQVersion(version) annotation

    AND/OR

    Your com.iciql.DbUpgrader implementation must specify the IQVersion(version) annotation

How does it work?#

If you choose to use versioning, iciql will maintain a table within your database named iq_versions which is defined as:

CREATE TABLE IQ_VERSIONS(SCHEMANAME VARCHAR(255) NOT NULL, TABLENAME VARCHAR(255) NOT NULL, VERSION INT NOT NULL)

This database table is automatically created if and only if at least one of your model classes specifies a version > 0.

When you generate a statement, iciql will compare the annotated version field of your model class to its last known value in the iq_versions table. If iq_versions lags behind the model annotation, iciql will immediately call the registered com.iciql.DbUpgrader implementation before generating and executing the current statement.

When an upgrade scenario is identified, the current version and the annotated version information is passed to either:

  • DbUpgrader.upgradeDatabase(db, fromVersion, toVersion)
  • DbUpgrader.upgradeTable(db, schema, table, fromVersion, toVersion)

both of which allow for non-linear upgrades. If the upgrade method call is successful and returns true, iciql will update the iq_versions table with the annotated version number.

The actual upgrade procedure is beyond the scope of iciql and is your responsibility to implement. This is simply a mechanism to automatically identify when an upgrade is necessary.

Note

The database entry of the iq_versions table is specified as SCHEMANAME=’‘ and TABLENAME=’‘.

Effective use of Versioning with a DAO#

When Iciql identifies that a version upgrade is necessary it will call the appropriate method and give you a Db instance. With the Db instance you may open a version-specific DAO instance that could give you a clean way to define all your upgrade commands.

public interface V2Upgrade extends Dao {

    @SqlStatement("ALTER TABLE PRODUCT ADD COLUMN TEST INT DEFAULT 0")
    void updateProductTable();

    @SqlStatement("UPDATE PRODUCT SET CATEGORY = :new WHERE CATEGORY = :old")
    void renameCategory(@Bind("old") String oldName, @Bind("new") String newName);
}

public class MyUpgrader implements DbUpgrader {

    public boolean upgradeDatabase(Db db, int fromVersion, int toVersion) {

        if (2 == toVersion) {
            V2Upgrade dao = db.open(V2Upgrade.class);
            dao.updateProductTable();
            dao.renameCategory("Condiments", "Dressings");
            return true;
        }

        return false;
    }