mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-10 07:25:50 +01:00
Export supports both of XML and SQL
This commit is contained in:
@@ -280,7 +280,11 @@ trait SystemSettingsControllerBase extends AccountManagementControllerBase {
|
|||||||
post("/admin/export")(adminOnly {
|
post("/admin/export")(adminOnly {
|
||||||
import gitbucket.core.util.JDBCUtil._
|
import gitbucket.core.util.JDBCUtil._
|
||||||
val session = request2Session(request)
|
val session = request2Session(request)
|
||||||
val file = session.conn.exportAsXML(request.getParameterValues("tableNames").toSeq)
|
val file = if(params("type") == "sql"){
|
||||||
|
session.conn.exportAsSQL(request.getParameterValues("tableNames").toSeq)
|
||||||
|
} else {
|
||||||
|
session.conn.exportAsXML(request.getParameterValues("tableNames").toSeq)
|
||||||
|
}
|
||||||
|
|
||||||
contentType = "application/octet-stream"
|
contentType = "application/octet-stream"
|
||||||
response.setHeader("Content-Disposition", "attachment; filename=" + file.getName)
|
response.setHeader("Content-Disposition", "attachment; filename=" + file.getName)
|
||||||
|
|||||||
@@ -164,11 +164,10 @@ object JDBCUtil {
|
|||||||
(null, null)
|
(null, null)
|
||||||
} else {
|
} else {
|
||||||
rsMeta.getColumnType(i) match {
|
rsMeta.getColumnType(i) match {
|
||||||
case Types.BOOLEAN | Types.BIT => ("boolean" , rs.getBoolean(columnName))
|
case Types.BOOLEAN | Types.BIT => ("boolean", rs.getBoolean(columnName))
|
||||||
case Types.VARCHAR | Types.CLOB | Types.CHAR | Types.LONGVARCHAR
|
case Types.VARCHAR | Types.CLOB | Types.CHAR | Types.LONGVARCHAR => ("string", rs.getString(columnName))
|
||||||
=> ("string" , rs.getString(columnName))
|
case Types.INTEGER => ("int", rs.getInt(columnName))
|
||||||
case Types.INTEGER => ("int" , rs.getInt(columnName))
|
case Types.TIMESTAMP => ("timestamp", dateFormat.format(rs.getTimestamp(columnName)))
|
||||||
case Types.TIMESTAMP => ("timestamp", dateFormat.format(rs.getTimestamp(columnName)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
writer.writeStartElement("column")
|
writer.writeStartElement("column")
|
||||||
@@ -193,6 +192,66 @@ object JDBCUtil {
|
|||||||
file
|
file
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def exportAsSQL(targetTables: Seq[String]): File = {
|
||||||
|
val dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss")
|
||||||
|
val file = File.createTempFile("gitbucket-export-", ".sql")
|
||||||
|
|
||||||
|
using(new FileOutputStream(file)) { out =>
|
||||||
|
val dbMeta = conn.getMetaData
|
||||||
|
val allTablesInDatabase = allTablesOrderByDependencies(dbMeta)
|
||||||
|
|
||||||
|
allTablesInDatabase.reverse.foreach { tableName =>
|
||||||
|
if (targetTables.contains(tableName)) {
|
||||||
|
out.write(s"DELETE FROM ${tableName};\n".getBytes("UTF-8"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allTablesInDatabase.foreach { tableName =>
|
||||||
|
if (targetTables.contains(tableName)) {
|
||||||
|
val sb = new StringBuilder()
|
||||||
|
select(s"SELECT * FROM ${tableName}") { rs =>
|
||||||
|
sb.append(s"INSERT INTO ${tableName} (")
|
||||||
|
|
||||||
|
val rsMeta = rs.getMetaData
|
||||||
|
val columns = (1 to rsMeta.getColumnCount).map { i =>
|
||||||
|
(rsMeta.getColumnName(i), rsMeta.getColumnType(i))
|
||||||
|
}
|
||||||
|
sb.append(columns.map(_._1).mkString(", "))
|
||||||
|
sb.append(") VALUES (")
|
||||||
|
|
||||||
|
val values = columns.map { case (columnName, columnType) =>
|
||||||
|
if(rs.getObject(columnName) == null){
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
columnType match {
|
||||||
|
case Types.BOOLEAN | Types.BIT => rs.getBoolean(columnName)
|
||||||
|
case Types.VARCHAR | Types.CLOB | Types.CHAR | Types.LONGVARCHAR => rs.getString(columnName)
|
||||||
|
case Types.INTEGER => rs.getInt(columnName)
|
||||||
|
case Types.TIMESTAMP => rs.getTimestamp(columnName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val columnValues = values.map { value =>
|
||||||
|
value match {
|
||||||
|
case x: String => "'" + x.replace("'", "''") + "'"
|
||||||
|
case x: Timestamp => "'" + dateFormat.format(x) + "'"
|
||||||
|
case null => "NULL"
|
||||||
|
case x => x
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sb.append(columnValues.mkString(", "))
|
||||||
|
sb.append(");\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
out.write(sb.toString.getBytes("UTF-8"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file
|
||||||
|
}
|
||||||
|
|
||||||
def allTableNames(): Seq[String] = {
|
def allTableNames(): Seq[String] = {
|
||||||
using(conn.getMetaData.getTables(null, null, "%", Seq("TABLE").toArray)) { rs =>
|
using(conn.getMetaData.getTables(null, null, "%", Seq("TABLE").toArray)) { rs =>
|
||||||
val tableNames = new ListBuffer[String]
|
val tableNames = new ListBuffer[String]
|
||||||
|
|||||||
@@ -15,6 +15,16 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
<input type="submit" class="btn btn-success pull-right" value="Export">
|
<input type="submit" class="btn btn-success pull-right" value="Export">
|
||||||
|
<div class="radio pull-right" style="margin-right: 10px;">
|
||||||
|
<label>
|
||||||
|
<input type="radio" name="type" value="sql">SQL
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="radio pull-right" style="margin-right: 10px;">
|
||||||
|
<label>
|
||||||
|
<input type="radio" name="type" value="xml" checked>XML
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user