2015-04-30 19:47:07 +03:00
|
|
|
package api
|
2014-10-11 02:14:17 +04:00
|
|
|
|
|
|
|
import (
|
2015-08-16 04:53:51 +03:00
|
|
|
"encoding/base64"
|
2014-10-11 02:14:17 +04:00
|
|
|
"errors"
|
|
|
|
"fmt"
|
2015-01-04 04:42:56 +03:00
|
|
|
"strconv"
|
2014-10-11 02:14:17 +04:00
|
|
|
"strings"
|
2015-01-06 04:46:02 +03:00
|
|
|
"time"
|
2014-11-11 08:10:05 +03:00
|
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
2015-04-30 19:47:07 +03:00
|
|
|
"github.com/sosedoff/pgweb/pkg/bookmarks"
|
|
|
|
"github.com/sosedoff/pgweb/pkg/client"
|
|
|
|
"github.com/sosedoff/pgweb/pkg/command"
|
|
|
|
"github.com/sosedoff/pgweb/pkg/connection"
|
2014-10-11 02:14:17 +04:00
|
|
|
)
|
|
|
|
|
2015-04-30 19:47:07 +03:00
|
|
|
var DbClient *client.Client
|
|
|
|
|
2015-05-01 03:59:48 +03:00
|
|
|
func GetHome(c *gin.Context) {
|
2015-05-03 04:10:14 +03:00
|
|
|
serveStaticAsset("/index.html", c)
|
|
|
|
}
|
2014-10-13 23:40:56 +04:00
|
|
|
|
2015-05-03 04:10:14 +03:00
|
|
|
func GetAsset(c *gin.Context) {
|
|
|
|
serveStaticAsset(c.Params.ByName("path"), c)
|
2014-10-13 22:55:19 +04:00
|
|
|
}
|
|
|
|
|
2015-05-03 04:13:04 +03:00
|
|
|
func Connect(c *gin.Context) {
|
2014-11-01 06:37:58 +03:00
|
|
|
url := c.Request.FormValue("url")
|
|
|
|
|
|
|
|
if url == "" {
|
|
|
|
c.JSON(400, Error{"Url parameter is required"})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2015-04-30 19:47:07 +03:00
|
|
|
opts := command.Options{Url: url}
|
|
|
|
url, err := connection.FormatUrl(opts)
|
2015-01-01 03:23:51 +03:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
c.JSON(400, Error{err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2015-04-30 19:47:07 +03:00
|
|
|
cl, err := client.NewFromUrl(url)
|
2014-11-01 06:37:58 +03:00
|
|
|
if err != nil {
|
|
|
|
c.JSON(400, Error{err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2015-04-30 19:47:07 +03:00
|
|
|
err = cl.Test()
|
2014-11-01 06:37:58 +03:00
|
|
|
if err != nil {
|
|
|
|
c.JSON(400, Error{err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2015-04-30 19:47:07 +03:00
|
|
|
info, err := cl.Info()
|
2014-11-01 06:37:58 +03:00
|
|
|
|
|
|
|
if err == nil {
|
2015-04-30 19:47:07 +03:00
|
|
|
if DbClient != nil {
|
|
|
|
DbClient.Close()
|
2014-11-01 23:44:24 +03:00
|
|
|
}
|
|
|
|
|
2015-04-30 19:47:07 +03:00
|
|
|
DbClient = cl
|
2014-11-01 06:37:58 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
c.JSON(200, info.Format()[0])
|
|
|
|
}
|
|
|
|
|
2015-05-03 04:13:04 +03:00
|
|
|
func GetDatabases(c *gin.Context) {
|
2015-04-30 19:47:07 +03:00
|
|
|
names, err := DbClient.Databases()
|
2015-05-03 04:32:16 +03:00
|
|
|
serveResult(names, err, c)
|
2014-10-16 01:05:23 +04:00
|
|
|
}
|
|
|
|
|
2015-05-03 04:13:04 +03:00
|
|
|
func RunQuery(c *gin.Context) {
|
2014-10-11 02:14:17 +04:00
|
|
|
query := strings.TrimSpace(c.Request.FormValue("query"))
|
|
|
|
|
|
|
|
if query == "" {
|
|
|
|
c.JSON(400, errors.New("Query parameter is missing"))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2015-05-03 04:32:16 +03:00
|
|
|
HandleQuery(query, c)
|
2014-10-11 02:14:17 +04:00
|
|
|
}
|
|
|
|
|
2015-05-03 04:13:04 +03:00
|
|
|
func ExplainQuery(c *gin.Context) {
|
2014-10-11 22:24:12 +04:00
|
|
|
query := strings.TrimSpace(c.Request.FormValue("query"))
|
|
|
|
|
|
|
|
if query == "" {
|
|
|
|
c.JSON(400, errors.New("Query parameter is missing"))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2015-05-03 04:32:16 +03:00
|
|
|
HandleQuery(fmt.Sprintf("EXPLAIN ANALYZE %s", query), c)
|
2014-10-11 22:24:12 +04:00
|
|
|
}
|
|
|
|
|
2015-05-03 04:13:04 +03:00
|
|
|
func GetSchemas(c *gin.Context) {
|
2015-04-30 19:47:07 +03:00
|
|
|
names, err := DbClient.Schemas()
|
2015-05-03 04:32:16 +03:00
|
|
|
serveResult(names, err, c)
|
2015-03-31 07:58:04 +03:00
|
|
|
}
|
|
|
|
|
2015-05-03 04:13:04 +03:00
|
|
|
func GetTables(c *gin.Context) {
|
2015-04-30 19:47:07 +03:00
|
|
|
names, err := DbClient.Tables()
|
2015-05-03 04:32:16 +03:00
|
|
|
serveResult(names, err, c)
|
2014-10-11 02:14:17 +04:00
|
|
|
}
|
|
|
|
|
2015-05-03 04:13:04 +03:00
|
|
|
func GetTable(c *gin.Context) {
|
2015-04-30 19:47:07 +03:00
|
|
|
res, err := DbClient.Table(c.Params.ByName("table"))
|
2015-05-03 04:32:16 +03:00
|
|
|
serveResult(res, err, c)
|
2014-10-11 02:14:17 +04:00
|
|
|
}
|
|
|
|
|
2015-05-03 04:13:04 +03:00
|
|
|
func GetTableRows(c *gin.Context) {
|
2015-01-04 04:42:56 +03:00
|
|
|
limit := 1000 // Number of rows to fetch
|
|
|
|
limitVal := c.Request.FormValue("limit")
|
|
|
|
|
|
|
|
if limitVal != "" {
|
|
|
|
num, err := strconv.Atoi(limitVal)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
c.JSON(400, Error{"Invalid limit value"})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if num <= 0 {
|
|
|
|
c.JSON(400, Error{"Limit should be greater than 0"})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
limit = num
|
|
|
|
}
|
|
|
|
|
2015-04-30 19:47:07 +03:00
|
|
|
opts := client.RowsOptions{
|
2015-01-04 04:42:56 +03:00
|
|
|
Limit: limit,
|
|
|
|
SortColumn: c.Request.FormValue("sort_column"),
|
|
|
|
SortOrder: c.Request.FormValue("sort_order"),
|
|
|
|
}
|
|
|
|
|
2015-04-30 19:47:07 +03:00
|
|
|
res, err := DbClient.TableRows(c.Params.ByName("table"), opts)
|
2015-05-03 04:32:16 +03:00
|
|
|
serveResult(res, err, c)
|
2015-01-04 04:42:56 +03:00
|
|
|
}
|
|
|
|
|
2015-05-03 04:13:04 +03:00
|
|
|
func GetTableInfo(c *gin.Context) {
|
2015-04-30 19:47:07 +03:00
|
|
|
res, err := DbClient.TableInfo(c.Params.ByName("table"))
|
2014-10-18 07:30:08 +04:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
c.JSON(400, NewError(err))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2014-10-27 01:16:35 +03:00
|
|
|
c.JSON(200, res.Format()[0])
|
2014-10-18 07:30:08 +04:00
|
|
|
}
|
|
|
|
|
2015-05-01 03:59:48 +03:00
|
|
|
func GetHistory(c *gin.Context) {
|
2015-04-30 19:47:07 +03:00
|
|
|
c.JSON(200, DbClient.History)
|
2014-10-11 02:14:17 +04:00
|
|
|
}
|
|
|
|
|
2015-05-01 03:59:48 +03:00
|
|
|
func GetConnectionInfo(c *gin.Context) {
|
2015-04-30 19:47:07 +03:00
|
|
|
res, err := DbClient.Info()
|
2014-10-11 02:14:17 +04:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
c.JSON(400, NewError(err))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
c.JSON(200, res.Format()[0])
|
|
|
|
}
|
|
|
|
|
2015-11-13 15:36:13 +03:00
|
|
|
func GetSequences(c *gin.Context) {
|
|
|
|
res, err := DbClient.Sequences()
|
|
|
|
serveResult(res, err, c)
|
|
|
|
}
|
|
|
|
|
2015-05-01 03:59:48 +03:00
|
|
|
func GetActivity(c *gin.Context) {
|
2015-04-30 19:47:07 +03:00
|
|
|
res, err := DbClient.Activity()
|
2015-05-03 04:32:16 +03:00
|
|
|
serveResult(res, err, c)
|
2015-03-21 19:46:14 +03:00
|
|
|
}
|
|
|
|
|
2015-05-01 03:59:48 +03:00
|
|
|
func GetTableIndexes(c *gin.Context) {
|
2015-04-30 19:47:07 +03:00
|
|
|
res, err := DbClient.TableIndexes(c.Params.ByName("table"))
|
2015-05-03 04:32:16 +03:00
|
|
|
serveResult(res, err, c)
|
2014-10-11 22:20:16 +04:00
|
|
|
}
|
|
|
|
|
2015-12-05 03:14:03 +03:00
|
|
|
func GetTableConstraints(c *gin.Context) {
|
|
|
|
res, err := DbClient.TableConstraints(c.Params.ByName("table"))
|
|
|
|
serveResult(res, err, c)
|
|
|
|
}
|
|
|
|
|
2015-05-03 04:32:16 +03:00
|
|
|
func HandleQuery(query string, c *gin.Context) {
|
2015-08-16 04:53:51 +03:00
|
|
|
rawQuery, err := base64.StdEncoding.DecodeString(query)
|
|
|
|
if err == nil {
|
|
|
|
query = string(rawQuery)
|
|
|
|
}
|
2014-10-11 02:14:17 +04:00
|
|
|
|
2015-08-16 04:53:51 +03:00
|
|
|
result, err := DbClient.Query(query)
|
2014-10-11 02:14:17 +04:00
|
|
|
if err != nil {
|
|
|
|
c.JSON(400, NewError(err))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2014-10-11 03:56:02 +04:00
|
|
|
q := c.Request.URL.Query()
|
|
|
|
|
2015-01-06 04:46:02 +03:00
|
|
|
if len(q["format"]) > 0 && q["format"][0] == "csv" {
|
|
|
|
filename := fmt.Sprintf("pgweb-%v.csv", time.Now().Unix())
|
2015-05-19 20:24:52 +03:00
|
|
|
if len(q["filename"]) > 0 && q["filename"][0] != "" {
|
|
|
|
filename = q["filename"][0]
|
|
|
|
}
|
|
|
|
|
2015-01-06 04:46:02 +03:00
|
|
|
c.Writer.Header().Set("Content-disposition", "attachment;filename="+filename)
|
|
|
|
c.Data(200, "text/csv", result.CSV())
|
|
|
|
return
|
2014-10-11 03:56:02 +04:00
|
|
|
}
|
|
|
|
|
2014-10-11 02:14:17 +04:00
|
|
|
c.JSON(200, result)
|
|
|
|
}
|
2014-10-13 23:40:56 +04:00
|
|
|
|
2015-05-01 03:59:48 +03:00
|
|
|
func GetBookmarks(c *gin.Context) {
|
2015-04-30 19:47:07 +03:00
|
|
|
bookmarks, err := bookmarks.ReadAll(bookmarks.Path())
|
2015-05-03 04:32:16 +03:00
|
|
|
serveResult(bookmarks, err, c)
|
2014-12-03 07:19:38 +03:00
|
|
|
}
|
2015-05-05 08:34:23 +03:00
|
|
|
|
|
|
|
func GetInfo(c *gin.Context) {
|
|
|
|
info := map[string]string{
|
|
|
|
"version": command.VERSION,
|
|
|
|
"git_sha": command.GitCommit,
|
|
|
|
"build_time": command.BuildTime,
|
|
|
|
}
|
|
|
|
|
|
|
|
c.JSON(200, info)
|
|
|
|
}
|