mirror of
https://github.com/sosedoff/pgweb.git
synced 2024-12-14 19:21:46 +03:00
Add ability to export table to JSON and XML
This commit is contained in:
parent
bc1f876fb5
commit
73a97893e9
@ -196,20 +196,27 @@ func HandleQuery(query string, c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
q := c.Request.URL.Query()
|
||||
format := getQueryParam(c, "format")
|
||||
filename := getQueryParam(c, "filename")
|
||||
|
||||
if len(q["format"]) > 0 && q["format"][0] == "csv" {
|
||||
filename := fmt.Sprintf("pgweb-%v.csv", time.Now().Unix())
|
||||
if len(q["filename"]) > 0 && q["filename"][0] != "" {
|
||||
filename = q["filename"][0]
|
||||
if filename == "" {
|
||||
filename = fmt.Sprintf("pgweb-%v.%v", time.Now().Unix(), format)
|
||||
}
|
||||
|
||||
if format != "" {
|
||||
c.Writer.Header().Set("Content-disposition", "attachment;filename="+filename)
|
||||
c.Data(200, "text/csv", result.CSV())
|
||||
return
|
||||
}
|
||||
|
||||
switch format {
|
||||
case "csv":
|
||||
c.Data(200, "text/csv", result.CSV())
|
||||
case "json":
|
||||
c.Data(200, "applicaiton/json", result.JSON())
|
||||
case "xml":
|
||||
c.XML(200, result)
|
||||
default:
|
||||
c.JSON(200, result)
|
||||
}
|
||||
}
|
||||
|
||||
func GetBookmarks(c *gin.Context) {
|
||||
|
@ -22,6 +22,17 @@ type Error struct {
|
||||
Message string `json:"error"`
|
||||
}
|
||||
|
||||
func getQueryParam(c *gin.Context, name string) string {
|
||||
result := ""
|
||||
q := c.Request.URL.Query()
|
||||
|
||||
if len(q[name]) > 0 {
|
||||
result = q[name][0]
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func assetContentType(name string) string {
|
||||
ext := filepath.Ext(name)
|
||||
result := mime.TypeByExtension(ext)
|
||||
|
@ -3,6 +3,7 @@ package client
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/csv"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
@ -250,6 +251,21 @@ func (res *Result) CSV() []byte {
|
||||
return buff.Bytes()
|
||||
}
|
||||
|
||||
func (res *Result) JSON() []byte {
|
||||
records := []map[string]interface{}{}
|
||||
|
||||
for _, row := range res.Rows {
|
||||
record := map[string]interface{}{}
|
||||
for i, col := range res.Columns {
|
||||
record[col] = row[i]
|
||||
}
|
||||
records = append(records, record)
|
||||
}
|
||||
|
||||
data, _ := json.Marshal(records)
|
||||
return data
|
||||
}
|
||||
|
||||
// Close database connection
|
||||
func (client *Client) Close() error {
|
||||
if client.db != nil {
|
||||
|
File diff suppressed because one or more lines are too long
@ -197,7 +197,9 @@
|
||||
</div>
|
||||
<div id="tables_context_menu">
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="#" data-action="export">Export to CSV</a></li>
|
||||
<li><a href="#" data-action="export" data-format="json">Export to JSON</a></li>
|
||||
<li><a href="#" data-action="export" data-format="csv">Export to CSV</a></li>
|
||||
<li><a href="#" data-action="export" data-format="xml">Export to XML</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="#" data-action="truncate">Truncate table</a></li>
|
||||
<li><a href="#" data-action="delete">Delete table</a></li>
|
||||
|
@ -84,7 +84,7 @@ function resetTable() {
|
||||
removeClass("no-crop");
|
||||
}
|
||||
|
||||
function performTableAction(table, action) {
|
||||
function performTableAction(table, action, el) {
|
||||
if (action == "truncate" || action == "delete") {
|
||||
var message = "Are you sure you want to " + action + " table " + table + " ?";
|
||||
if (!confirm(message)) return;
|
||||
@ -106,9 +106,10 @@ function performTableAction(table, action) {
|
||||
});
|
||||
break;
|
||||
case "export":
|
||||
var filename = table + ".csv"
|
||||
var format = el.data("format");
|
||||
var filename = table + "." + format;
|
||||
var query = window.encodeURI("SELECT * FROM " + table);
|
||||
var url = "http://" + window.location.host + "/api/query?format=csv&filename=" + filename + "&query=" + query;
|
||||
var url = "http://" + window.location.host + "/api/query?format=" + format + "&filename=" + filename + "&query=" + query;
|
||||
var win = window.open(url, "_blank");
|
||||
win.focus();
|
||||
break;
|
||||
@ -583,9 +584,10 @@ $(document).ready(function() {
|
||||
target: "#tables_context_menu",
|
||||
scopes: "li",
|
||||
onItem: function(context, e) {
|
||||
var el = $(e.target);
|
||||
var table = $.trim($(context[0]).text());
|
||||
var action = $(e.target).data("action");
|
||||
performTableAction(table, action);
|
||||
var action = el.data("action");
|
||||
performTableAction(table, action, el);
|
||||
}
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user