diff --git a/pkg/api/api.go b/pkg/api/api.go index 9e1c37f11f240dd64d5bd0d8f635c46b00483788..3b651182b4c3e404ce072619357494c9d6d7d913 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -34,6 +34,7 @@ func DB(c *gin.Context) *client.Client { if command.Opts.Sessions { return DbSessions[getSessionId(c.Request)] } + DbClient.SetApplicationName() return DbClient } @@ -121,6 +122,7 @@ func ConnectWithBackend(c *gin.Context) { } cl.External = true + cl.SetApplicationName() // Finalize session seetup _, err = cl.Info() if err == nil { @@ -175,6 +177,8 @@ func Connect(c *gin.Context) { return } + cl.SetApplicationName() + info, err := cl.Info() if err == nil { err = setClient(c, cl) @@ -235,6 +239,8 @@ func SwitchDb(c *gin.Context) { return } + cl.SetApplicationName() + info, err := cl.Info() if err == nil { err = setClient(c, cl) @@ -472,7 +478,7 @@ func HandleQuery(query string, c *gin.Context) { filename := getQueryParam(c, "filename") if filename == "" { - filename = fmt.Sprintf("pgweb-%v.%v", time.Now().Unix(), format) + filename = fmt.Sprintf("openGauss-webclient-%v.%v", time.Now().Unix(), format) } if format != "" { diff --git a/pkg/cli/cli.go b/pkg/cli/cli.go index 096e06ad82402a918b5186c3589767f5afb11c09..4156b43bc11e34d47c575ade1a96340aabd7816e 100644 --- a/pkg/cli/cli.go +++ b/pkg/cli/cli.go @@ -118,6 +118,9 @@ func initClient() { fmt.Printf("Connected to %s\n", cl.ServerVersion()) } + fmt.Println("Set application name...") + cl.SetApplicationName() + fmt.Println("Checking database objects...") _, err = cl.Objects() if err != nil { diff --git a/pkg/client/client.go b/pkg/client/client.go index 0b7a939638773877b993cadb3d68a2132d296873..f235e67a5b19da43d7b6faea1dd17cf8a05134a2 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -177,6 +177,10 @@ func (client *Client) setServerVersion() { } } +func (client *Client) SetApplicationName() (*Result, error) { + return client.query(statements.SetApplication) +} + func (client *Client) Test() error { return client.db.Ping() } @@ -361,7 +365,7 @@ func (client *Client) query(query string, args ...interface{}) (*Result, error) } action := strings.ToLower(strings.Split(query, " ")[0]) - if action == "update" || action == "delete" { + if action == "update" || action == "delete" || action == "insert" { res, err := client.db.Exec(query, args...) if err != nil { return nil, err diff --git a/pkg/command/version.go b/pkg/command/version.go index 926abe81cef14091f51ba761314bf2de3dab8f39..3455d98e9e56d2e23fb7af1f434c12a9543fc99a 100644 --- a/pkg/command/version.go +++ b/pkg/command/version.go @@ -2,7 +2,7 @@ package command const ( // Version is the current Pgweb application version - Version = "0.6.0" + Version = "0.7.0" ) var ( diff --git a/pkg/statements/sql.go b/pkg/statements/sql.go index 84a94eb7cc1b22ed9e8fdfc830e13f4ff9597c90..dc30be6fd68632b5d21c868fcc6bb1251b22bac9 100644 --- a/pkg/statements/sql.go +++ b/pkg/statements/sql.go @@ -152,11 +152,15 @@ WHERE n.nspname NOT IN ('information_schema', 'pg_catalog') AND has_schema_privilege(n.nspname, 'USAGE') ORDER BY 1, 2` + + SetApplication = ` +SET application_name = 'openGauss-webclient' + ` ) var ( Activity = map[string]string{ - "default": "SELECT * FROM pg_stat_activity WHERE datname = current_database()", + "default": "SELECT datid, datname, pid, query, query_start, state, waiting, application_name, client_addr FROM pg_stat_activity WHERE datname = current_database()", "9.1": "SELECT datname, current_query, waiting, query_start, procpid as pid, datid, application_name, client_addr FROM pg_stat_activity WHERE datname = current_database()", "9.2": "SELECT datname, query, state, waiting, query_start, state_change, pid, datid, application_name, client_addr FROM pg_stat_activity WHERE datname = current_database()", "9.3": "SELECT datname, query, state, waiting, query_start, state_change, pid, datid, application_name, client_addr FROM pg_stat_activity WHERE datname = current_database()", diff --git a/static/index.html b/static/index.html index 92634ea2215b78e9cc33be962d6406b7dd1767dd..ec77e88d07c139aa03023723731be6ba4a9da4a0 100644 --- a/static/index.html +++ b/static/index.html @@ -25,12 +25,12 @@ @@ -38,15 +38,17 @@
+
@@ -81,7 +83,7 @@
  • 分析查询
  • -
    请稍后,查询执行中...
    +
    执行中...
    @@ -279,13 +281,13 @@
    diff --git a/static/js/app.js b/static/js/app.js index 20c238b86a6780c2eab1f26886259b77e12a7b1d..c3a870d68855f566dadf86087fe8033755e1f280 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -18,6 +18,29 @@ var filterOptions = { not_null: "IS NOT NULL", }; +class OperateAction { + static SHOW_QUERY_HISTORY = new OperateAction("操作历史为空"); + static SHOW_TABLE_INDEX = new OperateAction("无索引"); + static SHOW_TABLE_CONSTRAINTS = new OperateAction("无约束"); + static SHOW_TABLE_CONTENT = new OperateAction("无数据"); + static SHOW_TABLE_STRUCTURE = new OperateAction("表结构为空"); + static SHOW_CONNECTION_PANEL = new OperateAction("show connection panel"); + static SHOW_ACTIVITY_PANEL = new OperateAction("会话为空"); + static EXECUTE_QUERY = new OperateAction("执行成功"); + static EXECUTE_EXPLAIN = new OperateAction("execute explain"); + static EXECUTE_ANALYZE = new OperateAction("execute analyze"); + static SHOW_UNIQ_COLUMN_VALUES = new OperateAction("show uniq column values"); + static SHOW_FILED_NUM_STATS = new OperateAction("show field num stats"); + + constructor(empty_message) { + this.empty_message = empty_message; + } + + toString() { + return this.empty_message; + } +} + function getSessionId() { var id = sessionStorage.getItem("session_id"); @@ -71,10 +94,9 @@ function apiCall(method, path, params, cb) { }, error: function (xhr, status, data) { if (status == "timeout") { - return cb({ error: "Query timeout after " + timeout / 1000 + "s" }); + return cb({ error: "执行超时: " + timeout / 1000 + "s" }); } - - cb(jQuery.parseJSON(xhr.responseText)); + cb({ error: "抱歉,发生未知异常!"}); }, }); } @@ -264,8 +286,9 @@ function resetTable() { function performTableAction(table, action, el) { if (action == "truncate" || action == "delete") { - var message = - "Are you sure you want to " + action + " table " + table + " ?"; + var message = "确认要"; + message += (action == "truncate" ? "清空" : "删除"); + message += "表 " + table + " ?"; if (!confirm(message)) return; } @@ -319,7 +342,7 @@ function performTableAction(table, action, el) { function performViewAction(view, action, el) { if (action == "delete") { - var message = "Are you sure you want to " + action + " view " + view + " ?"; + var message = "确认要删除视图 " + view + " ?"; if (!confirm(message)) return; } @@ -376,10 +399,7 @@ function sortArrow(direction) { } } -function buildTable(results, sortColumn, sortOrder, options) { - if (!options) options = {}; - var action = options.action; - +function buildTable(results, action, sortColumn, sortOrder) { resetTable(); if (results.error) { @@ -388,9 +408,10 @@ function buildTable(results, sortColumn, sortOrder, options) { return; } + var show_message = action.toString(); if (results.rows.length == 0) { $("#results_header").html(""); - $("#results_body").html("No records found"); + $("#results_body").html("" + show_message + ""); $("#result-rows-count").html(""); $("#results").addClass("empty"); return; @@ -419,12 +440,11 @@ function buildTable(results, sortColumn, sortOrder, options) { }); // No header to make the column non-sortable - if (action) { - cols += ""; - - // Determine which column contains the data attribute - action.dataColumn = results.columns.indexOf(action.data); - } + // if (action) { + // cols += ""; + // // Determine which column contains the data attribute + // action.dataColumn = results.columns.indexOf(action.data); + // } results.rows.forEach(function (row) { var r = ""; @@ -435,19 +455,20 @@ function buildTable(results, sortColumn, sortOrder, options) { "
    " + escapeHtml(row[i]) + "
    "; } - // Add row action button - if (action) { - r += - "" + - action.title + - ""; - } + // for tryme project, we are not suppposed to do ANY ACTION on ANY CONTENTS + // Add row action button. + // if (action) { + // r += + // "" + + // action.title + + // ""; + // } rows += "" + r + ""; }); @@ -455,8 +476,8 @@ function buildTable(results, sortColumn, sortOrder, options) { $("#results_header").html(cols); $("#results_body").html(rows); - // Show number of rows rendered on the page - $("#result-rows-count").html(results.rows.length + " rows"); + // Show number of rows rendered on the page. + //$("#result-rows-count").html(results.rows.length + " rows"); } function setCurrentTab(id) { @@ -480,7 +501,7 @@ function showQueryHistory() { rows.unshift([parseInt(i) + 1, data[i].query, data[i].timestamp]); } - buildTable({ columns: ["id", "query", "timestamp"], rows: rows }); + buildTable({ columns: ["id", "query", "timestamp"], rows: rows }, OperateAction.SHOW_QUERY_HISTORY); setCurrentTab("table_history"); $("#input").hide(); @@ -499,7 +520,7 @@ function showTableIndexes() { getTableIndexes(name, function (data) { setCurrentTab("table_indexes"); - buildTable(data); + buildTable(data, OperateAction.SHOW_TABLE_INDEX); $("#input").hide(); $("#body").prop("class", "full"); @@ -517,7 +538,7 @@ function showTableConstraints() { getTableConstraints(name, function (data) { setCurrentTab("table_constraints"); - buildTable(data); + buildTable(data, OperateAction.SHOW_TABLE_CONSTRAINTS); $("#input").hide(); $("#body").prop("class", "full"); @@ -609,7 +630,7 @@ function showTableContent(sortColumn, sortOrder) { $("#input").hide(); $("#body").prop("class", "with-pagination"); - buildTable(data, sortColumn, sortOrder); + buildTable(data, OperateAction.SHOW_TABLE_CONTENT, sortColumn, sortOrder); setCurrentTab("table_content"); updatePaginator(data.pagination); @@ -644,7 +665,7 @@ function showTableStructure() { $("#body").prop("class", "full"); getTableStructure(name, { type: getCurrentObject().type }, function (data) { - buildTable(data); + buildTable(data, OperateAction.SHOW_TABLE_STRUCTURE); $("#results").addClass("no-crop"); }); } @@ -671,10 +692,7 @@ function showConnectionPanel() { rows.push([key, data[key]]); } - buildTable({ - columns: ["attribute", "value"], - rows: rows, - }); + buildTable({columns: ["attribute", "value"], rows: rows,}, OperateAction.SHOW_CONNECTION_PANEL); $("#input").hide(); $("#body").addClass("full"); @@ -682,18 +700,19 @@ function showConnectionPanel() { } function showActivityPanel() { - var options = { - action: { - name: "stop_query", - title: "stop", - data: "pid", - style: "danger", - }, - }; + // for now, we donnot expose the dangerous STOP button + // var options = { + // action: { + // name: "stop_query", + // title: "stop", + // data: "pid", + // style: "danger", + // }, + // }; setCurrentTab("table_activity"); apiCall("get", "/activity", {}, function (data) { - buildTable(data, null, null, options); + buildTable(data, OperateAction.SHOW_ACTIVITY_PANEL); $("#input").hide(); $("#body").addClass("full"); }); @@ -790,7 +809,7 @@ function runQuery() { } executeQuery(query, function (data) { - buildTable(data); + buildTable(data, OperateAction.EXECUTE_QUERY); hideQueryProgressMessage(); $("#input").show(); @@ -819,7 +838,7 @@ function runExplain() { } explainQuery(query, function (data) { - buildTable(data); + buildTable(data, OperateAction.EXECUTE_EXPLAIN); hideQueryProgressMessage(); $("#input").show(); @@ -839,7 +858,7 @@ function runAnalyze() { } analyzeQuery(query, function (data) { - buildTable(data); + buildTable(data, OperateAction.EXECUTE_ANALYZE); hideQueryProgressMessage(); $("#input").show(); @@ -889,7 +908,7 @@ function showUniqueColumnsValues(table, column, showCounts) { $("#input").hide(); $("#body").prop("class", "full"); $("#results").data("mode", "query"); - buildTable(data); + buildTable(data, OperateAction.SHOW_UNIQ_COLUMN_VALUES); }); } @@ -909,7 +928,7 @@ function showFieldNumStats(table, column) { $("#input").hide(); $("#body").prop("class", "full"); $("#results").data("mode", "query"); - buildTable(data); + buildTable(data, OperateAction.SHOW_FILED_NUM_STATS); }); } @@ -1533,12 +1552,12 @@ function start() { } }); - $("#current_database").on("click", function (e) { - apiCall("get", "/databases", {}, function (resp) { - toggleDatabaseSearch(); - enableDatabaseSearch(resp); - }); - }); + // $("#current_database").on("click", function (e) { + // apiCall("get", "/databases", {}, function (resp) { + // toggleDatabaseSearch(); + // enableDatabaseSearch(resp); + // }); + // }); $("#database_search").change(function (e) { var current = $("#database_search").typeahead("getActive"); @@ -1764,6 +1783,7 @@ function handleMessage(e) { } $(document).ready(function () { - // window.postMessage({ status: "ready" }); + //window.postMessage({ status: "ready" }); + //start(); window.addEventListener("message", handleMessage); });