diff --git a/src/main/scala/service/RepositoryService.scala b/src/main/scala/service/RepositoryService.scala index 5305cb0..acbca97 100644 --- a/src/main/scala/service/RepositoryService.scala +++ b/src/main/scala/service/RepositoryService.scala @@ -137,7 +137,7 @@ WebHooks .filter(_.byRepository(userName, repositoryName)).delete Repositories .filter(_.byRepository(userName, repositoryName)).delete - // Update ORIGINAL_USER_NAME and ORIGINAL_REPOSITORY_NAME + // Update ORIGIN_USER_NAME and ORIGIN_REPOSITORY_NAME Repositories .filter { x => (x.originUserName === userName.bind) && (x.originRepositoryName === repositoryName.bind) } .map { x => (x.userName, x.repositoryName) } diff --git a/src/main/scala/servlet/AutoUpdateListener.scala b/src/main/scala/servlet/AutoUpdateListener.scala index e9d1e82..0a842b0 100644 --- a/src/main/scala/servlet/AutoUpdateListener.scala +++ b/src/main/scala/servlet/AutoUpdateListener.scala @@ -8,6 +8,7 @@ import org.slf4j.LoggerFactory import util.Directory._ import util.ControlUtil._ +import util.JDBCUtil._ import org.eclipse.jgit.api.Git import util.Directory import plugin.PluginUpdateJob @@ -56,13 +57,34 @@ new Version(2, 7) { override def update(conn: Connection): Unit = { super.update(conn) - using(conn.createStatement.executeQuery("SELECT USER_NAME, REPOSITORY_NAME FROM REPOSITORY")){ rs => - while(rs.next){ - defining(Directory.getAttachedDir(rs.getString("USER_NAME"), rs.getString("REPOSITORY_NAME"))){ newDir => - val oldDir = new File(newDir.getParentFile, "issues") - if(oldDir.exists && oldDir.isDirectory){ - oldDir.renameTo(newDir) - } + conn.select("SELECT * FROM REPOSITORY"){ rs => + // Rename attached files directory from /issues to /comments + val userName = rs.getString("USER_NAME") + val repoName = rs.getString("REPOSITORY_NAME") + defining(Directory.getAttachedDir(userName, repoName)){ newDir => + val oldDir = new File(newDir.getParentFile, "issues") + if(oldDir.exists && oldDir.isDirectory){ + oldDir.renameTo(newDir) + } + } + // Update ORIGIN_USER_NAME and ORIGIN_REPOSITORY_NAME if it does not exist + val originalUserName = rs.getString("ORIGIN_USER_NAME") + val originalRepoName = rs.getString("ORIGIN_REPOSITORY_NAME") + if(originalUserName != null && originalRepoName != null){ + if(conn.selectInt("SELECT COUNT(*) FROM REPOSITORY WHERE USER_NAME = ? AND REPOSITORY_NAME = ?", + originalUserName, originalRepoName) == 0){ + conn.update("UPDATE REPOSITORY SET ORIGIN_USER_NAME = NULL, ORIGIN_REPOSITORY_NAME = NULL " + + "WHERE USER_NAME = ? AND REPOSITORY_NAME = ?", userName, repoName) + } + } + // Update PARENT_USER_NAME and PARENT_REPOSITORY_NAME if it does not exist + val parentUserName = rs.getString("PARENT_USER_NAME") + val parentRepoName = rs.getString("PARENT_REPOSITORY_NAME") + if(parentUserName != null && parentRepoName != null){ + if(conn.selectInt("SELECT COUNT(*) FROM REPOSITORY WHERE USER_NAME = ? AND REPOSITORY_NAME = ?", + parentUserName, parentRepoName) == 0){ + conn.update("UPDATE REPOSITORY SET PARENT_USER_NAME = NULL, PARENT_REPOSITORY_NAME = NULL " + + "WHERE USER_NAME = ? AND REPOSITORY_NAME = ?", userName, repoName) } } } @@ -74,18 +96,11 @@ new Version(2, 3) { override def update(conn: Connection): Unit = { super.update(conn) - using(conn.createStatement.executeQuery("SELECT ACTIVITY_ID, ADDITIONAL_INFO FROM ACTIVITY WHERE ACTIVITY_TYPE='push'")){ rs => - while(rs.next) { - val info = rs.getString("ADDITIONAL_INFO") - val newInfo = info.split("\n").filter(_ matches "^[0-9a-z]{40}:.*").mkString("\n") - if (info != newInfo) { - val id = rs.getString("ACTIVITY_ID") - using(conn.prepareStatement("UPDATE ACTIVITY SET ADDITIONAL_INFO=? WHERE ACTIVITY_ID=?")) { sql => - sql.setString(1, newInfo) - sql.setLong(2, id.toLong) - sql.executeUpdate - } - } + conn.select("SELECT ACTIVITY_ID, ADDITIONAL_INFO FROM ACTIVITY WHERE ACTIVITY_TYPE='push'"){ rs => + val curInfo = rs.getString("ADDITIONAL_INFO") + val newInfo = curInfo.split("\n").filter(_ matches "^[0-9a-z]{40}:.*").mkString("\n") + if (curInfo != newInfo) { + conn.update("UPDATE ACTIVITY SET ADDITIONAL_INFO = ? WHERE ACTIVITY_ID = ?", newInfo, rs.getInt("ACTIVITY_ID")) } } FileUtils.deleteDirectory(Directory.getPluginCacheDir()) @@ -102,16 +117,14 @@ mimeUtil.registerMimeDetector("eu.medsea.mimeutil.detector.MagicMimeMimeDetector") super.update(conn) - using(conn.createStatement.executeQuery("SELECT USER_NAME, REPOSITORY_NAME FROM REPOSITORY")){ rs => - while(rs.next){ - defining(Directory.getAttachedDir(rs.getString("USER_NAME"), rs.getString("REPOSITORY_NAME"))){ dir => - if(dir.exists && dir.isDirectory){ - dir.listFiles.foreach { file => - if(file.getName.indexOf('.') < 0){ - val mimeType = MimeUtil2.getMostSpecificMimeType(mimeUtil.getMimeTypes(file, new MimeType("application/octet-stream"))).toString - if(mimeType.startsWith("image/")){ - file.renameTo(new File(file.getParent, file.getName + "." + mimeType.split("/")(1))) - } + conn.select("SELECT USER_NAME, REPOSITORY_NAME FROM REPOSITORY"){ rs => + defining(Directory.getAttachedDir(rs.getString("USER_NAME"), rs.getString("REPOSITORY_NAME"))){ dir => + if(dir.exists && dir.isDirectory){ + dir.listFiles.foreach { file => + if(file.getName.indexOf('.') < 0){ + val mimeType = MimeUtil2.getMostSpecificMimeType(mimeUtil.getMimeTypes(file, new MimeType("application/octet-stream"))).toString + if(mimeType.startsWith("image/")){ + file.renameTo(new File(file.getParent, file.getName + "." + mimeType.split("/")(1))) } } } @@ -134,14 +147,12 @@ override def update(conn: Connection): Unit = { super.update(conn) // Fix wiki repository configuration - using(conn.createStatement.executeQuery("SELECT USER_NAME, REPOSITORY_NAME FROM REPOSITORY")){ rs => - while(rs.next){ - using(Git.open(getWikiRepositoryDir(rs.getString("USER_NAME"), rs.getString("REPOSITORY_NAME")))){ git => - defining(git.getRepository.getConfig){ config => - if(!config.getBoolean("http", "receivepack", false)){ - config.setBoolean("http", null, "receivepack", true) - config.save - } + conn.select("SELECT USER_NAME, REPOSITORY_NAME FROM REPOSITORY"){ rs => + using(Git.open(getWikiRepositoryDir(rs.getString("USER_NAME"), rs.getString("REPOSITORY_NAME")))){ git => + defining(git.getRepository.getConfig){ config => + if(!config.getBoolean("http", "receivepack", false)){ + config.setBoolean("http", null, "receivepack", true) + config.save } } } diff --git a/src/main/scala/util/JDBCUtil.scala b/src/main/scala/util/JDBCUtil.scala new file mode 100644 index 0000000..375ea14 --- /dev/null +++ b/src/main/scala/util/JDBCUtil.scala @@ -0,0 +1,55 @@ +package util + +import java.sql._ +import util.ControlUtil._ +import scala.collection.mutable.ListBuffer + +/** + * Provides implicit class which extends java.sql.Connection. + * This is used in automatic migration in [[servlet.AutoUpdateListener]]. + */ +object JDBCUtil { + + implicit class RichConnection(conn: Connection){ + + def update(sql: String, params: Any*): Int = { + execute(sql, params: _*){ stmt => + stmt.executeUpdate() + } + } + + def select[T](sql: String, params: Any*)(f: ResultSet => T): Seq[T] = { + execute(sql, params: _*){ stmt => + using(stmt.executeQuery()){ rs => + val list = new ListBuffer[T] + while(rs.next){ + list += f(rs) + } + list.toSeq + } + } + } + + def selectInt(sql: String, params: Any*): Int = { + execute(sql, params: _*){ stmt => + using(stmt.executeQuery()){ rs => + if(rs.next) rs.getInt(1) else 0 + } + } + } + + private def execute[T](sql: String, params: Any*)(f: (PreparedStatement) => T): T = { + using(conn.prepareStatement(sql)){ stmt => + params.zipWithIndex.foreach { case (p, i) => + p match { + case x: Int => stmt.setInt(i + 1, x) + case x: String => stmt.setString(i + 1, x) + } + } + f(stmt) + } + } + + } + +}