Skip to content

Instantly share code, notes, and snippets.

@evandertino
Forked from izmailoff/SchemaMigration.scala
Created January 7, 2021 07:45
Show Gist options
  • Save evandertino/872fcec57973a50616840db03fcb3973 to your computer and use it in GitHub Desktop.
Save evandertino/872fcec57973a50616840db03fcb3973 to your computer and use it in GitHub Desktop.
Liquibase for Scala
// Liquibase SBT dependency is something like this:
// "org.liquibase" % "liquibase-core" % "3.0.5"
import java.sql.Connection
import liquibase.Liquibase
import liquibase.resource.FileSystemResourceAccessor
import liquibase.database.DatabaseFactory
import liquibase.database.jvm.JdbcConnection
import liquibase.resource.ClassLoaderResourceAccessor
import net.liftweb.common.Logger
/**
* Runs Liquibase based database schema and data migrations. This is the only place for all related
* modules to run updates from.
*
* Liquibase finds its files on the classpath and applies them to DB. If migration fails
* this class will throw an exception and by default your application should not continue to run.
*
* It does not matter which module runs this migration first.
*/
class SchemaMigration extends Logger {
val masterChangeLogFile = "db/db.changelog-master.xml"
def createLiquibase(dbConnection: Connection, diffFilePath: String): Liquibase = {
val database = DatabaseFactory.getInstance.findCorrectDatabaseImplementation(new JdbcConnection(dbConnection))
val classLoader = classOf[SchemaMigration].getClassLoader
val resourceAccessor = new ClassLoaderResourceAccessor(classLoader)
new Liquibase(diffFilePath, resourceAccessor, database)
}
def updateDb(db: DbConnectionProvider, diffFilePath: String): Unit = {
val dbConnection = db.getConnection
val liquibase = createLiquibase(dbConnection, diffFilePath)
try {
liquibase.update(null)
} catch {
case e: Throwable => throw e
} finally {
liquibase.forceReleaseLocks()
dbConnection.rollback()
dbConnection.close()
}
}
def connProvider = new SomeSortOfDbConnectionProvider // just load JDBC driver and get connection if nothing else
/**
* Invoke this method to apply all DB migrations.
*/
def run(): Unit = {
val db = connProvider
info(s"Liquibase running on db: [\n$db\n]")
updateDb(db, masterChangeLogFile)
}
}
object SchemaMigration extends SchemaMigration
//---------------------------------------------------
// then invoke it like that:
SchemaMigration.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment