diff --git a/src/main/resources/migration/1_0.sql b/src/main/resources/migration/1_0.sql
new file mode 100644
index 0000000..9b25eeb
--- /dev/null
+++ b/src/main/resources/migration/1_0.sql
@@ -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
+);
+
diff --git a/src/main/scala/util/AutoUpdate.scala b/src/main/scala/util/AutoUpdate.scala
new file mode 100644
index 0000000..897eb59
--- /dev/null
+++ b/src/main/scala/util/AutoUpdate.scala
@@ -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")
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/scala/util/Migration.scala b/src/main/scala/util/Migration.scala
deleted file mode 100644
index 1d674ff..0000000
--- a/src/main/scala/util/Migration.scala
+++ /dev/null
@@ -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)
- }
-
-
-}
\ No newline at end of file
diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml
index d2b646a..93bc19d 100644
--- a/src/main/webapp/WEB-INF/web.xml
+++ b/src/main/webapp/WEB-INF/web.xml
@@ -35,7 +35,7 @@
- org.h2.server.web.DbStarter
+ util.AutoUpdateListener