diff --git a/pkg/api/api.go b/pkg/api/api.go index 6d895817e..c1d8b4ffe 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -506,8 +506,43 @@ func GetTableConstraints(c *gin.Context) { // GetTablesStats renders data sizes and estimated rows for all tables in the database func GetTablesStats(c *gin.Context) { - res, err := DB(c).TablesStats() - serveResult(c, res, err) + db := DB(c) + + connCtx, err := db.GetConnContext() + if err != nil { + badRequest(c, err) + return + } + + res, err := db.TablesStats() + if err != nil { + badRequest(c, err) + return + } + + format := getQueryParam(c, "format") + if format == "" { + format = "json" + } + + // Save as attachment if exporting parameter is set + if getQueryParam(c, "export") == "true" { + ts := time.Now().Format(time.DateOnly) + + filename := fmt.Sprintf("pgweb-dbstats-%s-%s.%s", connCtx.Database, ts, format) + c.Writer.Header().Set("Content-disposition", "attachment;filename="+filename) + } + + switch format { + case "json": + c.JSON(http.StatusOK, res) + case "csv": + c.Data(http.StatusOK, "text/csv", res.CSV()) + case "xml": + c.XML(200, res) + default: + badRequest(c, "invalid format") + } } // HandleQuery runs the database query diff --git a/pkg/api/helpers.go b/pkg/api/helpers.go index ed7be10f2..8e0fcb91e 100644 --- a/pkg/api/helpers.go +++ b/pkg/api/helpers.go @@ -155,11 +155,12 @@ func assetContentType(name string) string { // Send a query result to client func serveResult(c *gin.Context, result interface{}, err interface{}) { - if err == nil { - successResponse(c, result) - } else { + if err != nil { badRequest(c, err) + return } + + successResponse(c, result) } // Send successful response back to client diff --git a/static/index.html b/static/index.html index 0697b3d9a..d92fa7dd3 100644 --- a/static/index.html +++ b/static/index.html @@ -324,7 +324,9 @@

SSH Connection

diff --git a/static/js/app.js b/static/js/app.js index b8ad384d1..50e3fb511 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -660,7 +660,7 @@ function showPaginatedTableContent() { showTableContent(sortColumn, sortOrder); } -function showTablesStats() { +function showDatabaseStats() { getTablesStats(function(data) { buildTable(data); @@ -671,6 +671,10 @@ function showTablesStats() { }); } +function downloadDatabaseStats() { + openInNewWindow("api/tables_stats", { format: "csv", export: "true" }); +} + function showTableStructure() { var name = getCurrentObject().name; @@ -1267,8 +1271,11 @@ function bindCurrentDatabaseMenu() { var menuItem = $(e.target); switch(menuItem.data("action")) { - case "show_tables_stats": - showTablesStats(); + case "show_db_stats": + showDatabaseStats(); + break; + case "download_db_stats": + downloadDatabaseStats(); break; case "export": openInNewWindow("api/export");