Bootstrap Liquibase in your Grails app

Grails has had a liquibase plugin for a long time (note: I am talking about the old liquibase plugin based on 1.9). One functionality that (I feel) it's missing is a proper Bootstrap hook so that database changes can be deployed right when the application starts. The newest liquibase plugin called grails database migration has it built in.



This is especially handy when running integration tests as the database can be brought up-to-date without calling any grails script, but will run from within the application as it starts up instead.

I use the liquibase plugin with the XML changelog format, to maximize compatibility, and I have now decided that I have had enough of running grails scripts whenever I change something. Well, actually, I have had enough of having to remember to run it.

So I'd like to share with you my Bootstrap code with liquibase plugin integration. If running liquibase in production automatically makes you nervous you can leave it out (use an if, or a separate section).

import org.mappu.*
import org.codehaus.groovy.grails.commons.ApplicationHolder
import liquibase.*
import liquibase.util.NetUtil
import liquibase.database.DatabaseFactory;
import grails.util.Environment
class BootStrap {
def dataSource
def init = { servletContext ->
/****************************************
*
* Update database schema.
*
****************************************/
println "Liquibase: checking schema update, context="+Environment.current.toString()
FileOpener clFO = new ClassLoaderFileOpener();
FileOpener fsFO = new FileSystemFileOpener();
// following code detects the changelog path in both war and cmdline environments
// works with grails 1.3.6 and apache tomcat YMMV, expecially with other containers
String changelog = ApplicationHolder.application.parentContext.servletContext.getRealPath("/WEB-INF/changelog.xml")
def changelogFile = new File(changelog)
if( ! changelogFile.exists() ) {
changelog="grails-app/migrations/changelog.xml"
}
Liquibase liquibase = new Liquibase(
changelog,
new CompositeFileOpener(clFO,fsFO),
DatabaseFactory.getInstance().findCorrectDatabaseImplementation(dataSource.getConnection())
);
liquibase.update(Environment.current.toString());
println "Liquibase: checking schema update completeted"
/****************************************
*
* Done.
*
****************************************/
}
def destroy = {
}
}

Popular posts

Mirth: recover space when mirthdb grows out of control

1/4/2000 to 1/4/2025: the beginning

From 0 to ZFS replication in 5m with syncoid