daniel-shuy / liquibase-slick-codegen-sbt-plugin

A SBT plugin to generate Slick database schema code from a Liquibase changelog file.

Version Matrix

liquibase-slick-codegen-sbt-plugin

Download

Branch Travis CI CodeFactor Codacy Better Code Hub
Master Build Status CodeFactor Codacy Badge BCH compliance
Develop Build Status CodeFactor Codacy Badge BCH compliance
Plugin Version SBT Version Slick Version sbt-liquibase Version Liquibase Version
1.0.x 0.13.x, 1.x.x 3.x.x 1.1.0 3.6.1+
1.1.x 0.13.x, 1.x.x 3.x.x 1.2.0 3.8.0+

A SBT plugin that uses sbt-liquibase and Slick Codegen to generate Slick database schema code from a Liquibase changelog file.

The database schema code is generated in the Source folder (because the generated Slick database schema code should be under version control), in the configured package, with the configured class name.

The plugin attaches itself to the compile phase, and will run before the compilation takes place (the generated Slick database schema code will be compiled as well). It is skipped on subsequent runs if the Liquibase changelog file hasn't been modified, and the Slick database schema code file hasn't been deleted.

Warning: This plugin currently depends on an experimental feature in Slick Codegen. This plugin uses the H2 Database to generate the Slick database schema code. Currently, using a different database profile from the one used to generate the database schema code is considered experimental and is not officially supported by Slick (see http://slick.lightbend.com/doc/3.0.0/code-generation.html#generated-code for more information).

Limitations

Because the plugin uses the Liquibase changelog file to create tables in a temporary H2 database, there are some limitations when configuring the Liquibase changelog file. If possible, avoid using them. If not, refer below for the workarounds. Make sure to test the generated Slick database schema code thoroughly.

The Liquibase version must be 3.6.1 or above, due to sbt-liquibase.

Database-specific Preconditions

If a \ precondition with a database other than H2 is used, add <dbms type="h2" /> as well.

Unsupported Changes

If a change that isn't supported by H2 (eg. \) is used, add corresponding SQL or a combination of changes to achieve the same result, with the <dbms type="h2" /> precondition.

Eg. for <renameView>, use \ and \ to achieve the same result.

Database-specific SQL

If database-specific SQL is used with \, add a \ precondition to limit it to the database type that supports it, then add corresponding SQL for H2 that achieves the same result in a <sql> change, with the <dbms type="h2" /> precondition.

Usage

Step 1: Include the plugin in your build

Add the following to your project/plugins.sbt:

addSbtPlugin("com.github.daniel-shuy" % "sbt-liquibase-slick-codegen" % "1.0.1")

Override the slick-codegen dependency version with the version of Slick you are using in your project. The dependency version can be extracted out into a Scala object in the project folder to allow it to be referenced in both project/plugins.sbt and build.sbt (there are many ways to do this), eg.

// project/project/Dependencies.scala
import sbt._

object Dependencies {
  def slickVersion(scalaVersion: String): String =
    CrossVersion.partialVersion(scalaVersion) match {
      case Some((2, 10)) => "3.1.1"
      case Some((2, 11)) | Some((2, 12)) => "3.2.3"
      case _ =>
        throw new IllegalArgumentException(s"Unsupported Scala version $scalaVersion")
    }
}
// project/plugins.sbt
addSbtPlugin("com.github.daniel-shuy" % "sbt-liquibase-slick-codegen" % "1.0.1")
libraryDependencies += "com.typesafe.slick" %% "slick-codegen" % Dependencies.slickVersion(scalaVersion.value)

// allows build.sbt to reference Dependencies
unmanagedSourceDirectories in Compile += (baseDirectory in Compile).value / "project"
// build.sbt
libraryDependencies ++= Seq(
  "com.typesafe.slick" %% "slick" % Dependencies.slickVersion(scalaVersion.value),
  // ...
)

Override the liquibase-core dependency version with the version of Liquibase you wise to use:

addSbtPlugin("com.github.daniel-shuy" % "sbt-liquibase-slick-codegen" % "1.0.1")
libraryDependencies += "org.liquibase" % "liquibase-core" % "3.6.3"

Step 2: Enable the plugin for your project

Add the following to your build.sbt:

enablePlugins(SbtLiquibaseSlickCodegen)

Step 3: Create the Liquibase changelog file

See http://www.liquibase.org/documentation/databasechangelog.html

Step 4: Configure project settings for the plugin

See Settings.

Minimal example:

enablePlugins(SbtLiquibaseSlickCodegen)

liquibaseSlickCodegenOutputPackage := "com.foo.bar"
liquibaseSlickCodegenOutputClass := "Tables"

This will create the Slick database schema code as com.foo.bar.Tables.scala

Step 5: Execute the plugin

Run sbt compile or sbt liquibaseSlickCodegen to generate the Slick database schema code.

Settings

Setting Type Description
liquibaseChangelog File Optional. Your Liquibase changelog file. Defaults to src/main/migrations/changelog.xml.
liquibaseSlickCodegenOutputPackage String Required. Package the generated Slick database schema code should be created in.
liquibaseSlickCodegenOutputClass String Optional. The class name for the generated Slick database schema code, without the .scala extension. Defaults to Tables.
liquibaseSlickCodegenProfile JdbcProfile Optional. The Slick database profile for the generated Slick database schema code. This should be substituted with the Slick driver implementation for the database you intend to use. Defaults to slick.driver.H2Driver.
liquibaseSlickCodegenSourceGeneratorFactory Model => SourceCodeGenerator Optional. The factory for the SourceCodeGenerator implementation. See Slick Codegen customization. Defaults to the bundled SourceCodeGenerator.

Tasks

Task Description
liquibaseSlickCodegen Forces the plugin to run, regardless of whether the Liquibase changelog file has been modified, or the Slick database schema code file exists.

Notes

sbt-liquibase

A project that enables the SbtLiquibaseSlickCodegen plugin automatically enables the SbtLiquibase plugin as well.

The sbt-liquibase plugin can still be used as normal alongside sbt-liquibase-slick-codegen.

Note that the liquibaseChangelog setting is shared among both plugins.

This plugin used to depend on sbtliquibase/sbt-liquibase-plugin, but has been changed to depend on permutive/sbt-liquibase (a fork of sbtliquibase/sbt-liquibase-plugin) since version 1.0.0, in order to support SBT 1.0.

Play Framework

When using this plugin with Play Framework, remember to configure liquibaseChangelog to point to the correct path, eg.

liquibaseChangelog := file("conf/migrations/changelog.xml")

Since we are using Liquibase instead of Play Slick Evolutions for Database Migration, it is recommended to use Slick standalone, instead of the play-slick module, so that you are not bound to the version of Slick supported by play-slick.

Multiple Liquibase changelog files

You can have multiple Liquibase changelog files, then include all of them in a "master" changelog file, then configure liquibaseChangelog to point to it.

Slick Codegen customization

You can still perform Slick Codegen customizations with this plugin.

Create a class in project that extends com.github.daniel.shuy.liquibase.slick.codegen.SourceCodeGenerator, then override methods to customize Slick Codegen's behavior, eg.

project/CustomSourceCodeGenerator.scala:

import com.github.daniel.shuy.liquibase.slick.codegen.SourceCodeGenerator
import slick.model.Model

class CustomSourceCodeGenerator(model: Model) extends SourceCodeGenerator(model) {
    // override def ...

then in build.sbt, assign the constructor as the liquibaseSlickCodegenSourceCodeGeneratorFactory, eg.

liquibaseSlickCodegenSourceCodeGeneratorFactory := (model => new CustomSourceCodeGenerator(model))