mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-07 05:55:51 +01:00
Test of automatic schema update.
This commit is contained in:
11
src/main/resources/migration/1_0.sql
Normal file
11
src/main/resources/migration/1_0.sql
Normal file
@@ -0,0 +1,11 @@
|
||||
-- Test Script for Database Migration
|
||||
CREATE TABLE ACCOUNT (
|
||||
USER_ID INT PRIMARY KEY,
|
||||
USER_NAME VARCHAR(100) NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE PROJECT (
|
||||
PROJECT_ID INT PRIMARY KEY,
|
||||
PROJECT_NAME VARCHAR(100) NOT NULL
|
||||
);
|
||||
|
||||
102
src/main/scala/util/AutoUpdate.scala
Normal file
102
src/main/scala/util/AutoUpdate.scala
Normal file
@@ -0,0 +1,102 @@
|
||||
package util
|
||||
|
||||
import java.io.File
|
||||
import java.sql.Connection
|
||||
import org.apache.commons.io.FileUtils
|
||||
import javax.servlet.ServletContextEvent
|
||||
import org.apache.commons.io.IOUtils
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
object AutoUpdate {
|
||||
|
||||
case class Version(majorVersion: Int, minorVersion: Int){
|
||||
|
||||
val logger = LoggerFactory.getLogger(classOf[Version])
|
||||
|
||||
def update(conn: Connection): Unit = {
|
||||
val sqlPath = "update/%d.%d.sq".format(majorVersion, minorVersion)
|
||||
val in = Thread.currentThread.getContextClassLoader.getResourceAsStream(sqlPath)
|
||||
if(in != null){
|
||||
val sql = IOUtils.toString(in)
|
||||
val stmt = conn.createStatement()
|
||||
try {
|
||||
logger.debug(sqlPath + "=" + sql)
|
||||
stmt.executeUpdate(sql)
|
||||
} finally {
|
||||
stmt.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val versionString = "%d.%d".format(majorVersion, minorVersion)
|
||||
}
|
||||
|
||||
/**
|
||||
* The history of versions. A head of this sequence is the current BitBucket version.
|
||||
*/
|
||||
val versions = Seq(
|
||||
Version(1, 0)
|
||||
)
|
||||
|
||||
/**
|
||||
* The head version of BitBucket.
|
||||
*/
|
||||
val headVersion = versions.head
|
||||
|
||||
/**
|
||||
* The version file (GITBUCKET_HOME/version).
|
||||
*/
|
||||
val versionFile = new File(Directory.GitBucketHome, "version")
|
||||
|
||||
/**
|
||||
* Returns the current version from the version file.
|
||||
*/
|
||||
def getCurrentVersion(): Version = {
|
||||
if(versionFile.exists){
|
||||
FileUtils.readFileToString(versionFile).split(".") match {
|
||||
case Array(majorVersion, minorVersion) => {
|
||||
versions.find { v => v.majorVersion == majorVersion.toInt && v.minorVersion == minorVersion.toInt }.get
|
||||
}
|
||||
case _ => Version(0, 0)
|
||||
}
|
||||
} else {
|
||||
Version(0, 0)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Start H2 database and update schema automatically.
|
||||
*/
|
||||
class AutoUpdateListener extends org.h2.server.web.DbStarter {
|
||||
import AutoUpdate._
|
||||
val logger = LoggerFactory.getLogger(classOf[AutoUpdateListener])
|
||||
|
||||
override def contextInitialized(event: ServletContextEvent): Unit = {
|
||||
super.contextInitialized(event)
|
||||
logger.debug("H2 started")
|
||||
|
||||
logger.debug("Start migration")
|
||||
val conn = getConnection()
|
||||
try {
|
||||
val currentVersion = getCurrentVersion()
|
||||
|
||||
versions.takeWhile(_ != currentVersion).reverse.foreach(_.update(conn))
|
||||
FileUtils.writeStringToFile(versionFile, headVersion.majorVersion + "." + headVersion.minorVersion)
|
||||
|
||||
logger.debug("Migrate from " + currentVersion.versionString + " to " + headVersion.versionString)
|
||||
|
||||
conn.commit()
|
||||
} catch {
|
||||
case ex: Throwable => {
|
||||
logger.error("Failed to migrate", ex)
|
||||
conn.rollback()
|
||||
}
|
||||
}
|
||||
logger.debug("End migration")
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
package util
|
||||
|
||||
import java.io._
|
||||
import org.apache.commons.io.FileUtils
|
||||
|
||||
object Migration {
|
||||
|
||||
/**
|
||||
* Define Migrator interface.
|
||||
*/
|
||||
trait Migrator {
|
||||
def migrate(): Unit
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate H2 database by SQL files.
|
||||
*/
|
||||
case class DatabaseMigrator(sqlPath: String) extends Migrator {
|
||||
def migrate(): Unit = {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
case class Version(majorVersion: Int, minorVersion: Int, migrators: Migrator*)
|
||||
|
||||
/**
|
||||
* The history of versions. A head of this sequence is the current BitBucket version.
|
||||
* Migration#migrate() updates the data directory to move to the head version.
|
||||
*/
|
||||
val versions = Seq(
|
||||
Version(1, 0, DatabaseMigrator("migration/1.0/createdb.sql"))
|
||||
)
|
||||
|
||||
/**
|
||||
* The head version of BitBucket.
|
||||
*/
|
||||
val headVersion = versions.head
|
||||
|
||||
/**
|
||||
* The version file (GITBUCKET_HOME/version).
|
||||
*/
|
||||
val versionFile = new File(Directory.GitBucketHome, "version")
|
||||
|
||||
/**
|
||||
* Returns the current version
|
||||
*/
|
||||
def getCurrentVersion(): Version = {
|
||||
FileUtils.readFileToString(versionFile).split(".") match {
|
||||
case Array(majorVersion, minorVersion) => {
|
||||
versions.find { v => v.majorVersion == majorVersion.toInt && v.minorVersion == minorVersion.toInt }.get
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do migrate old data directory to the head version.
|
||||
*/
|
||||
def migrate(): Unit = {
|
||||
val currentVersion = getCurrentVersion()
|
||||
versions.takeWhile(_ != currentVersion).reverse.foreach(_.migrators.foreach(_.migrate()))
|
||||
FileUtils.writeStringToFile(versionFile, headVersion.majorVersion + "." + headVersion.minorVersion)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -35,7 +35,7 @@
|
||||
<!-- H2 database configuration -->
|
||||
<!-- ===================================================================== -->
|
||||
<listener>
|
||||
<listener-class>org.h2.server.web.DbStarter</listener-class>
|
||||
<listener-class>util.AutoUpdateListener</listener-class>
|
||||
</listener>
|
||||
|
||||
<context-param>
|
||||
|
||||
Reference in New Issue
Block a user