mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-09 15:05:50 +01:00
(refs #464)Implementing database migration system for plugin
This commit is contained in:
@@ -6,12 +6,14 @@ import org.slf4j.LoggerFactory
|
|||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
import util.Directory._
|
import util.Directory._
|
||||||
import util.ControlUtil._
|
import util.ControlUtil._
|
||||||
import org.apache.commons.io.FileUtils
|
import org.apache.commons.io.{IOUtils, FileUtils}
|
||||||
import service.RepositoryService.RepositoryInfo
|
import service.RepositoryService.RepositoryInfo
|
||||||
import Security._
|
import Security._
|
||||||
import service.PluginService
|
import service.PluginService
|
||||||
import model.Profile._
|
import model.Profile._
|
||||||
import profile.simple._
|
import profile.simple._
|
||||||
|
import java.io.FileInputStream
|
||||||
|
import java.sql.Connection
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides extension points to plug-ins.
|
* Provides extension points to plug-ins.
|
||||||
@@ -24,7 +26,7 @@ object PluginSystem extends PluginService {
|
|||||||
private val pluginsMap = scala.collection.mutable.Map[String, Plugin]()
|
private val pluginsMap = scala.collection.mutable.Map[String, Plugin]()
|
||||||
private val repositoriesList = scala.collection.mutable.ListBuffer[PluginRepository]()
|
private val repositoriesList = scala.collection.mutable.ListBuffer[PluginRepository]()
|
||||||
|
|
||||||
def install(plugin: Plugin)(implicit session: Session): Unit = {
|
def install(plugin: Plugin): Unit = {
|
||||||
pluginsMap.put(plugin.id, plugin)
|
pluginsMap.put(plugin.id, plugin)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,11 +82,17 @@ object PluginSystem extends PluginService {
|
|||||||
""".stripMargin + FileUtils.readFileToString(scalaFile, "UTF-8")
|
""".stripMargin + FileUtils.readFileToString(scalaFile, "UTF-8")
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Compile and eval Scala source code
|
||||||
ScalaPlugin.eval(source)
|
ScalaPlugin.eval(source)
|
||||||
if(getPlugin(pluginId).isDefined){
|
|
||||||
|
// Migrate database
|
||||||
|
val plugin = getPlugin(pluginId)
|
||||||
|
if(plugin.isEmpty){
|
||||||
registerPlugin(model.Plugin(pluginId, version))
|
registerPlugin(model.Plugin(pluginId, version))
|
||||||
|
migrate(session.conn, pluginId, "0.0")
|
||||||
} else {
|
} else {
|
||||||
updatePlugin(model.Plugin(pluginId, version))
|
updatePlugin(model.Plugin(pluginId, version))
|
||||||
|
migrate(session.conn, pluginId, plugin.get.version)
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
case e: Exception => logger.warn(s"Error in plugin loading for ${scalaFile.getAbsolutePath}", e)
|
case e: Exception => logger.warn(s"Error in plugin loading for ${scalaFile.getAbsolutePath}", e)
|
||||||
@@ -92,6 +100,42 @@ object PluginSystem extends PluginService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO Should PluginSystem provide a way to migrate resources other than H2?
|
||||||
|
private def migrate(conn: Connection, pluginId: String, current: String): Unit = {
|
||||||
|
val pluginDir = new java.io.File(PluginHome)
|
||||||
|
|
||||||
|
// TODO Is ot possible to use this migration system in GitBucket migration?
|
||||||
|
val dim = current.split("\\.")
|
||||||
|
val currentVersion = Version(dim(0).toInt, dim(1).toInt)
|
||||||
|
|
||||||
|
val sqlDir = new java.io.File(pluginDir, pluginId + "/sql")
|
||||||
|
if(sqlDir.exists && sqlDir.isDirectory){
|
||||||
|
sqlDir.listFiles.filter(_.getName.endsWith(".sql")).map { file =>
|
||||||
|
val array = file.getName.replaceFirst("\\.sql", "").split("_")
|
||||||
|
Version(array(0).toInt, array(1).toInt)
|
||||||
|
}.sorted.reverse.takeWhile(_ > currentVersion).reverse.foreach { version =>
|
||||||
|
val sqlFile = new java.io.File(pluginDir, pluginId + "/sql/" + version.major + "_" + version.minor + ".sql")
|
||||||
|
val sql = IOUtils.toString(new FileInputStream(sqlFile), "UTF-8")
|
||||||
|
using(conn.createStatement()){ stmt =>
|
||||||
|
stmt.executeUpdate(sql)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case class Version(major: Int, minor: Int) extends Ordered[Version] {
|
||||||
|
|
||||||
|
override def compare(that: Version): Int = {
|
||||||
|
if(major != that.major){
|
||||||
|
major.compare(that.major)
|
||||||
|
} else{
|
||||||
|
minor.compare(that.minor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def displayString: String = major + "." + minor
|
||||||
|
}
|
||||||
|
|
||||||
def repositoryMenus : List[RepositoryMenu] = pluginsMap.values.flatMap(_.repositoryMenus).toList
|
def repositoryMenus : List[RepositoryMenu] = pluginsMap.values.flatMap(_.repositoryMenus).toList
|
||||||
def globalMenus : List[GlobalMenu] = pluginsMap.values.flatMap(_.globalMenus).toList
|
def globalMenus : List[GlobalMenu] = pluginsMap.values.flatMap(_.globalMenus).toList
|
||||||
def repositoryActions : List[RepositoryAction] = pluginsMap.values.flatMap(_.repositoryActions).toList
|
def repositoryActions : List[RepositoryAction] = pluginsMap.values.flatMap(_.repositoryActions).toList
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ class AutoUpdateListener extends ServletContextListener {
|
|||||||
case ex: Throwable => {
|
case ex: Throwable => {
|
||||||
logger.error("Failed to initialize plugin system", ex)
|
logger.error("Failed to initialize plugin system", ex)
|
||||||
ex.printStackTrace()
|
ex.printStackTrace()
|
||||||
session.rollback()
|
throw ex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user