Automatically applying Liquibase changesets to HSQL
This is a quick tip for usage of Liquibase with HSQL. You may use the former tool for relational database schema migrations and the latter as in-memory database on the developers’ machines. Today, with feature branches and project customisation, i.e. changes that are specific for a single customer, you may have to shutdown the database, restart and reapply the migrations on a regular basis. Of course, this is a task that can be automated!
Typical situation: you are working on the project’s main development branch, but you now wish to review a colleague’s new feature, which has been developed in a feature branch. You switch to the feature branch, start the server, open the application and BAM, an exception occurs due a failed schema validation. The reason: your colleague made some schema changes in the feature branch that you forgot to apply.
Improving your Liquibase and HSQL workflow is rather simple: restart the database whenever the schema changes and apply the migrations! This is how you can do it in bash (sorry Windows users).
#!/bin/bash
set -e
HSQL_PID=""
PROJECT=""
if [[ $1 = "customisation" ]]; then
echo "Using customer specific changelogs..."
PROJECT="$PROJECT_REPO/customisation"
else
echo "Using default changelogs..."
PROJECT="$PROJECT_REPO/database"
fi
control_c() {
kill $HSQL_PID
exit
}
trap control_c SIGHUP SIGINT SIGTERM 0
start() {
# Start HSQL
java -cp "$M2_REPO/org/hsqldb/hsqldb/2.2.9/hsqldb-2.2.9.jar" \
org.hsqldb.Server \
-database.0 mem:myDB \
-dbname.0 myDB &
HSQL_PID=$!
# Schema update
mvn -f "$PROJECT/pom.xml" liquibase:update -Plocal --no-snapshot-updates
}
start
while true; do
if hash inotifywait 2>/dev/null; then
WATCH_DIR="$PROJECT/src/changelogs"
echo "Watching $WATCH_DIR for changes..."
# Wait for changelog changes
inotifywait --recursive $WATCH_DIR \
--event modify \
--event move \
--event create \
--event delete
# Just a precaution: wait until the VCS is done changing the branch
sleep 1
else
echo "[Press any key to discard the schema and apply a new one...]"
read
fi
# kill HSQL and wait until it is actually shut down
kill $HSQL_PID
while kill -0 "$HSQL_PID"; do
sleep 0.1
done
start
done
You need to make sure that you have two environment variables setup. There should be a variable PROJECTREPO which points to the root directory of your project’s repository and M2REPO which points to the Maven repository. You may also need to tweak a few paths, e.g. the version of HSQL that you are using as well as the Maven project and profile names. At last, you should install the inotify-tools (unfortunately not available on OS X). inotifywait (part of the inotify-tools) is used to watch the changelog directory for changes. The project’s Wiki has a section on installation.
Once setup, usage is pretty easy: start the script and let it do the rest. When the inotify-tools are not installed, you need to switch to your terminal and hit “the any key” in order to discard the current and apply a new schema.