Backend changes to fetch the statistics for the database and server
nodes, along with the front-end changes for those node. NOTE: We've not yet added the support to show them on the front-end.pull/3/head
parent
6f58170894
commit
8a39b3a700
|
@ -530,7 +530,32 @@ class ServerNode(PGChildNodeView):
|
|||
return make_json_response(data='')
|
||||
|
||||
def statistics(self, gid, sid):
|
||||
return make_json_response(data='')
|
||||
from pgadmin.utils.driver import get_driver
|
||||
manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
|
||||
conn = manager.connection()
|
||||
|
||||
if conn.connected():
|
||||
status, res = conn.execute_dict(
|
||||
render_template(
|
||||
"/".join([
|
||||
'servers/sql',
|
||||
'9.2_plus' if manager.version >= 90200 else '9.1_plus',
|
||||
'stats.sql'
|
||||
]),
|
||||
conn=conn, _=gettext
|
||||
)
|
||||
)
|
||||
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return make_json_response(data=res)
|
||||
|
||||
return make_json_response(
|
||||
info=gettext(
|
||||
"Server has no active connection for generating statistics!"
|
||||
)
|
||||
)
|
||||
|
||||
def dependencies(self, gid, sid):
|
||||
return make_json_response(data='')
|
||||
|
|
|
@ -148,8 +148,11 @@ class DatabaseView(PGChildNodeView):
|
|||
|
||||
@check_precondition(action="list")
|
||||
def list(self, gid, sid):
|
||||
last_system_oid = 0 if self.blueprint.show_system_objects else \
|
||||
(self.manager.db_info[self.manager.did])['datlastsysoid']
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'properties.sql'])
|
||||
"/".join([self.template_path, 'properties.sql']),
|
||||
conn=self.conn, last_system_oid=last_system_oid
|
||||
)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
|
||||
|
@ -164,8 +167,12 @@ class DatabaseView(PGChildNodeView):
|
|||
@check_precondition(action="nodes")
|
||||
def nodes(self, gid, sid):
|
||||
res = []
|
||||
last_system_oid = 0 if self.blueprint.show_system_objects else \
|
||||
(self.manager.db_info[self.manager.did])['datlastsysoid']
|
||||
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'nodes.sql'])
|
||||
"/".join([self.template_path, 'nodes.sql']),
|
||||
last_system_oid=last_system_oid
|
||||
)
|
||||
status, rset = self.conn.execute_dict(SQL)
|
||||
|
||||
|
@ -174,20 +181,20 @@ class DatabaseView(PGChildNodeView):
|
|||
|
||||
for row in rset['rows']:
|
||||
if self.manager.db == row['name']:
|
||||
connected=True
|
||||
canDisConn=False
|
||||
connected = True
|
||||
canDisConn = False
|
||||
else:
|
||||
conn=self.manager.connection(row['name'])
|
||||
connected=conn.connected()
|
||||
canDisConn=True
|
||||
conn = self.manager.connection(row['name'])
|
||||
connected = conn.connected()
|
||||
canDisConn = True
|
||||
|
||||
res.append(
|
||||
self.blueprint.generate_browser_node(
|
||||
row['did'],
|
||||
sid,
|
||||
row['name'],
|
||||
icon="icon-database-not-connected" if not connected \
|
||||
else "pg-icon-database",
|
||||
icon="icon-database-not-connected" if not connected
|
||||
else "pg-icon-database",
|
||||
connected=connected,
|
||||
tablespace=row['spcname'],
|
||||
allowConn=row['datallowconn'],
|
||||
|
@ -205,7 +212,7 @@ class DatabaseView(PGChildNodeView):
|
|||
def node(self, gid, sid, did):
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'nodes.sql']),
|
||||
did=did, conn=self.conn
|
||||
did=did, conn=self.conn, last_system_oid=0
|
||||
)
|
||||
status, rset = self.conn.execute_2darray(SQL)
|
||||
|
||||
|
@ -240,7 +247,7 @@ class DatabaseView(PGChildNodeView):
|
|||
def properties(self, gid, sid, did):
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'properties.sql']),
|
||||
did=did, conn=self.conn
|
||||
did=did, conn=self.conn, last_system_oid=0
|
||||
)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
|
||||
|
@ -466,7 +473,7 @@ class DatabaseView(PGChildNodeView):
|
|||
# We need oid of newly created database
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'properties.sql']),
|
||||
name=data['name'], conn=self.conn
|
||||
name=data['name'], conn=self.conn, last_system_oid=0
|
||||
)
|
||||
SQL = SQL.strip('\n').strip(' ')
|
||||
if SQL and SQL != "":
|
||||
|
@ -501,7 +508,9 @@ class DatabaseView(PGChildNodeView):
|
|||
def update(self, gid, sid, did):
|
||||
"""Update the database."""
|
||||
|
||||
data = request.form if request.form else json.loads(request.data.decode())
|
||||
data = request.form if request.form else json.loads(
|
||||
request.data.decode()
|
||||
)
|
||||
info = "nothing to update."
|
||||
|
||||
if did is not None:
|
||||
|
@ -509,7 +518,7 @@ class DatabaseView(PGChildNodeView):
|
|||
status, rset = self.conn.execute_dict(
|
||||
render_template(
|
||||
"/".join([self.template_path, 'nodes.sql']),
|
||||
did=did, conn=self.conn
|
||||
did=did, conn=self.conn, last_system_oid=0
|
||||
)
|
||||
)
|
||||
if not status:
|
||||
|
@ -646,7 +655,7 @@ class DatabaseView(PGChildNodeView):
|
|||
status, rset = self.conn.execute_dict(
|
||||
render_template(
|
||||
"/".join([self.template_path, 'nodes.sql']),
|
||||
did=did, conn=self.conn
|
||||
did=did, conn=self.conn, last_system_oid=0
|
||||
)
|
||||
)
|
||||
if not status:
|
||||
|
@ -775,10 +784,12 @@ class DatabaseView(PGChildNodeView):
|
|||
otherwise it will return statistics for all the databases in that
|
||||
server.
|
||||
"""
|
||||
last_system_oid = 0 if self.blueprint.show_system_objects else \
|
||||
(self.manager.db_info[self.manager.did])['datlastsysoid']
|
||||
status, res = self.conn.execute_dict(
|
||||
render_template(
|
||||
"/".join([self.template_path, 'stats.sql']),
|
||||
did=did, conn=self.conn
|
||||
did=did, conn=self.conn, last_system_oid=last_system_oid
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -786,7 +797,7 @@ class DatabaseView(PGChildNodeView):
|
|||
return internal_server_error(errormsg=res)
|
||||
|
||||
return make_json_response(
|
||||
data=res['rows'],
|
||||
data=res,
|
||||
status=200
|
||||
)
|
||||
|
||||
|
@ -797,7 +808,7 @@ class DatabaseView(PGChildNodeView):
|
|||
"""
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'properties.sql']),
|
||||
did=did, conn=self.conn
|
||||
did=did, conn=self.conn, last_system_oid=0
|
||||
)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
|
|
|
@ -11,7 +11,8 @@ function($, _, S, pgAdmin, pgBrowser, Alertify) {
|
|||
node: 'database',
|
||||
label: '{{ _('Databases') }}',
|
||||
type: 'coll-database',
|
||||
columns: ['name', 'datowner', 'comments']
|
||||
columns: ['name', 'datowner', 'comments'],
|
||||
hasStatistics: true
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -51,6 +52,7 @@ function($, _, S, pgAdmin, pgBrowser, Alertify) {
|
|||
sqlCreateHelp: 'sql-createdatabase.html',
|
||||
hasSQL: true,
|
||||
hasDepends: true,
|
||||
hasStatistics: true,
|
||||
canDrop: true,
|
||||
label: '{{ _('Database') }}',
|
||||
node_image: function() {
|
||||
|
|
|
@ -4,7 +4,9 @@ SELECT
|
|||
FROM
|
||||
pg_database db
|
||||
LEFT OUTER JOIN pg_tablespace ta ON db.dattablespace = ta.oid{% if did %}
|
||||
|
||||
WHERE db.oid={{ did|qtLiteral }}::OID{% endif %}
|
||||
WHERE {% if did %}
|
||||
db.oid = {{ did|qtLiteral }}::OID{% else %}
|
||||
db.oid > {{ last_system_oid }}::OID
|
||||
{% endif %}
|
||||
|
||||
ORDER BY datname;
|
||||
|
|
|
@ -11,10 +11,10 @@ FROM pg_database db
|
|||
LEFT OUTER JOIN pg_shdescription descr ON (
|
||||
db.oid=descr.objoid AND descr.classoid='pg_database'::regclass
|
||||
)
|
||||
{% if did %}
|
||||
WHERE db.oid= {{did}}::int
|
||||
{% endif %}
|
||||
{% if name %}
|
||||
WHERE db.datname = {{name|qtLiteral}}
|
||||
{% endif %}
|
||||
ORDER BY datname
|
||||
WHERE {% if did %}
|
||||
db.oid = {{ did|qtLiteral }}::OID{% else %}{% if name %}
|
||||
db.datname = {{ name|qtLiteral }}::text{% else %}
|
||||
db.oid > {{ last_system_oid|qtLiteral }}::OID
|
||||
{% endif %}{% endif %}
|
||||
|
||||
ORDER BY datname;
|
||||
|
|
|
@ -1,13 +1,28 @@
|
|||
SELECT
|
||||
db.datid as oid, db.datname, numbackends, xact_commit, xact_rollback, blks_read,
|
||||
blks_hit, stats_reset, slave.confl_tablespace, slave.confl_lock,
|
||||
slave.confl_snapshot, slave.confl_bufferpin, slave.confl_deadlock{% if has_size %},
|
||||
pg_size_pretty(pg_database_size(db.datid)) as size
|
||||
{% if not did %}db.datname AS {{ conn|qtIdent(_('Database')) }}, {% endif %}
|
||||
numbackends AS {{ conn|qtIdent(_('Backends')) }},
|
||||
xact_commit AS {{ conn|qtIdent(_('Xact Committed')) }},
|
||||
xact_rollback AS {{ conn|qtIdent(_('Xact Rolled back')) }},
|
||||
blks_read AS {{ conn|qtIdent(_('Blocks Read')) }},
|
||||
blks_hit AS {{ conn|qtIdent(_('Blocks Hit')) }},
|
||||
tup_returned AS {{ conn|qtIdent(_('Tuples Returned')) }},
|
||||
tup_fetched AS {{ conn|qtIdent(_('Tuples Fetched')) }},
|
||||
tup_inserted AS {{ conn|qtIdent(_('Tuples Inserted')) }},
|
||||
tup_updated AS {{ conn|qtIdent(_('Tuples Updated')) }},
|
||||
tup_deleted AS {{ conn|qtIdent(_('Tuples Deleted')) }},
|
||||
stats_reset AS {{ conn|qtIdent(_('Last statistics reset')) }},
|
||||
slave.confl_tablespace AS {{ conn|qtIdent(_('Tablespace conflicts')) }},
|
||||
slave.confl_lock AS {{ conn|qtIdent(_('Lock conflicts')) }},
|
||||
slave.confl_snapshot AS {{ conn|qtIdent(_('Snapshot conflicts')) }},
|
||||
slave.confl_bufferpin AS {{ conn|qtIdent(_('Bufferpin conflicts')) }},
|
||||
slave.confl_deadlock AS {{ conn|qtIdent(_('Deadlock conflicts')) }},
|
||||
pg_size_pretty(pg_database_size(db.datid)) AS {{ conn|qtIdent(_('Size')) }}
|
||||
FROM
|
||||
pg_stat_database db
|
||||
LEFT JOIN pg_stat_database_conflicts slave ON db.datid=slave.datid
|
||||
{% if did %}
|
||||
WHERE
|
||||
did = {{ conn|qtIdent(did) }}::OID
|
||||
WHERE {% if did %}
|
||||
db.datid = {{ did|qtLiteral }}::OID{% else %}
|
||||
db.datid > {{ last_system_oid|qtLiteral }}::OID
|
||||
{% endif %}
|
||||
|
||||
ORDER BY db.datname;
|
||||
|
|
|
@ -3,8 +3,10 @@ SELECT
|
|||
has_database_privilege(db.oid, 'CREATE') as cancreate, datdba as owner
|
||||
FROM
|
||||
pg_database db
|
||||
LEFT OUTER JOIN pg_tablespace ta ON db.dattablespace = ta.oid{% if did %}
|
||||
LEFT OUTER JOIN pg_tablespace ta ON db.dattablespace = ta.oid
|
||||
WHERE {% if did %}
|
||||
db.oid = {{ did|qtLiteral }}::OID{% else %}
|
||||
db.oid > {{ last_system_oid }}::OID
|
||||
{% endif %}
|
||||
|
||||
WHERE db.oid={{ did|qtLiteral }}::OID {% endif %}
|
||||
|
||||
ORDER BY datname;
|
||||
ORDER BY datname;
|
||||
|
|
|
@ -12,10 +12,10 @@ FROM pg_database db
|
|||
LEFT OUTER JOIN pg_shdescription descr ON (
|
||||
db.oid=descr.objoid AND descr.classoid='pg_database'::regclass
|
||||
)
|
||||
{% if did %}
|
||||
WHERE db.oid= {{did}}::int
|
||||
{% endif %}
|
||||
{% if name %}
|
||||
WHERE db.datname = {{name|qtLiteral}}
|
||||
{% endif %}
|
||||
WHERE {% if did %}
|
||||
db.oid = {{ did|qtLiteral }}::OID{% else %}{% if name %}
|
||||
db.datname = {{ name|qtLiteral }}::text{% else %}
|
||||
db.oid > {{ last_system_oid|qtLiteral }}::OID
|
||||
{% endif %}{% endif %}
|
||||
|
||||
ORDER BY datname
|
||||
|
|
|
@ -1,13 +1,33 @@
|
|||
SELECT
|
||||
db.datid as oid, db.datname, numbackends, xact_commit, xact_rollback, blks_read,
|
||||
blks_hit, stats_reset, slave.confl_tablespace, slave.confl_lock,
|
||||
slave.confl_snapshot, slave.confl_bufferpin, slave.confl_deadlock{% if has_size %},
|
||||
pg_size_pretty(pg_database_size(db.datid)) as size
|
||||
{% if not did %}db.datname AS {{ conn|qtIdent(_('Database')) }}, {% endif %}
|
||||
numbackends AS {{ conn|qtIdent(_('Backends')) }},
|
||||
xact_commit AS {{ conn|qtIdent(_('Xact Committed')) }},
|
||||
xact_rollback AS {{ conn|qtIdent(_('Xact Rolled back')) }},
|
||||
blks_read AS {{ conn|qtIdent(_('Blocks Read')) }},
|
||||
blks_hit AS {{ conn|qtIdent(_('Blocks Hit')) }},
|
||||
tup_returned AS {{ conn|qtIdent(_('Tuples Returned')) }},
|
||||
tup_fetched AS {{ conn|qtIdent(_('Tuples Fetched')) }},
|
||||
tup_inserted AS {{ conn|qtIdent(_('Tuples Inserted')) }},
|
||||
tup_updated AS {{ conn|qtIdent(_('Tuples Updated')) }},
|
||||
tup_deleted AS {{ conn|qtIdent(_('Tuples Deleted')) }},
|
||||
stats_reset AS {{ conn|qtIdent(_('Last statistics reset')) }},
|
||||
slave.confl_tablespace AS {{ conn|qtIdent(_('Tablespace conflicts')) }},
|
||||
slave.confl_lock AS {{ conn|qtIdent(_('Lock conflicts')) }},
|
||||
slave.confl_snapshot AS {{ conn|qtIdent(_('Snapshot conflicts')) }},
|
||||
slave.confl_bufferpin AS {{ conn|qtIdent(_('Bufferpin conflicts')) }},
|
||||
slave.confl_deadlock AS {{ conn|qtIdent(_('Deadlock conflicts')) }},
|
||||
temp_files AS {{ conn|qtIdent(_("Temporary files")) }},
|
||||
pg_size_pretty(temp_bytes) AS {{ conn|qtIdent(_("Size of temporary files")) }},
|
||||
deadlocks AS {{ conn|qtIdent(_("Deadlocks")) }},
|
||||
blk_read_time AS {{ conn|qtIdent(_("Block read time")) }},
|
||||
blk_write_time AS {{ conn|qtIdent(_("Block write time")) }},
|
||||
pg_size_pretty(pg_database_size(db.datid)) AS {{ conn|qtIdent(_('Size')) }}
|
||||
FROM
|
||||
pg_stat_database db
|
||||
LEFT JOIN pg_stat_database_conflicts slave ON db.datid=slave.datid
|
||||
{% if did %}
|
||||
WHERE
|
||||
did = {{ conn|qtIdent(did) }}::OID
|
||||
WHERE {% if did %}
|
||||
db.datid = {{ did|qtLiteral }}::OID{% else %}
|
||||
db.datid > {{ last_system_oid|qtLiteral }}::OID
|
||||
{% endif %}
|
||||
|
||||
ORDER BY db.datname;
|
||||
|
|
|
@ -3,8 +3,10 @@ SELECT
|
|||
has_database_privilege(db.oid, 'CREATE') as cancreate, datdba as owner
|
||||
FROM
|
||||
pg_database db
|
||||
LEFT OUTER JOIN pg_tablespace ta ON db.dattablespace = ta.oid{% if did %}
|
||||
|
||||
WHERE db.oid={{ did|qtLiteral }}::OID{% endif %}
|
||||
LEFT OUTER JOIN pg_tablespace ta ON db.dattablespace = ta.oid
|
||||
WHERE {% if did %}
|
||||
db.oid = {{ did|qtLiteral }}::OID{% else %}
|
||||
db.oid > {{ last_system_oid }}::OID
|
||||
{% endif %}
|
||||
|
||||
ORDER BY datname;
|
||||
|
|
|
@ -12,10 +12,10 @@ FROM pg_database db
|
|||
LEFT OUTER JOIN pg_shdescription descr ON (
|
||||
db.oid=descr.objoid AND descr.classoid='pg_database'::regclass
|
||||
)
|
||||
{% if did %}
|
||||
WHERE db.oid= {{did}}::int
|
||||
{% endif %}
|
||||
{% if name %}
|
||||
WHERE db.datname = {{name|qtLiteral}}
|
||||
{% endif %}
|
||||
WHERE {% if did %}
|
||||
db.oid = {{ did|qtLiteral }}::OID{% else %}{% if name %}
|
||||
db.datname = {{ name|qtLiteral }}::text{% else %}
|
||||
db.oid > {{ last_system_oid|qtLiteral }}::OID
|
||||
{% endif %}{% endif %}
|
||||
|
||||
ORDER BY datname
|
||||
|
|
|
@ -1,13 +1,33 @@
|
|||
SELECT
|
||||
db.datid as oid, db.datname, numbackends, xact_commit, xact_rollback, blks_read,
|
||||
blks_hit, stats_reset, slave.confl_tablespace, slave.confl_lock,
|
||||
slave.confl_snapshot, slave.confl_bufferpin, slave.confl_deadlock{% if has_size %},
|
||||
pg_size_pretty(pg_database_size(db.datid)) as size
|
||||
{% if not did %}db.datname AS {{ conn|qtIdent(_('Database')) }}, {% endif %}
|
||||
numbackends AS {{ conn|qtIdent(_('Backends')) }},
|
||||
xact_commit AS {{ conn|qtIdent(_('Xact Committed')) }},
|
||||
xact_rollback AS {{ conn|qtIdent(_('Xact Rolled back')) }},
|
||||
blks_read AS {{ conn|qtIdent(_('Blocks Read')) }},
|
||||
blks_hit AS {{ conn|qtIdent(_('Blocks Hit')) }},
|
||||
tup_returned AS {{ conn|qtIdent(_('Tuples Returned')) }},
|
||||
tup_fetched AS {{ conn|qtIdent(_('Tuples Fetched')) }},
|
||||
tup_inserted AS {{ conn|qtIdent(_('Tuples Inserted')) }},
|
||||
tup_updated AS {{ conn|qtIdent(_('Tuples Updated')) }},
|
||||
tup_deleted AS {{ conn|qtIdent(_('Tuples Deleted')) }},
|
||||
stats_reset AS {{ conn|qtIdent(_('Last statistics reset')) }},
|
||||
slave.confl_tablespace AS {{ conn|qtIdent(_('Tablespace conflicts')) }},
|
||||
slave.confl_lock AS {{ conn|qtIdent(_('Lock conflicts')) }},
|
||||
slave.confl_snapshot AS {{ conn|qtIdent(_('Snapshot conflicts')) }},
|
||||
slave.confl_bufferpin AS {{ conn|qtIdent(_('Bufferpin conflicts')) }},
|
||||
slave.confl_deadlock AS {{ conn|qtIdent(_('Deadlock conflicts')) }},
|
||||
temp_files AS {{ conn|qtIdent(_("Temporary files")) }},
|
||||
pg_size_pretty(temp_bytes) AS {{ conn|qtIdent(_("Size of temporary files")) }},
|
||||
deadlocks AS {{ conn|qtIdent(_("Deadlocks")) }},
|
||||
blk_read_time AS {{ conn|qtIdent(_("Block read time")) }},
|
||||
blk_write_time AS {{ conn|qtIdent(_("Block write time")) }},
|
||||
pg_size_pretty(pg_database_size(db.datid)) AS {{ conn|qtIdent(_('Size')) }}
|
||||
FROM
|
||||
pg_stat_database db
|
||||
LEFT JOIN pg_stat_database_conflicts slave ON db.datid=slave.datid
|
||||
{% if did %}
|
||||
WHERE
|
||||
did = {{ conn|qtIdent(did) }}::OID
|
||||
WHERE {% if did %}
|
||||
db.datid = {{ did|qtLiteral }}::OID{% else %}
|
||||
db.datid > {{ last_system_oid|qtLiteral }}::OID
|
||||
{% endif %}
|
||||
|
||||
ORDER BY db.datname;
|
||||
|
|
|
@ -8,6 +8,8 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
|
|||
type: 'server',
|
||||
label: '{{ _('Server') }}',
|
||||
canDrop: true,
|
||||
hasStatistics: true,
|
||||
hasCollectiveStatistics: true,
|
||||
Init: function() {
|
||||
|
||||
/* Avoid multiple registration of same menus */
|
||||
|
|
|
@ -12,7 +12,11 @@ function($, _, S, pgAdmin, Backbone, Alertify, Backform) {
|
|||
if (pgBrowser.Collection)
|
||||
return pgBrowser.Collection;
|
||||
|
||||
pgBrowser.Collection = _.extend(_.clone(pgBrowser.Node), {
|
||||
pgBrowser.Collection = function() {};
|
||||
|
||||
_.extend(
|
||||
pgBrowser.Collection,
|
||||
_.clone(pgBrowser.Node), {
|
||||
///////
|
||||
// Initialization function
|
||||
// Generally - used to register the menus for this type of node.
|
||||
|
@ -34,6 +38,9 @@ function($, _, S, pgAdmin, Backbone, Alertify, Backform) {
|
|||
}]);
|
||||
},
|
||||
hasId: false,
|
||||
// A collection will always have a collection of statistics, when the node
|
||||
// it represent will have some statistics.
|
||||
hasCollectiveStatistics: true,
|
||||
showProperties: function(item, data, panel) {
|
||||
var that = this,
|
||||
j = panel.$container.find('.obj_properties').first(),
|
||||
|
@ -133,5 +140,5 @@ function($, _, S, pgAdmin, Backbone, Alertify, Backform) {
|
|||
}
|
||||
});
|
||||
|
||||
return pgAdmin.Browser.Collection;
|
||||
return pgBrowser.Collection;
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue