mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Resolved few issues (with some improvements) with existing nodes.
This commit takes care of the following issues/improvements. * Adding missing imports for unauthorised in database module * Node under Servers Nodes (i.e. Databases, tablespaces, roles nodes) need to be inherited from PGChildNodeView (and, not from NodeView) for adding server version check for their children. * Adding statistics for database, and tablespaces in its node (not, yet in UI) * Renaming the camel case methods with proper name. (i.e. getSQL -> get_sql, getNewSQL -> get_new_sql, etc.) * Fixed the functions going beyond the text limit (column: 80) in Databases, Roles & Tablespaces modules. * Fixed the node method of Database module, which was not tested ever. * We do not need separate SQL template for fetching the name (i.e. get_name.sql), using the 'nodes.sql' for the same. * Optimise the query for fetching ACLs for the database node, we didn't require to join certain tables, while fetching only the ACLs. * Introduced the list of the ACLs (regular and default ACLs for different type) supported by each version [Databases Module]. * Renamed the templates 'get_nodes.sql' to' nodes.sql' to make it consistent with other modules. * Removed the checks for the authentication table use, as we don't need to expose the password to the users (even the encrypted MD5). Using the pg_roles view always for fetching roles/users information now. * Resolved some typos in unreachable (specially the exceptions catchment area.) * Logging the exception in the application. * Using qtLiteral, qtIdent properly in the templates (do not assume about the types of data.) * Using tsid as identifier instead of did for the tablespaces. * Using nodes method of tablespace view for fetching individual node information. * Removing the hardcoded node information from the 'parse_priv_to_db' function, and pass on allowed ACLs by the caller nodes. * Using 'nodes.sql' to fetch name of the template instead of writing that in the delete.sql template, which is definitely wrong place to fetch the name of the object. [Tablespace Module]
This commit is contained in:
parent
9274d87c55
commit
d5da26876b
web/pgadmin
browser/server_groups/servers
databases
__init__.py
templates/databases/sql
roles
__init__.py
templates/role/sql
tablespaces
__init__.py
utils.pytemplates/tablespaces/sql
utils/driver/psycopg2
@ -10,16 +10,17 @@ import json
|
||||
from flask import render_template, make_response, current_app, request, jsonify
|
||||
from flask.ext.babel import gettext as _
|
||||
from pgadmin.utils.ajax import make_json_response, \
|
||||
make_response as ajax_response, internal_server_error
|
||||
from pgadmin.browser.utils import NodeView
|
||||
make_response as ajax_response, internal_server_error, unauthorized
|
||||
from pgadmin.browser.utils import PGChildNodeView
|
||||
from pgadmin.browser.server_groups.servers.utils import parse_priv_from_db, \
|
||||
parse_priv_to_db
|
||||
from pgadmin.browser.collection import CollectionNodeModule
|
||||
import pgadmin.browser.server_groups.servers as servers
|
||||
from pgadmin.utils.ajax import precondition_required
|
||||
from pgadmin.utils.ajax import precondition_required, gone
|
||||
from pgadmin.utils.driver import get_driver
|
||||
from config import PG_DEFAULT_DRIVER
|
||||
from functools import wraps
|
||||
import re
|
||||
|
||||
class DatabaseModule(CollectionNodeModule):
|
||||
NODE_TYPE = 'database'
|
||||
@ -72,7 +73,7 @@ class DatabaseModule(CollectionNodeModule):
|
||||
blueprint = DatabaseModule(__name__)
|
||||
|
||||
|
||||
class DatabaseView(NodeView):
|
||||
class DatabaseView(PGChildNodeView):
|
||||
node_type = blueprint.node_type
|
||||
|
||||
parent_ids = [
|
||||
@ -91,7 +92,7 @@ class DatabaseView(NodeView):
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
'msql': [{'get': 'msql'}, {'get': 'msql'}],
|
||||
'stats': [{'get': 'statistics'}],
|
||||
'stats': [{'get': 'statistics'}, {'get': 'statistics'}],
|
||||
'dependency': [{'get': 'dependencies'}],
|
||||
'dependent': [{'get': 'dependents'}],
|
||||
'children': [{'get': 'children'}],
|
||||
@ -99,8 +100,8 @@ class DatabaseView(NodeView):
|
||||
'connect': [{
|
||||
'get': 'connect_status', 'post': 'connect', 'delete': 'disconnect'
|
||||
}],
|
||||
'get_encodings': [{'get': 'getEncodings'}, {'get': 'getEncodings'}],
|
||||
'get_ctypes': [{'get': 'getCtypes'}, {'get': 'getCtypes'}],
|
||||
'get_encodings': [{'get': 'get_encodings'}, {'get': 'get_encodings'}],
|
||||
'get_ctypes': [{'get': 'get_ctypes'}, {'get': 'get_ctypes'}],
|
||||
'vopts': [{}, {'get': 'variable_options'}]
|
||||
})
|
||||
|
||||
@ -124,10 +125,8 @@ class DatabaseView(NodeView):
|
||||
# If DB not connected then return error to browser
|
||||
if not self.conn.connected():
|
||||
return precondition_required(
|
||||
_(
|
||||
"Connection to the server has been lost!"
|
||||
_("Connection to the server has been lost!")
|
||||
)
|
||||
)
|
||||
|
||||
ver = self.manager.version
|
||||
# we will set template path for sql scripts
|
||||
@ -143,7 +142,9 @@ class DatabaseView(NodeView):
|
||||
|
||||
@check_precondition(action="list")
|
||||
def list(self, gid, sid):
|
||||
SQL = render_template("/".join([self.template_path, 'properties.sql']))
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'properties.sql'])
|
||||
)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
|
||||
if not status:
|
||||
@ -157,8 +158,10 @@ class DatabaseView(NodeView):
|
||||
@check_precondition(action="nodes")
|
||||
def nodes(self, gid, sid):
|
||||
res = []
|
||||
SQL = render_template("/".join([self.template_path, 'get_nodes.sql']))
|
||||
status, rset = self.conn.execute_2darray(SQL)
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'nodes.sql'])
|
||||
)
|
||||
status, rset = self.conn.execute_dict(SQL)
|
||||
|
||||
if not status:
|
||||
return internal_server_error(errormsg=rset)
|
||||
@ -194,7 +197,10 @@ class DatabaseView(NodeView):
|
||||
|
||||
@check_precondition(action="node")
|
||||
def node(self, gid, sid, did):
|
||||
SQL = render_template("/".join([self.template_path, 'get_nodes.sql']), did=did)
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'nodes.sql']),
|
||||
did=did, conn=self.conn
|
||||
)
|
||||
status, rset = self.conn.execute_2darray(SQL)
|
||||
|
||||
if not status:
|
||||
@ -205,7 +211,7 @@ class DatabaseView(NodeView):
|
||||
connected=True
|
||||
else:
|
||||
conn=self.manager.connection(row['name'])
|
||||
connected=self.conn.connected()
|
||||
connected=conn.connected()
|
||||
return make_json_response(
|
||||
data=self.blueprint.generate_browser_node(
|
||||
row['did'],
|
||||
@ -220,22 +226,35 @@ class DatabaseView(NodeView):
|
||||
),
|
||||
status=200
|
||||
)
|
||||
|
||||
return gone(errormsg=_("Couldn't find the database in the server!"))
|
||||
|
||||
|
||||
@check_precondition(action="properties")
|
||||
def properties(self, gid, sid, did):
|
||||
SQL = render_template("/".join([self.template_path, 'properties.sql']), did=did)
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'properties.sql']),
|
||||
did=did, conn=self.conn
|
||||
)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
SQL = render_template("/".join([self.template_path, 'acl.sql']), did=did)
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'acl.sql']),
|
||||
did=did, conn=self.conn
|
||||
)
|
||||
status, dataclres = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
res = self.formatdbacl(res, dataclres['rows'])
|
||||
|
||||
SQL = render_template("/".join([self.template_path, 'defacl.sql']), did=did)
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'defacl.sql']),
|
||||
did=did, conn=self.conn
|
||||
)
|
||||
status, defaclres = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
@ -244,7 +263,10 @@ class DatabaseView(NodeView):
|
||||
|
||||
result = res['rows'][0]
|
||||
# Fetching variable for database
|
||||
SQL = render_template("/".join([self.template_path, 'get_variables.sql']), did=did)
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'get_variables.sql']),
|
||||
did=did, conn=self.conn
|
||||
)
|
||||
|
||||
status, res1 = self.conn.execute_dict(SQL)
|
||||
|
||||
@ -355,15 +377,17 @@ class DatabaseView(NodeView):
|
||||
}
|
||||
)
|
||||
|
||||
@check_precondition(action="getEncodings")
|
||||
def getEncodings(self, gid, sid, did=None):
|
||||
@check_precondition(action="get_encodings")
|
||||
def get_encodings(self, gid, sid, did=None):
|
||||
"""
|
||||
This function to return list of avialable encodings
|
||||
"""
|
||||
res = [{ 'label': '', 'value': '' }]
|
||||
try:
|
||||
SQL = render_template("/".join([self.template_path, 'get_encodings.sql']))
|
||||
status, rset = self.conn.execute_2darray(SQL)
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'get_encodings.sql'])
|
||||
)
|
||||
status, rset = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
@ -380,8 +404,8 @@ class DatabaseView(NodeView):
|
||||
except Exception as e:
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
@check_precondition(action="getCtypes")
|
||||
def getCtypes(self, gid, sid, did=None):
|
||||
@check_precondition(action="get_ctypes")
|
||||
def get_ctypes(self, gid, sid, did=None):
|
||||
"""
|
||||
This function to return list of available collation/character types
|
||||
"""
|
||||
@ -392,16 +416,16 @@ class DatabaseView(NodeView):
|
||||
{'label': val, 'value': val}
|
||||
)
|
||||
try:
|
||||
SQL = render_template("/".join([self.template_path, 'get_ctypes.sql']))
|
||||
status, rset = self.conn.execute_2darray(SQL)
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'get_ctypes.sql'])
|
||||
)
|
||||
status, rset = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
for row in rset['rows']:
|
||||
if row['cname'] not in default_list:
|
||||
res.append(
|
||||
{ 'label': row['cname'], 'value': row['cname'] }
|
||||
)
|
||||
res.append({'label': row['cname'], 'value': row['cname']})
|
||||
|
||||
return make_json_response(
|
||||
data=res,
|
||||
@ -431,7 +455,10 @@ class DatabaseView(NodeView):
|
||||
)
|
||||
try:
|
||||
# The below SQL will execute CREATE DDL only
|
||||
SQL = render_template("/".join([self.template_path, 'create.sql']), data=data, conn=self.conn)
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'create.sql']),
|
||||
data=data, conn=self.conn
|
||||
)
|
||||
status, msg = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=msg)
|
||||
@ -440,7 +467,10 @@ class DatabaseView(NodeView):
|
||||
data['datacl'] = parse_priv_to_db(data['datacl'], 'DATABASE')
|
||||
|
||||
# The below SQL will execute rest DMLs because we can not execute CREATE with any other
|
||||
SQL = render_template("/".join([self.template_path, 'grant.sql']), data=data, conn=self.conn)
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'grant.sql']),
|
||||
data=data, conn=self.conn
|
||||
)
|
||||
SQL = SQL.strip('\n').strip(' ')
|
||||
if SQL and SQL != "":
|
||||
status, msg = self.conn.execute_scalar(SQL)
|
||||
@ -448,7 +478,10 @@ class DatabaseView(NodeView):
|
||||
return internal_server_error(errormsg=msg)
|
||||
|
||||
# We need oid of newly created database
|
||||
SQL = render_template("/".join([self.template_path, 'properties.sql']), name=data['name'])
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'properties.sql']),
|
||||
name=data['name'], conn=self.conn
|
||||
)
|
||||
SQL = SQL.strip('\n').strip(' ')
|
||||
if SQL and SQL != "":
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
@ -487,20 +520,29 @@ class DatabaseView(NodeView):
|
||||
|
||||
if did is not None:
|
||||
# Fetch the name of database for comparison
|
||||
SQL = render_template("/".join([self.template_path, 'get_name.sql']), did=did)
|
||||
status, name = self.conn.execute_scalar(SQL)
|
||||
status, rset = self.conn.execute_dict(
|
||||
render_template(
|
||||
"/".join([self.template_path, 'nodes.sql']),
|
||||
did=did, conn=self.conn
|
||||
)
|
||||
)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=name)
|
||||
return internal_server_error(errormsg=rset)
|
||||
|
||||
data['old_name'] = name
|
||||
if len(rset['rows']) == 0:
|
||||
return gone(
|
||||
_("Couldn't find the database on the server!")
|
||||
)
|
||||
|
||||
data['old_name'] = (rset['rows'][0])['name']
|
||||
if 'name' not in data:
|
||||
data['name'] = name
|
||||
data['name'] = data['old_name']
|
||||
|
||||
try:
|
||||
status = self.manager.release(did=did)
|
||||
conn = self.manager.connection()
|
||||
for action in ["rename_database", "tablespace"]:
|
||||
SQL = self.getOfflineSQL(gid, sid, data, did, action)
|
||||
SQL = self.get_offline_sql(gid, sid, data, did, action)
|
||||
SQL = SQL.strip('\n').strip(' ')
|
||||
if SQL and SQL != "":
|
||||
status, msg = conn.execute_scalar(SQL)
|
||||
@ -512,7 +554,7 @@ class DatabaseView(NodeView):
|
||||
self.conn = self.manager.connection(database=data['name'], auto_reconnect=True)
|
||||
status, errmsg = self.conn.connect()
|
||||
|
||||
SQL = self.getOnlineSQL(gid, sid, data, did)
|
||||
SQL = self.get_online_sql(gid, sid, data, did)
|
||||
SQL = SQL.strip('\n').strip(' ')
|
||||
if SQL and SQL != "":
|
||||
status, msg = self.conn.execute_scalar(SQL)
|
||||
@ -543,7 +585,10 @@ class DatabaseView(NodeView):
|
||||
"""Delete the database."""
|
||||
try:
|
||||
default_conn = self.manager.connection()
|
||||
SQL = render_template("/".join([self.template_path, 'delete.sql']), did=did)
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'delete.sql']),
|
||||
did=did, conn=self.conn
|
||||
)
|
||||
status, res = default_conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
@ -559,7 +604,10 @@ class DatabaseView(NodeView):
|
||||
|
||||
status = self.manager.release(did=did)
|
||||
|
||||
SQL = render_template("/".join([self.template_path, 'delete.sql']), datname=res, conn=self.conn)
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'delete.sql']),
|
||||
datname=res, conn=self.conn
|
||||
)
|
||||
|
||||
status, msg = default_conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
@ -587,40 +635,57 @@ class DatabaseView(NodeView):
|
||||
except ValueError:
|
||||
data[k] = v
|
||||
try:
|
||||
SQL = self.getSQL(gid, sid, data, did)
|
||||
SQL = SQL.strip('\n').strip(' ')
|
||||
status, res = self.get_sql(gid, sid, data, did)
|
||||
|
||||
if not status:
|
||||
return res
|
||||
|
||||
SQL = res.strip('\n').strip(' ')
|
||||
|
||||
return make_json_response(
|
||||
data=SQL,
|
||||
status=200
|
||||
)
|
||||
except Exception as e:
|
||||
current_app.logger.exception(e)
|
||||
return make_json_response(
|
||||
data="-- modified SQL",
|
||||
status=200
|
||||
)
|
||||
|
||||
def getSQL(self, gid, sid, data, did=None):
|
||||
def get_sql(self, gid, sid, data, did=None):
|
||||
SQL = ''
|
||||
if did is not None:
|
||||
# Fetch the name of database for comparison
|
||||
SQL = render_template("/".join([self.template_path, 'get_name.sql']), did=did)
|
||||
status, name = self.conn.execute_scalar(SQL)
|
||||
status, rset = self.conn.execute_dict(
|
||||
render_template(
|
||||
"/".join([self.template_path, 'nodes.sql']),
|
||||
did=did, conn=self.conn
|
||||
)
|
||||
)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=name)
|
||||
return False, internal_server_error(errormsg=rset)
|
||||
|
||||
data['old_name'] = name
|
||||
if len(rset['rows']) == 0:
|
||||
return False, gone(
|
||||
_("Couldn't find the database on the server!")
|
||||
)
|
||||
|
||||
data['old_name'] = (rset['rows'][0])['name']
|
||||
if 'name' not in data:
|
||||
data['name'] = name
|
||||
data['name'] = data['old_name']
|
||||
|
||||
SQL = ''
|
||||
for action in ["rename_database", "tablespace"]:
|
||||
SQL += self.getOfflineSQL(gid, sid, data, did, action)
|
||||
SQL += self.get_offline_sql(gid, sid, data, did, action)
|
||||
|
||||
SQL += self.getOnlineSQL(gid, sid, data, did)
|
||||
SQL += self.get_online_sql(gid, sid, data, did)
|
||||
else:
|
||||
SQL += self.getNewSQL(gid, sid, data, did)
|
||||
return SQL
|
||||
SQL += self.get_new_sql(gid, sid, data, did)
|
||||
|
||||
def getNewSQL(self, gid, sid, data, did=None):
|
||||
return True, SQL
|
||||
|
||||
def get_new_sql(self, gid, sid, data, did=None):
|
||||
"""
|
||||
Generates sql for creating new database.
|
||||
"""
|
||||
@ -630,52 +695,84 @@ class DatabaseView(NodeView):
|
||||
|
||||
for arg in required_args:
|
||||
if arg not in data:
|
||||
return " -- definition incomplete"
|
||||
return _(" -- definition incomplete")
|
||||
|
||||
acls = []
|
||||
try:
|
||||
acls = render_template(
|
||||
"/".join([self.template_path, 'allowed_privs.json'])
|
||||
)
|
||||
acls = json.loads(acls)
|
||||
except Exception as e:
|
||||
current_app.logger.exception(e)
|
||||
|
||||
# Privileges
|
||||
if 'datacl' in data:
|
||||
data['datacl'] = parse_priv_to_db(data['datacl'], 'DATABASE')
|
||||
for aclcol in acls:
|
||||
if aclcol in data:
|
||||
allowedacl = acls[aclcol]
|
||||
data[aclcol] = parse_priv_to_db(
|
||||
data[aclcol], allowedacl['acl']
|
||||
)
|
||||
|
||||
# Default privileges
|
||||
for key in ['deftblacl', 'defseqacl', 'deffuncacl', 'deftypeacl']:
|
||||
if key in data and data[key] is not None:
|
||||
data[key] = parse_priv_to_db(data[key])
|
||||
|
||||
SQL = render_template("/".join([self.template_path, 'create.sql']), data=data)
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'create.sql']),
|
||||
data=data, conn=self.conn
|
||||
)
|
||||
SQL += "\n"
|
||||
SQL += render_template("/".join([self.template_path, 'grant.sql']), data=data)
|
||||
SQL += render_template(
|
||||
"/".join([self.template_path, 'grant.sql']),
|
||||
data=data, conn=self.conn
|
||||
)
|
||||
return SQL
|
||||
|
||||
def getOnlineSQL(self, gid, sid, data, did=None):
|
||||
def get_online_sql(self, gid, sid, data, did=None):
|
||||
"""
|
||||
Generates sql for altering database which don not require
|
||||
database to be disconnected before applying.
|
||||
"""
|
||||
acls = []
|
||||
try:
|
||||
acls = render_template(
|
||||
"/".join([self.template_path, 'allowed_privs.json'])
|
||||
)
|
||||
acls = json.loads(acls)
|
||||
except Exception as e:
|
||||
current_app.logger.exception(e)
|
||||
|
||||
for key in ['datacl', 'deftblacl', 'defseqacl', 'deffuncacl', 'deftypeacl']:
|
||||
if key in data and data[key] is not None:
|
||||
if 'added' in data[key]:
|
||||
data[key]['added'] = parse_priv_to_db(data[key]['added'])
|
||||
if 'changed' in data[key]:
|
||||
data[key]['changed'] = parse_priv_to_db(data[key]['changed'])
|
||||
if 'deleted' in data[key]:
|
||||
data[key]['deleted'] = parse_priv_to_db(data[key]['deleted'])
|
||||
# Privileges
|
||||
for aclcol in acls:
|
||||
if aclcol in data:
|
||||
allowedacl = acls[aclcol]
|
||||
|
||||
return render_template("/".join([self.template_path, 'alter_online.sql']), data=data, conn=self.conn)
|
||||
for key in ['added', 'changed', 'deleted']:
|
||||
if key in data[aclcol]:
|
||||
data[aclcol][key] = parse_priv_to_db(
|
||||
data[aclcol][key], allowedacl['acl']
|
||||
)
|
||||
|
||||
def getOfflineSQL(self, gid, sid, data, did=None, action=None):
|
||||
return render_template(
|
||||
"/".join([self.template_path, 'alter_online.sql']),
|
||||
data=data, conn=self.conn
|
||||
)
|
||||
|
||||
def get_offline_sql(self, gid, sid, data, did=None, action=None):
|
||||
"""
|
||||
Generates sql for altering database which require
|
||||
database to be disconnected before applying.
|
||||
"""
|
||||
|
||||
return render_template("/".join([self.template_path, 'alter_offline.sql']),
|
||||
data=data, conn=self.conn, action=action)
|
||||
return render_template(
|
||||
"/".join([self.template_path, 'alter_offline.sql']),
|
||||
data=data, conn=self.conn, action=action
|
||||
)
|
||||
|
||||
@check_precondition(action="variable_options")
|
||||
def variable_options(self, gid, sid):
|
||||
res = []
|
||||
SQL = render_template("/".join([self.template_path, 'variables.sql']))
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'variables.sql'])
|
||||
)
|
||||
status, rset = self.conn.execute_dict(SQL)
|
||||
|
||||
if not status:
|
||||
return internal_server_error(errormsg=rset)
|
||||
|
||||
@ -684,23 +781,55 @@ class DatabaseView(NodeView):
|
||||
status=200
|
||||
)
|
||||
|
||||
@check_precondition()
|
||||
def statistics(self, gid, sid, did=None):
|
||||
"""
|
||||
statistics
|
||||
Returns the statistics for a particular database if did is specified,
|
||||
otherwise it will return statistics for all the databases in that
|
||||
server.
|
||||
"""
|
||||
status, res = self.conn.execute_dict(
|
||||
render_template(
|
||||
"/".join([self.template_path, 'stats.sql']),
|
||||
did=did, conn=self.conn
|
||||
)
|
||||
)
|
||||
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return make_json_response(
|
||||
data=res['rows'],
|
||||
status=200
|
||||
)
|
||||
|
||||
@check_precondition(action="sql")
|
||||
def sql(self, gid, sid, did):
|
||||
"""
|
||||
This function will generate sql for sql panel
|
||||
"""
|
||||
SQL = render_template("/".join([self.template_path, 'properties.sql']), did=did)
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'properties.sql']),
|
||||
did=did, conn=self.conn
|
||||
)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
SQL = render_template("/".join([self.template_path, 'acl.sql']), did=did)
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'acl.sql']),
|
||||
did=did, conn=self.conn
|
||||
)
|
||||
status, dataclres = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
res = self.formatdbacl(res, dataclres['rows'])
|
||||
|
||||
SQL = render_template("/".join([self.template_path, 'defacl.sql']), did=did)
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'defacl.sql']),
|
||||
did=did, conn=self.conn
|
||||
)
|
||||
status, defaclres = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
@ -709,7 +838,10 @@ class DatabaseView(NodeView):
|
||||
|
||||
result = res['rows'][0]
|
||||
|
||||
SQL = render_template("/".join([self.template_path, 'get_variables.sql']), did=did)
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'get_variables.sql']),
|
||||
did=did, conn=self.conn
|
||||
)
|
||||
status, res1 = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res1)
|
||||
@ -717,7 +849,7 @@ class DatabaseView(NodeView):
|
||||
frmtd_reslt = self.formatter(result, res1)
|
||||
result.update(frmtd_reslt)
|
||||
|
||||
SQL = self.getNewSQL(gid, sid, result, did)
|
||||
SQL = self.get_new_sql(gid, sid, result, did)
|
||||
|
||||
return ajax_response(response=SQL)
|
||||
|
||||
|
@ -1,4 +1,7 @@
|
||||
SELECT 'relacl' as deftype, COALESCE(gt.rolname, 'public') grantee, g.rolname grantor, array_agg(privilege_type) as privileges, array_agg(is_grantable) as grantable
|
||||
SELECT
|
||||
'datacl' AS deftype, COALESCE(gt.rolname, 'public') AS grantee,
|
||||
g.rolname AS grantor, array_agg(privilege_type) AS privileges,
|
||||
array_agg(is_grantable) AS grantable
|
||||
FROM
|
||||
(SELECT
|
||||
d.grantee, d.grantor, d.is_grantable,
|
||||
@ -18,16 +21,15 @@ FROM
|
||||
ELSE 'UNKNOWN'
|
||||
END AS privilege_type
|
||||
FROM
|
||||
(SELECT datacl FROM pg_database db
|
||||
LEFT OUTER JOIN pg_tablespace ta ON db.dattablespace=ta.OID
|
||||
LEFT OUTER JOIN pg_shdescription descr ON (
|
||||
db.oid=descr.objoid AND descr.classoid='pg_database'::regclass)
|
||||
WHERE db.oid = {{ did|qtLiteral }}::OID
|
||||
) acl,
|
||||
(SELECT (d).grantee AS grantee, (d).grantor AS grantor, (d).is_grantable AS is_grantable, (d).privilege_type AS privilege_type
|
||||
FROM (SELECT aclexplode(datacl) as d FROM pg_database db1
|
||||
WHERE db1.oid = {{ did|qtLiteral }}::OID) a) d
|
||||
(SELECT
|
||||
(d).grantee AS grantee, (d).grantor AS grantor,
|
||||
(d).is_grantable AS is_grantable,
|
||||
(d).privilege_type AS privilege_type
|
||||
FROM
|
||||
(SELECT aclexplode(db.datacl) AS d FROM pg_database db
|
||||
WHERE db.oid = {{ did|qtLiteral }}::OID) a
|
||||
) d
|
||||
) d
|
||||
LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid)
|
||||
LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid)
|
||||
GROUP BY g.rolname, gt.rolname
|
||||
GROUP BY g.rolname, gt.rolname;
|
||||
|
@ -0,0 +1,26 @@
|
||||
{# List down allowed privileges for PostgreSQL/PPAS 9.1, or less #}
|
||||
{#
|
||||
Format for allowed privileges are:
|
||||
"acl_col": {
|
||||
"type": "name",
|
||||
"acl": [...]
|
||||
}
|
||||
#}
|
||||
{
|
||||
"datacl": {
|
||||
"type": "DATABASE",
|
||||
"acl": ["c", "C", "T"]
|
||||
},
|
||||
"deftblacl": {
|
||||
"type": "TABLE",
|
||||
"acl": ["r", "a", "w", "d", "D", "x", "t"]
|
||||
},
|
||||
"defseqacl": {
|
||||
"type": "SEQUENCE",
|
||||
"acl": ["U", "r", "a"]
|
||||
},
|
||||
"deffuncacl": {
|
||||
"type": "FUNCTION",
|
||||
"acl": ["X"]
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
{# We need database name #}
|
||||
{% if did %}
|
||||
SELECT db.datname as name FROM pg_database as db WHERE db.oid = {{did}}
|
||||
{% endif %}
|
@ -1,7 +1,8 @@
|
||||
SELECT
|
||||
db.oid as did, db.datname as name, ta.spcname as spcname, db.datallowconn,
|
||||
has_database_privilege(db.oid, 'CREATE') as cancreate
|
||||
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}}::int {% endif %}
|
||||
LEFT OUTER JOIN pg_tablespace ta ON db.dattablespace = ta.oid{% if did %}
|
||||
|
||||
WHERE db.oid={{ did|qtLiteral }}::OID{% endif %};
|
@ -0,0 +1,13 @@
|
||||
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
|
||||
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
|
||||
{% endif %}
|
||||
ORDER BY db.datname;
|
@ -1,4 +1,7 @@
|
||||
SELECT 'datacl' as deftype, COALESCE(gt.rolname, 'public') grantee, g.rolname grantor, array_agg(privilege_type) as privileges, array_agg(is_grantable) as grantable
|
||||
SELECT
|
||||
'datacl' AS deftype, COALESCE(gt.rolname, 'public') AS grantee,
|
||||
g.rolname grantor, array_agg(privilege_type) AS privileges,
|
||||
array_agg(is_grantable) AS grantable
|
||||
FROM
|
||||
(SELECT
|
||||
d.grantee, d.grantor, d.is_grantable,
|
||||
@ -18,16 +21,15 @@ FROM
|
||||
ELSE 'UNKNOWN'
|
||||
END AS privilege_type
|
||||
FROM
|
||||
(SELECT datacl FROM pg_database db
|
||||
LEFT OUTER JOIN pg_tablespace ta ON db.dattablespace=ta.OID
|
||||
LEFT OUTER JOIN pg_shdescription descr ON (
|
||||
db.oid=descr.objoid AND descr.classoid='pg_database'::regclass)
|
||||
WHERE db.oid = {{ did|qtLiteral }}::OID
|
||||
) acl,
|
||||
(SELECT (d).grantee AS grantee, (d).grantor AS grantor, (d).is_grantable AS is_grantable, (d).privilege_type AS privilege_type
|
||||
FROM (SELECT aclexplode(datacl) as d FROM pg_database db1
|
||||
WHERE db1.oid = {{ did|qtLiteral }}::OID) a) d
|
||||
(SELECT
|
||||
(d).grantee AS grantee, (d).grantor AS grantor,
|
||||
(d).is_grantable AS is_grantable,
|
||||
(d).privilege_type AS privilege_type
|
||||
FROM
|
||||
(SELECT aclexplode(db.datacl) AS d FROM pg_database db
|
||||
WHERE db.oid = {{ did|qtLiteral }}::OID) a
|
||||
) d
|
||||
) d
|
||||
LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid)
|
||||
LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid)
|
||||
GROUP BY g.rolname, gt.rolname
|
||||
GROUP BY g.rolname, gt.rolname;
|
||||
|
@ -0,0 +1,30 @@
|
||||
{# List down allowed privileges for PostgreSQL/PPAS 9.1, or less #}
|
||||
{#
|
||||
Format for allowed privileges are:
|
||||
"acl_col": {
|
||||
"type": "name",
|
||||
"acl": [...]
|
||||
}
|
||||
#}
|
||||
{
|
||||
"datacl": {
|
||||
"type": "DATABASE",
|
||||
"acl": ["c", "C", "T"]
|
||||
},
|
||||
"deftblacl": {
|
||||
"type": "TABLE",
|
||||
"acl": ["r", "a", "w", "d", "D", "x", "t"]
|
||||
},
|
||||
"defseqacl": {
|
||||
"type": "SEQUENCE",
|
||||
"acl": ["U", "r", "a"]
|
||||
},
|
||||
"deffuncacl": {
|
||||
"type": "FUNCTION",
|
||||
"acl": ["X"]
|
||||
},
|
||||
"deftypeacl": {
|
||||
"type": "TYPE",
|
||||
"acl": ["U"]
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
{# We need database name #}
|
||||
{% if did %}
|
||||
SELECT db.datname as name FROM pg_database as db WHERE db.oid = {{did}}
|
||||
{% endif %}
|
@ -1,7 +1,8 @@
|
||||
SELECT
|
||||
db.oid as did, db.datname as name, ta.spcname as spcname, db.datallowconn,
|
||||
has_database_privilege(db.oid, 'CREATE') as cancreate
|
||||
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}}::int {% endif %}
|
||||
LEFT OUTER JOIN pg_tablespace ta ON db.dattablespace = ta.oid{% if did %}
|
||||
|
||||
WHERE db.oid={{ did|qtLiteral }}::OID {% endif %};
|
@ -0,0 +1,13 @@
|
||||
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
|
||||
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
|
||||
{% endif %}
|
||||
ORDER BY db.datname;
|
@ -1,4 +1,7 @@
|
||||
SELECT 'datacl' AS deftype, COALESCE(gt.rolname, 'public') AS grantee, g.rolname AS grantor, array_agg(privilege_type) AS privileges, array_agg(is_grantable) AS grantable
|
||||
SELECT
|
||||
'datacl' AS deftype, COALESCE(gt.rolname, 'public') AS grantee,
|
||||
g.rolname AS grantor, array_agg(privilege_type) AS privileges,
|
||||
array_agg(is_grantable) AS grantable
|
||||
FROM
|
||||
(SELECT
|
||||
d.grantee, d.grantor, d.is_grantable,
|
||||
@ -18,16 +21,15 @@ FROM
|
||||
ELSE 'UNKNOWN'
|
||||
END AS privilege_type
|
||||
FROM
|
||||
(SELECT datacl FROM pg_database db
|
||||
LEFT OUTER JOIN pg_tablespace ta ON db.dattablespace=ta.OID
|
||||
LEFT OUTER JOIN pg_shdescription descr ON (
|
||||
db.oid=descr.objoid AND descr.classoid='pg_database'::regclass)
|
||||
{% if did %}
|
||||
WHERE db.oid = {{ did|qtLiteral }}::OID
|
||||
{% endif %}
|
||||
) acl,
|
||||
aclexplode(datacl) d
|
||||
(SELECT
|
||||
(d).grantee AS grantee, (d).grantor AS grantor,
|
||||
(d).is_grantable AS is_grantable,
|
||||
(d).privilege_type AS privilege_type
|
||||
FROM
|
||||
(SELECT aclexplode(db.datacl) AS d FROM pg_database db
|
||||
WHERE db.oid = {{ did|qtLiteral }}::OID) a
|
||||
) d
|
||||
) d
|
||||
LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid)
|
||||
LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid)
|
||||
GROUP BY g.rolname, gt.rolname
|
||||
GROUP BY g.rolname, gt.rolname;
|
||||
|
@ -0,0 +1,30 @@
|
||||
{# List down allowed privileges for PostgreSQL/PPAS 9.1, or less #}
|
||||
{#
|
||||
Format for allowed privileges are:
|
||||
"acl_col": {
|
||||
"type": "name",
|
||||
"acl": [...]
|
||||
}
|
||||
#}
|
||||
{
|
||||
"datacl": {
|
||||
"type": "DATABASE",
|
||||
"acl": ["c", "C", "T"]
|
||||
},
|
||||
"deftblacl": {
|
||||
"type": "TABLE",
|
||||
"acl": ["r", "a", "w", "d", "D", "x", "t"]
|
||||
},
|
||||
"defseqacl": {
|
||||
"type": "SEQUENCE",
|
||||
"acl": ["U", "r", "a"]
|
||||
},
|
||||
"deffuncacl": {
|
||||
"type": "FUNCTION",
|
||||
"acl": ["X"]
|
||||
},
|
||||
"deftypeacl": {
|
||||
"type": "TYPE",
|
||||
"acl": ["U"]
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
{# We need database name #}
|
||||
{% if did %}
|
||||
SELECT db.datname as name FROM pg_database as db WHERE db.oid = {{did}}
|
||||
{% endif %}
|
@ -1,7 +1,8 @@
|
||||
SELECT
|
||||
db.oid as did, db.datname as name, ta.spcname as spcname, db.datallowconn,
|
||||
has_database_privilege(db.oid, 'CREATE') as cancreate
|
||||
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}}::int {% endif %}
|
||||
LEFT OUTER JOIN pg_tablespace ta ON db.dattablespace = ta.oid{% if did %}
|
||||
|
||||
WHERE db.oid={{ did|qtLiteral }}::OID{% endif %};
|
@ -0,0 +1,13 @@
|
||||
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
|
||||
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
|
||||
{% endif %}
|
||||
ORDER BY db.datname;
|
@ -6,13 +6,13 @@
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
from flask import render_template, request, current_app, jsonify
|
||||
from flask import render_template, request, jsonify
|
||||
from flask.ext.babel import gettext as _
|
||||
from pgadmin.utils.ajax import make_json_response, \
|
||||
make_response as ajax_response, precondition_required, \
|
||||
internal_server_error, forbidden, \
|
||||
not_implemented, success_return
|
||||
from pgadmin.browser.utils import NodeView
|
||||
not_implemented, success_return, gone
|
||||
from pgadmin.browser.utils import PGChildNodeView
|
||||
from pgadmin.browser.collection import CollectionNodeModule
|
||||
import pgadmin.browser.server_groups as sg
|
||||
from pgadmin.utils.driver import get_driver
|
||||
@ -76,7 +76,7 @@ class RoleModule(CollectionNodeModule):
|
||||
blueprint = RoleModule(__name__)
|
||||
|
||||
|
||||
class RoleView(NodeView):
|
||||
class RoleView(PGChildNodeView):
|
||||
node_type = 'role'
|
||||
|
||||
parent_ids = [
|
||||
@ -453,14 +453,11 @@ rolmembership:{
|
||||
u'rolvaliduntil', u'rolpassword'
|
||||
]
|
||||
|
||||
auth_tbl=False
|
||||
check_permission=False
|
||||
fetch_name=False
|
||||
forbidden_msg = None
|
||||
|
||||
if action in ['list', 'properties']:
|
||||
auth_tbl = True
|
||||
elif action in ['drop', 'update']:
|
||||
if action in ['drop', 'update']:
|
||||
check_permission = True
|
||||
fetch_name = True
|
||||
if action == 'drop':
|
||||
@ -480,28 +477,13 @@ rolmembership:{
|
||||
'rid' in kwargs and kwargs['rid'] != -1):
|
||||
fetch_name = True
|
||||
|
||||
if auth_tbl:
|
||||
status, res = self.conn.execute_scalar(
|
||||
"SELECT has_table_privilege('pg_authid', 'SELECT')"
|
||||
)
|
||||
|
||||
if not status:
|
||||
return internal_server_error(
|
||||
_(
|
||||
"Error checking the permission to the pg_authid!\n{0}"
|
||||
).format(res)
|
||||
)
|
||||
self.role_tbl = 'pg_authid' if res else 'pg_roles'
|
||||
else:
|
||||
self.role_tbl = 'pg_roles'
|
||||
|
||||
if check_permission:
|
||||
user = self.manager.user_info
|
||||
|
||||
if not user['is_superuser'] and not user['can_create_role']:
|
||||
if (action != 'update' or
|
||||
'rid' in kwargs and kwargs['rid'] != -1 and
|
||||
user['id'] != rid):
|
||||
user['id'] != kwargs['rid']):
|
||||
return forbidden(forbidden_msg)
|
||||
|
||||
if fetch_name:
|
||||
@ -540,8 +522,8 @@ rolmembership:{
|
||||
@check_precondition(action='list')
|
||||
def list(self, gid, sid):
|
||||
status, res = self.conn.execute_dict(
|
||||
render_template(self.sql_path + 'properties.sql',
|
||||
role_tbl=self.role_tbl
|
||||
render_template(
|
||||
self.sql_path + 'properties.sql'
|
||||
)
|
||||
)
|
||||
|
||||
@ -563,16 +545,14 @@ rolmembership:{
|
||||
def nodes(self, gid, sid):
|
||||
|
||||
status, rset = self.conn.execute_2darray(
|
||||
render_template(self.sql_path + 'nodes.sql',
|
||||
role_tbl=self.role_tbl
|
||||
)
|
||||
)
|
||||
render_template(self.sql_path + 'nodes.sql')
|
||||
)
|
||||
|
||||
if not status:
|
||||
return internal_server_error(
|
||||
_(
|
||||
"Error fetching the roles information from the database server!\n{0}"
|
||||
).format(res)
|
||||
).format(rset)
|
||||
)
|
||||
|
||||
res = []
|
||||
@ -596,17 +576,17 @@ rolmembership:{
|
||||
def node(self, gid, sid, rid):
|
||||
|
||||
status, rset = self.conn.execute_2darray(
|
||||
render_template(self.sql_path + 'nodes.sql',
|
||||
rid=rid,
|
||||
role_tbl=self.role_tbl
|
||||
)
|
||||
render_template(
|
||||
self.sql_path + 'nodes.sql',
|
||||
rid=rid
|
||||
)
|
||||
)
|
||||
|
||||
if not status:
|
||||
return internal_server_error(
|
||||
_(
|
||||
"Error fetching the roles information from the database server!\n{0}"
|
||||
).format(res)
|
||||
).format(rset)
|
||||
)
|
||||
|
||||
for row in rset['rows']:
|
||||
@ -653,8 +633,8 @@ rolmembership:{
|
||||
def properties(self, gid, sid, rid):
|
||||
|
||||
status, res = self.conn.execute_dict(
|
||||
render_template(self.sql_path + 'properties.sql',
|
||||
role_tbl=self.role_tbl,
|
||||
render_template(
|
||||
self.sql_path + 'properties.sql',
|
||||
rid=rid
|
||||
)
|
||||
)
|
||||
@ -692,8 +672,7 @@ rolmembership:{
|
||||
def sql(self, gid, sid, rid):
|
||||
status, res = self.conn.execute_scalar(
|
||||
render_template(
|
||||
self.sql_path + 'sql.sql',
|
||||
role_tbl=self.role_tbl
|
||||
self.sql_path + 'sql.sql'
|
||||
),
|
||||
dict({'rid':rid})
|
||||
)
|
||||
@ -731,9 +710,7 @@ rolmembership:{
|
||||
)
|
||||
|
||||
status, rid = self.conn.execute_scalar(
|
||||
"SELECT oid FROM {0} WHERE rolname = %(rolname)s".format(
|
||||
self.role_tbl
|
||||
),
|
||||
"SELECT oid FROM pg_roles WHERE rolname = %(rolname)s",
|
||||
{'rolname': self.request[u'rolname']}
|
||||
)
|
||||
|
||||
@ -745,8 +722,7 @@ rolmembership:{
|
||||
|
||||
status, rset = self.conn.execute_dict(
|
||||
render_template(self.sql_path + 'nodes.sql',
|
||||
rid=rid,
|
||||
role_tbl=self.role_tbl
|
||||
rid=rid
|
||||
)
|
||||
)
|
||||
|
||||
@ -754,7 +730,7 @@ rolmembership:{
|
||||
return internal_server_error(
|
||||
_(
|
||||
"Error fetching the roles information from the database server!\n{0}"
|
||||
).format(res)
|
||||
).format(rset)
|
||||
)
|
||||
for row in rset['rows']:
|
||||
return jsonify(
|
||||
@ -793,8 +769,7 @@ rolmembership:{
|
||||
|
||||
status, rset = self.conn.execute_dict(
|
||||
render_template(self.sql_path + 'nodes.sql',
|
||||
rid=rid,
|
||||
role_tbl=self.role_tbl
|
||||
rid=rid
|
||||
)
|
||||
)
|
||||
|
||||
@ -802,7 +777,7 @@ rolmembership:{
|
||||
return internal_server_error(
|
||||
_(
|
||||
"Error fetching the roles information from the database server!\n{0}"
|
||||
).format(res)
|
||||
).format(rset)
|
||||
)
|
||||
|
||||
for row in rset['rows']:
|
||||
|
@ -1,8 +1,8 @@
|
||||
SELECT
|
||||
r.oid, r.rolname, r.rolcanlogin, r.rolsuper
|
||||
FROM
|
||||
{{ role_tbl }} r
|
||||
pg_roles r
|
||||
{% if rid %}
|
||||
WHERE r.oid = {{ rid }}::int
|
||||
WHERE r.oid = {{ rid|qtLiteral }}::OID
|
||||
{% endif %}
|
||||
ORDER BY r.rolcanlogin, r.rolname
|
||||
|
@ -9,8 +9,8 @@ SELECT
|
||||
LEFT JOIN pg_catalog.pg_roles rm ON (rm.oid = am.roleid)
|
||||
) rolmembership
|
||||
FROM
|
||||
{{ role_tbl }} r
|
||||
pg_roles r
|
||||
{% if rid %}
|
||||
WHERE r.oid = {{ rid }}::int
|
||||
WHERE r.oid = {{ rid|qtIdent }}::OID
|
||||
{% endif %}
|
||||
ORDER BY r.rolcanlogin, r.rolname
|
||||
|
@ -19,7 +19,7 @@ FROM
|
||||
-- PostgreSQL < 9.5
|
||||
CASE WHEN rolsuper AND NOT rolcatupdate THEN E'\n\nUPDATE pg_authid SET rolcatupdate=false WHERE rolname=' || pg_catalog.quote_literal(rolname) || ';' ELSE '' END AS sql
|
||||
FROM
|
||||
{{ role_tbl }} r
|
||||
pg_roles r
|
||||
WHERE
|
||||
r.oid=%(rid)s::OID
|
||||
UNION ALL
|
||||
|
@ -1,8 +1,8 @@
|
||||
SELECT
|
||||
r.oid, r.rolname, r.rolcanlogin, r.rolsuper
|
||||
FROM
|
||||
{{ role_tbl }} r
|
||||
pg_roles r
|
||||
{% if rid %}
|
||||
WHERE r.oid = {{ rid }}::int
|
||||
WHERE r.oid = {{ rid|qtLiteral }}::OID
|
||||
{% endif %}
|
||||
ORDER BY r.rolcanlogin, r.rolname
|
||||
|
@ -9,8 +9,8 @@ SELECT
|
||||
LEFT JOIN pg_catalog.pg_roles rm ON (rm.oid = am.roleid)
|
||||
) rolmembership
|
||||
FROM
|
||||
{{ role_tbl }} r
|
||||
pg_roles r
|
||||
{% if rid %}
|
||||
WHERE r.oid = {{ rid }}::int
|
||||
WHERE r.oid = {{ rid|qtLiteral }}::int
|
||||
{% endif %}
|
||||
ORDER BY r.rolcanlogin, r.rolname
|
||||
|
@ -19,7 +19,7 @@ FROM
|
||||
-- PostgreSQL < 9.5
|
||||
CASE WHEN rolsuper AND NOT rolcatupdate THEN E'\n\nUPDATE pg_authid SET rolcatupdate=false WHERE rolname=' || pg_catalog.quote_literal(rolname) || ';' ELSE '' END AS sql
|
||||
FROM
|
||||
{{ role_tbl }} r
|
||||
pg_roles r
|
||||
WHERE
|
||||
r.oid=%(rid)s::OID
|
||||
UNION ALL
|
||||
|
@ -1,8 +1,8 @@
|
||||
SELECT
|
||||
r.oid, r.rolname, r.rolcanlogin, r.rolsuper
|
||||
FROM
|
||||
{{ role_tbl }} r
|
||||
pg_roles r
|
||||
{% if rid %}
|
||||
WHERE r.oid = {{ rid }}::int
|
||||
WHERE r.oid = {{ rid|qtLiteral }}::int
|
||||
{% endif %}
|
||||
ORDER BY r.rolcanlogin, r.rolname
|
||||
|
@ -10,8 +10,8 @@ SELECT
|
||||
) rolmembership,
|
||||
(SELECT array_agg(provider || '=' || label) FROM pg_shseclabel sl1 WHERE sl1.objoid=r.oid) AS seclabels
|
||||
FROM
|
||||
{{ role_tbl }} r
|
||||
pg_roles r
|
||||
{% if rid %}
|
||||
WHERE r.oid = {{ rid }}::int
|
||||
WHERE r.oid = {{ rid|qtLiteral }}::int
|
||||
{% endif %}
|
||||
ORDER BY r.rolcanlogin, r.rolname
|
||||
|
@ -21,7 +21,7 @@ FROM
|
||||
-- PostgreSQL < 9.5
|
||||
CASE WHEN rolsuper AND NOT rolcatupdate THEN E'\n\nUPDATE pg_authid SET rolcatupdate=false WHERE rolname=' || pg_catalog.quote_literal(rolname) || ';' ELSE '' END AS sql
|
||||
FROM
|
||||
{{ role_tbl }} r
|
||||
pg_roles r
|
||||
WHERE
|
||||
r.oid=%(rid)s::OID
|
||||
UNION ALL
|
||||
|
@ -1,8 +1,8 @@
|
||||
SELECT
|
||||
r.oid, r.rolname, r.rolcanlogin, r.rolsuper
|
||||
FROM
|
||||
{{ role_tbl }} r
|
||||
pg_roles r
|
||||
{% if rid %}
|
||||
WHERE r.oid = {{ rid }}::int
|
||||
WHERE r.oid = {{ rid|qtLiteral }}::int
|
||||
{% endif %}
|
||||
ORDER BY r.rolcanlogin, r.rolname
|
||||
|
@ -10,8 +10,8 @@ SELECT
|
||||
) AS rolmembership,
|
||||
(SELECT array_agg(provider || '=' || label) FROM pg_shseclabel sl1 WHERE sl1.objoid=r.oid) AS seclabels
|
||||
FROM
|
||||
{{ role_tbl }} r
|
||||
pg_roles r
|
||||
{% if rid %}
|
||||
WHERE r.oid = {{ rid }}::int
|
||||
WHERE r.oid = {{ rid|qtLiteral }}::int
|
||||
{% endif %}
|
||||
ORDER BY r.rolcanlogin, r.rolname
|
||||
|
@ -19,7 +19,7 @@ FROM
|
||||
CASE WHEN rolconnlimit > 0 THEN E'\n CONNECTION LIMIT ' || rolconnlimit ELSE '' END ||
|
||||
CASE WHEN rolvaliduntil IS NOT NULL THEN E'\n VALID UNTIL ' || quote_literal(rolvaliduntil::text) ELSE ';' END AS sql
|
||||
FROM
|
||||
{{ role_tbl }} r
|
||||
pg_roles r
|
||||
WHERE
|
||||
r.oid=%(rid)s::OID
|
||||
UNION ALL
|
||||
|
@ -7,11 +7,11 @@
|
||||
#
|
||||
##########################################################################
|
||||
import json
|
||||
from flask import render_template, make_response, request, jsonify
|
||||
from flask import render_template, make_response, request, jsonify, current_app
|
||||
from flask.ext.babel import gettext
|
||||
from pgadmin.utils.ajax import make_json_response, \
|
||||
make_response as ajax_response, internal_server_error
|
||||
from pgadmin.browser.utils import NodeView
|
||||
make_response as ajax_response, internal_server_error, gone
|
||||
from pgadmin.browser.utils import PGChildNodeView
|
||||
from pgadmin.browser.collection import CollectionNodeModule
|
||||
import pgadmin.browser.server_groups.servers as servers
|
||||
from pgadmin.utils.ajax import precondition_required
|
||||
@ -54,7 +54,7 @@ class TablespaceModule(CollectionNodeModule):
|
||||
blueprint = TablespaceModule(__name__)
|
||||
|
||||
|
||||
class TablespaceView(NodeView):
|
||||
class TablespaceView(PGChildNodeView):
|
||||
node_type = blueprint.node_type
|
||||
|
||||
parent_ids = [
|
||||
@ -62,7 +62,7 @@ class TablespaceView(NodeView):
|
||||
{'type': 'int', 'id': 'sid'}
|
||||
]
|
||||
ids = [
|
||||
{'type': 'int', 'id': 'did'}
|
||||
{'type': 'int', 'id': 'tsid'}
|
||||
]
|
||||
|
||||
operations = dict({
|
||||
@ -70,11 +70,11 @@ class TablespaceView(NodeView):
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'nodes': [{'get': 'nodes'}, {'get': 'nodes'}],
|
||||
'children': [{'get': 'children'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
'msql': [{'get': 'msql'}, {'get': 'msql'}],
|
||||
'stats': [{'get': 'statistics'}],
|
||||
'stats': [{'get': 'statistics'}, {'get': 'statistics'}],
|
||||
'dependency': [{'get': 'dependencies'}],
|
||||
'dependent': [{'get': 'dependents'}],
|
||||
'module.js': [{}, {}, {'get': 'module_js'}],
|
||||
@ -102,17 +102,20 @@ class TablespaceView(NodeView):
|
||||
"""
|
||||
@wraps(f)
|
||||
def wrap(*args, **kwargs):
|
||||
# Here args[0] will hold self & kwargs will hold gid,sid,did
|
||||
# Here args[0] will hold self & kwargs will hold gid,sid,tsid
|
||||
self = args[0]
|
||||
self.manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(kwargs['sid'])
|
||||
self.conn = self.manager.connection()
|
||||
|
||||
# If DB not connected then return error to browser
|
||||
if not self.conn.connected():
|
||||
current_app.logger.warning(
|
||||
"Connection to the server has been lost!"
|
||||
)
|
||||
return precondition_required(
|
||||
gettext(
|
||||
"Connection to the server has been lost!"
|
||||
)
|
||||
"Connection to the server has been lost!"
|
||||
)
|
||||
)
|
||||
|
||||
ver = self.manager.version
|
||||
@ -122,13 +125,19 @@ class TablespaceView(NodeView):
|
||||
self.template_path = 'tablespaces/sql/9.1_plus'
|
||||
else:
|
||||
self.template_path = 'tablespaces/sql/pre_9.1'
|
||||
current_app.logger.debug(
|
||||
"Using the template path: %s", self.template_path
|
||||
)
|
||||
|
||||
return f(*args, **kwargs)
|
||||
return wrap
|
||||
|
||||
@check_precondition
|
||||
def list(self, gid, sid):
|
||||
SQL = render_template("/".join([self.template_path, 'properties.sql']))
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'properties.sql']),
|
||||
conn=self.conn
|
||||
)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
|
||||
if not status:
|
||||
@ -139,9 +148,12 @@ class TablespaceView(NodeView):
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
def nodes(self, gid, sid):
|
||||
def nodes(self, gid, sid, tsid=None):
|
||||
res = []
|
||||
SQL = render_template("/".join([self.template_path, 'properties.sql']))
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'nodes.sql']),
|
||||
tsid=tsid, conn=self.conn
|
||||
)
|
||||
status, rset = self.conn.execute_2darray(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=rset)
|
||||
@ -160,11 +172,11 @@ class TablespaceView(NodeView):
|
||||
status=200
|
||||
)
|
||||
|
||||
def _formatter(self, data, did=None):
|
||||
def _formatter(self, data, tsid=None):
|
||||
"""
|
||||
Args:
|
||||
data: dict of query result
|
||||
did: tablespace oid
|
||||
tsid: tablespace oid
|
||||
|
||||
Returns:
|
||||
It will return formatted output of collections
|
||||
@ -188,8 +200,10 @@ class TablespaceView(NodeView):
|
||||
data['seclabels'] = seclabels
|
||||
|
||||
# We need to parse & convert ACL coming from database to json format
|
||||
SQL = render_template("/".join([self.template_path, 'acl.sql']),
|
||||
did=did)
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'acl.sql']),
|
||||
tsid=tsid, conn=self.conn
|
||||
)
|
||||
status, acl = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=acl)
|
||||
@ -208,16 +222,18 @@ class TablespaceView(NodeView):
|
||||
return data
|
||||
|
||||
@check_precondition
|
||||
def properties(self, gid, sid, did):
|
||||
SQL = render_template("/".join([self.template_path, 'properties.sql']),
|
||||
did=did, conn=self.conn)
|
||||
def properties(self, gid, sid, tsid):
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'properties.sql']),
|
||||
tsid=tsid, conn=self.conn
|
||||
)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
# Making copy of output for future use
|
||||
copy_data = dict(res['rows'][0])
|
||||
copy_data = self._formatter(copy_data, did)
|
||||
copy_data = self._formatter(copy_data, tsid)
|
||||
|
||||
return ajax_response(
|
||||
response=copy_data,
|
||||
@ -250,49 +266,61 @@ class TablespaceView(NodeView):
|
||||
|
||||
# To format privileges coming from client
|
||||
if 'spcacl' in data:
|
||||
data['spcacl'] = parse_priv_to_db(data['spcacl'], 'TABLESPACE')
|
||||
data['spcacl'] = parse_priv_to_db(data['spcacl'], ['C'])
|
||||
|
||||
try:
|
||||
SQL = render_template("/".join([self.template_path, 'create.sql']),
|
||||
data=data, conn=self.conn)
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'create.sql']),
|
||||
data=data, conn=self.conn
|
||||
)
|
||||
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
SQL = render_template("/".join([self.template_path, 'alter.sql']),
|
||||
data=data, conn=self.conn)
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'alter.sql']),
|
||||
data=data, conn=self.conn
|
||||
)
|
||||
|
||||
# Checking if we are not executing empty query
|
||||
if SQL and SQL.strip('\n') and SQL.strip(' '):
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
# To fetch the oid of newly created tablespace
|
||||
SQL = render_template("/".join([self.template_path, 'alter.sql']),
|
||||
tablespace=data['name'], conn=self.conn)
|
||||
status, did = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
|
||||
return internal_server_error(errormsg=did)
|
||||
# To fetch the oid of newly created tablespace
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'alter.sql']),
|
||||
tablespace=data['name'], conn=self.conn
|
||||
)
|
||||
|
||||
status, tsid = self.conn.execute_scalar(SQL)
|
||||
|
||||
if not status:
|
||||
return internal_server_error(errormsg=tsid)
|
||||
|
||||
return jsonify(
|
||||
node=self.blueprint.generate_browser_node(
|
||||
did,
|
||||
tsid,
|
||||
sid,
|
||||
data['name'],
|
||||
icon="icon-tablespace"
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
current_app.logger.exception(e)
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
@check_precondition
|
||||
def update(self, gid, sid, did):
|
||||
def update(self, gid, sid, tsid):
|
||||
"""
|
||||
This function will update tablespace object
|
||||
"""
|
||||
data = request.form if request.form else json.loads(request.data.decode())
|
||||
|
||||
try:
|
||||
SQL = self.getSQL(gid, sid, data, did)
|
||||
SQL = self.get_sql(gid, sid, data, tsid)
|
||||
if SQL and SQL.strip('\n') and SQL.strip(' '):
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
@ -302,7 +330,7 @@ class TablespaceView(NodeView):
|
||||
success=1,
|
||||
info="Tablespace updated",
|
||||
data={
|
||||
'id': did,
|
||||
'id': tsid,
|
||||
'sid': sid,
|
||||
'gid': gid
|
||||
}
|
||||
@ -312,30 +340,44 @@ class TablespaceView(NodeView):
|
||||
success=1,
|
||||
info="Nothing to update",
|
||||
data={
|
||||
'id': did,
|
||||
'id': tsid,
|
||||
'sid': sid,
|
||||
'gid': gid
|
||||
}
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
current_app.logger.exception(e)
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
@check_precondition
|
||||
def delete(self, gid, sid, did):
|
||||
def delete(self, gid, sid, tsid):
|
||||
"""
|
||||
This function will drop the tablespace object
|
||||
"""
|
||||
try:
|
||||
# Get name for tablespace from did
|
||||
SQL = render_template("/".join([self.template_path, 'delete.sql']),
|
||||
did=did, conn=self.conn)
|
||||
status, tsname = self.conn.execute_scalar(SQL)
|
||||
# Get name for tablespace from tsid
|
||||
status, rset = self.conn.execute_dict(
|
||||
render_template(
|
||||
"/".join([self.template_path, 'nodes.sql']),
|
||||
tsid=tsid, conn=self.conn
|
||||
)
|
||||
)
|
||||
|
||||
if not status:
|
||||
return internal_server_error(errormsg=tsname)
|
||||
return internal_server_error(errormsg=rset)
|
||||
|
||||
if len(rset['rows']) != 1:
|
||||
return gone(
|
||||
errormsg=gettext("Couldn't the tablespace in the server!")
|
||||
)
|
||||
|
||||
# drop tablespace
|
||||
SQL = render_template("/".join([self.template_path, 'delete.sql']),
|
||||
tsname=tsname, conn=self.conn)
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'delete.sql']),
|
||||
tsname=(rset['rows'][0])['name'], conn=self.conn
|
||||
)
|
||||
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
@ -344,17 +386,18 @@ class TablespaceView(NodeView):
|
||||
success=1,
|
||||
info=gettext("Tablespace dropped"),
|
||||
data={
|
||||
'id': did,
|
||||
'id': tsid,
|
||||
'sid': sid,
|
||||
'gid': gid,
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
current_app.logger.exception(e)
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
@check_precondition
|
||||
def msql(self, gid, sid, did=None):
|
||||
def msql(self, gid, sid, tsid=None):
|
||||
"""
|
||||
This function to return modified SQL
|
||||
"""
|
||||
@ -362,20 +405,22 @@ class TablespaceView(NodeView):
|
||||
for k, v in request.args.items():
|
||||
try:
|
||||
data[k] = json.loads(v)
|
||||
except ValueError:
|
||||
except ValueError as ve:
|
||||
current_app.logger.exception(ve)
|
||||
data[k] = v
|
||||
try:
|
||||
SQL = self.getSQL(gid, sid, data, did)
|
||||
|
||||
if SQL and SQL.strip('\n') and SQL.strip(' '):
|
||||
return make_json_response(
|
||||
data=SQL,
|
||||
status=200
|
||||
)
|
||||
SQL = self.get_sql(gid, sid, data, tsid)
|
||||
except Exception as e:
|
||||
current_app.logger.exception(e)
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
def getSQL(self, gid, sid, data, did=None):
|
||||
if SQL and SQL.strip('\n') and SQL.strip(' '):
|
||||
return make_json_response(
|
||||
data=SQL,
|
||||
status=200
|
||||
)
|
||||
|
||||
def get_sql(self, gid, sid, data, tsid=None):
|
||||
"""
|
||||
This function will genrate sql from model/properties data
|
||||
"""
|
||||
@ -383,16 +428,18 @@ class TablespaceView(NodeView):
|
||||
'name'
|
||||
]
|
||||
|
||||
if did is not None:
|
||||
SQL = render_template("/".join([self.template_path, 'properties.sql']),
|
||||
did=did, conn=self.conn)
|
||||
if tsid is not None:
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'properties.sql']),
|
||||
tsid=tsid, conn=self.conn
|
||||
)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
# Making copy of output for further processing
|
||||
old_data = dict(res['rows'][0])
|
||||
old_data = self._formatter(old_data, did)
|
||||
old_data = self._formatter(old_data, tsid)
|
||||
|
||||
# To format privileges data coming from client
|
||||
for key in ['spcacl']:
|
||||
@ -410,28 +457,36 @@ class TablespaceView(NodeView):
|
||||
if arg not in data:
|
||||
data[arg] = old_data[arg]
|
||||
|
||||
SQL = render_template("/".join([self.template_path, 'update.sql']),
|
||||
data=data, o_data=old_data)
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'update.sql']),
|
||||
data=data, o_data=old_data
|
||||
)
|
||||
else:
|
||||
# To format privileges coming from client
|
||||
if 'spcacl' in data:
|
||||
data['spcacl'] = parse_priv_to_db(data['spcacl'], 'TABLESPACE')
|
||||
# If the request for new object which do not have did
|
||||
SQL = render_template("/".join([self.template_path, 'create.sql']),
|
||||
data=data)
|
||||
# If the request for new object which do not have tsid
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'create.sql']),
|
||||
data=data
|
||||
)
|
||||
SQL += "\n"
|
||||
SQL += render_template("/".join([self.template_path, 'alter.sql']),
|
||||
data=data)
|
||||
SQL += render_template(
|
||||
"/".join([self.template_path, 'alter.sql']),
|
||||
data=data, conn=self.conn
|
||||
)
|
||||
|
||||
return SQL
|
||||
|
||||
@check_precondition
|
||||
def sql(self, gid, sid, did):
|
||||
def sql(self, gid, sid, tsid):
|
||||
"""
|
||||
This function will generate sql for sql panel
|
||||
"""
|
||||
SQL = render_template("/".join([self.template_path, 'properties.sql']),
|
||||
did=did, conn=self.conn)
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'properties.sql']),
|
||||
tsid=tsid, conn=self.conn
|
||||
)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
@ -439,7 +494,7 @@ class TablespaceView(NodeView):
|
||||
# Making copy of output for future use
|
||||
old_data = dict(res['rows'][0])
|
||||
|
||||
old_data = self._formatter(old_data, did)
|
||||
old_data = self._formatter(old_data, tsid)
|
||||
|
||||
# To format privileges
|
||||
if 'spcacl' in old_data:
|
||||
@ -448,16 +503,20 @@ class TablespaceView(NodeView):
|
||||
SQL = ''
|
||||
# We are not showing create sql for system tablespace
|
||||
if not old_data['name'].startswith('pg_'):
|
||||
SQL = render_template("/".join([self.template_path, 'create.sql']),
|
||||
data=old_data)
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'create.sql']),
|
||||
data=old_data
|
||||
)
|
||||
SQL += "\n"
|
||||
SQL += render_template("/".join([self.template_path, 'alter.sql']),
|
||||
data=old_data)
|
||||
SQL += render_template(
|
||||
"/".join([self.template_path, 'alter.sql']),
|
||||
data=old_data, conn=self.conn
|
||||
)
|
||||
|
||||
sql_header = """
|
||||
-- Tablespace: {0}
|
||||
|
||||
-- DROP TABLESPACE {0}
|
||||
-- DROP TABLESPACE {0};
|
||||
|
||||
""".format(old_data['name'])
|
||||
|
||||
@ -477,9 +536,11 @@ class TablespaceView(NodeView):
|
||||
This function will return list of variables available for
|
||||
table spaces.
|
||||
"""
|
||||
res = []
|
||||
SQL = render_template("/".join([self.template_path, 'variables.sql']))
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'variables.sql'])
|
||||
)
|
||||
status, rset = self.conn.execute_dict(SQL)
|
||||
|
||||
if not status:
|
||||
return internal_server_error(errormsg=rset)
|
||||
|
||||
@ -489,19 +550,23 @@ class TablespaceView(NodeView):
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
def stats(self, gid, sid, did):
|
||||
def statistics(self, gid, sid, tsid=None):
|
||||
"""
|
||||
This function will return data for statistics panel
|
||||
"""
|
||||
SQL = render_template("/".join([self.template_path, 'stats.sql']),
|
||||
did=did)
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'stats.sql']),
|
||||
tsid=tsid, conn=self.conn
|
||||
)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
# TODO:// Format & return output of stats call accordingly
|
||||
# TODO:// for now it's hardcoded as below
|
||||
result = 'Tablespace Size: {0}'.format(res)
|
||||
|
||||
return ajax_response(response=result)
|
||||
|
||||
|
||||
|
@ -11,18 +11,18 @@ FROM
|
||||
FROM
|
||||
(SELECT ts.spcacl
|
||||
FROM pg_tablespace ts
|
||||
{% if did %}
|
||||
WHERE ts.oid={{did}}::int
|
||||
{% if tsid %}
|
||||
WHERE ts.oid={{ tsid|qtLiteral }}::OID
|
||||
{% endif %}
|
||||
) acl,
|
||||
(SELECT (d).grantee AS grantee, (d).grantor AS grantor, (d).is_grantable
|
||||
AS is_grantable, (d).privilege_type AS privilege_type FROM (SELECT
|
||||
aclexplode(ts.spcacl) as d FROM pg_tablespace ts
|
||||
{% if did %}
|
||||
WHERE ts.oid={{did}}::int
|
||||
{% if tsid %}
|
||||
WHERE ts.oid={{ tsid|qtLiteral }}::OID
|
||||
{% endif %}
|
||||
) a) d
|
||||
) d
|
||||
LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid)
|
||||
LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid)
|
||||
GROUP BY g.rolname, gt.rolname
|
||||
GROUP BY g.rolname, gt.rolname
|
||||
|
@ -37,5 +37,5 @@ COMMENT ON TABLESPACE {{ conn|qtIdent(data.name) }}
|
||||
{% endif %}
|
||||
{# ======== The SQl Below will fetch id for given dataspace ======== #}
|
||||
{% if tablespace %}
|
||||
SELECT ts.oid FROM pg_tablespace ts WHERE spcname = {{tablespace|qtLiteral}}
|
||||
{% endif %}
|
||||
SELECT ts.oid FROM pg_tablespace ts WHERE spcname = {{tablespace|qtLiteral}};
|
||||
{% endif %}
|
||||
|
@ -1,9 +1,2 @@
|
||||
{### SQL to delete tablespace object ###}
|
||||
{% if did %}
|
||||
SELECT spcname
|
||||
FROM pg_tablespace ts
|
||||
WHERE ts.oid = {{did}}
|
||||
{% endif %}
|
||||
{% if tsname %}
|
||||
DROP TABLESPACE {{ conn|qtIdent(tsname) }};
|
||||
{% endif %}
|
@ -0,0 +1,9 @@
|
||||
SELECT
|
||||
ts.oid, spcname AS name, spcowner as owner
|
||||
FROM
|
||||
pg_tablespace ts
|
||||
{% if tsid %}
|
||||
WHERE
|
||||
ts.oid={{ tsid|qtLiteral }}::OID
|
||||
{% endif %}
|
||||
ORDER BY name;
|
@ -1,8 +1,11 @@
|
||||
{### SQL to fetch tablespace object properties ###}
|
||||
SELECT ts.oid, spcname AS name, spclocation, spcoptions, pg_get_userbyid(spcowner) as spcuser, spcacl,
|
||||
pg_catalog.shobj_description(oid, 'pg_tablespace') AS description
|
||||
FROM pg_tablespace ts
|
||||
{% if did %}
|
||||
WHERE ts.oid={{did}}::int
|
||||
SELECT
|
||||
ts.oid, spcname AS name, spclocation, spcoptions,
|
||||
pg_get_userbyid(spcowner) as spcuser, spcacl,
|
||||
pg_catalog.shobj_description(oid, 'pg_tablespace') AS description
|
||||
FROM
|
||||
pg_tablespace ts
|
||||
{% if tsid %}
|
||||
WHERE ts.oid={{ tsid|qtLiteral }}::OID
|
||||
{% endif %}
|
||||
ORDER BY name
|
||||
ORDER BY name
|
||||
|
@ -1,2 +1,6 @@
|
||||
{### SQL to fetch tablespace object stats ###}
|
||||
SELECT pg_size_pretty(pg_tablespace_size({{did}})) AS tablespace_size
|
||||
{% if tsid %}
|
||||
SELECT pg_size_pretty(pg_tablespace_size({{ tsid|qtLiteral }}::OID)) AS size
|
||||
{% else %}
|
||||
SELECT ts.spcname as name, pg_size_pretty(pg_tablespace_size(ts.oid)) AS size FROM pg_catalog.pg_tablespace ts;
|
||||
{% endif %}
|
||||
|
@ -11,18 +11,18 @@ FROM
|
||||
FROM
|
||||
(SELECT ts.spcacl
|
||||
FROM pg_tablespace ts
|
||||
{% if did %}
|
||||
WHERE ts.oid={{did}}::int
|
||||
{% if tsid %}
|
||||
WHERE ts.oid={{ tsid|qtLiteral }}::OID
|
||||
{% endif %}
|
||||
) acl,
|
||||
(SELECT (d).grantee AS grantee, (d).grantor AS grantor, (d).is_grantable
|
||||
AS is_grantable, (d).privilege_type AS privilege_type FROM (SELECT
|
||||
aclexplode(ts.spcacl) as d FROM pg_tablespace ts
|
||||
{% if did %}
|
||||
WHERE ts.oid={{did}}::int
|
||||
{% if tsid %}
|
||||
WHERE ts.oid={{ tsid|qtLiteral }}::OID
|
||||
{% endif %}
|
||||
) a) d
|
||||
) d
|
||||
LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid)
|
||||
LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid)
|
||||
GROUP BY g.rolname, gt.rolname
|
||||
GROUP BY g.rolname, gt.rolname
|
||||
|
@ -37,5 +37,5 @@ COMMENT ON TABLESPACE {{ conn|qtIdent(data.name) }}
|
||||
{% endif %}
|
||||
{# ======== The SQl Below will fetch id for given dataspace ======== #}
|
||||
{% if tablespace %}
|
||||
SELECT ts.oid FROM pg_tablespace ts WHERE spcname = {{tablespace|qtLiteral}}
|
||||
{% endif %}
|
||||
SELECT ts.oid FROM pg_tablespace ts WHERE spcname = {{tablespace|qtLiteral}};
|
||||
{% endif %}
|
||||
|
@ -1,9 +1,2 @@
|
||||
{### SQL to delete tablespace object ###}
|
||||
{% if did %}
|
||||
SELECT spcname
|
||||
FROM pg_tablespace ts
|
||||
WHERE ts.oid = {{did}}
|
||||
{% endif %}
|
||||
{% if tsname %}
|
||||
DROP TABLESPACE {{ conn|qtIdent(tsname) }};
|
||||
{% endif %}
|
@ -0,0 +1,9 @@
|
||||
SELECT
|
||||
ts.oid AS oid, spcname AS name, spcowner as owner
|
||||
FROM
|
||||
pg_tablespace ts
|
||||
{% if tsid %}
|
||||
WHERE
|
||||
ts.oid={{ tsid|qtLiteral }}::OID
|
||||
{% endif %}
|
||||
ORDER BY name;
|
@ -1,10 +1,15 @@
|
||||
{### SQL to fetch tablespace object properties ###}
|
||||
SELECT ts.oid, spcname AS name, pg_catalog.pg_tablespace_location(ts.oid) AS spclocation, spcoptions,
|
||||
pg_get_userbyid(spcowner) as spcuser, spcacl::text[],
|
||||
pg_catalog.shobj_description(oid, 'pg_tablespace') AS description
|
||||
,(SELECT array_agg(provider || '=' || label) FROM pg_shseclabel sl1 WHERE sl1.objoid=ts.oid) AS seclabels
|
||||
FROM pg_tablespace ts
|
||||
{% if did %}
|
||||
WHERE ts.oid={{did}}::int
|
||||
SELECT
|
||||
ts.oid, spcname AS name, spcoptions, pg_get_userbyid(spcowner) as spcuser,
|
||||
pg_catalog.pg_tablespace_location(ts.oid) AS spclocation, spcacl::text[],
|
||||
pg_catalog.shobj_description(oid, 'pg_tablespace') AS description,
|
||||
(SELECT
|
||||
array_agg(provider || '=' || label)
|
||||
FROM pg_shseclabel sl1
|
||||
WHERE sl1.objoid=ts.oid) AS seclabels
|
||||
FROM
|
||||
pg_tablespace ts
|
||||
{% if tsid %}
|
||||
WHERE ts.oid={{ tsid|qtLiteral }}::OID
|
||||
{% endif %}
|
||||
ORDER BY name
|
||||
ORDER BY name
|
||||
|
@ -1,2 +1,6 @@
|
||||
{### SQL to fetch tablespace object stats ###}
|
||||
SELECT pg_size_pretty(pg_tablespace_size({{did}})) AS tablespace_size
|
||||
{% if tsid %}
|
||||
SELECT pg_size_pretty(pg_tablespace_size({{ qtLiteral(tsid) }}::OID)) AS size
|
||||
{% else %}
|
||||
SELECT ts.spcname as name, pg_size_pretty(pg_tablespace_size(ts.oid)) AS size FROM pg_catalog.pg_tablespace ts;
|
||||
{% endif %}
|
||||
|
@ -11,18 +11,18 @@ FROM
|
||||
FROM
|
||||
(SELECT ts.spcacl
|
||||
FROM pg_tablespace ts
|
||||
{% if did %}
|
||||
WHERE ts.oid={{did}}::int
|
||||
{% if tsid %}
|
||||
WHERE ts.oid={{ tsid|qtLiteral }}::OID
|
||||
{% endif %}
|
||||
) acl,
|
||||
(SELECT (d).grantee AS grantee, (d).grantor AS grantor, (d).is_grantable
|
||||
AS is_grantable, (d).privilege_type AS privilege_type FROM (SELECT
|
||||
aclexplode(ts.spcacl) as d FROM pg_tablespace ts
|
||||
{% if did %}
|
||||
WHERE ts.oid={{did}}::int
|
||||
{% if tsid %}
|
||||
WHERE ts.oid={{ tsid|qtLiteral }}::OID
|
||||
{% endif %}
|
||||
) a) d
|
||||
) d
|
||||
LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid)
|
||||
LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid)
|
||||
GROUP BY g.rolname, gt.rolname
|
||||
GROUP BY g.rolname, gt.rolname
|
||||
|
@ -37,5 +37,5 @@ COMMENT ON TABLESPACE {{ conn|qtIdent(data.name) }}
|
||||
{% endif %}
|
||||
{# ======== The SQl Below will fetch id for given dataspace ======== #}
|
||||
{% if tablespace %}
|
||||
SELECT ts.oid FROM pg_tablespace ts WHERE spcname = {{tablespace|qtLiteral}}
|
||||
{% endif %}
|
||||
SELECT ts.oid FROM pg_tablespace ts WHERE spcname = {{tablespace|qtLiteral}};
|
||||
{% endif %}
|
||||
|
@ -1,9 +1,2 @@
|
||||
{### SQL to delete tablespace object ###}
|
||||
{% if did %}
|
||||
SELECT spcname
|
||||
FROM pg_tablespace ts
|
||||
WHERE ts.oid = {{did}}
|
||||
{% endif %}
|
||||
{% if tsname %}
|
||||
DROP TABLESPACE {{ conn|qtIdent(tsname) }};
|
||||
{% endif %}
|
@ -0,0 +1,8 @@
|
||||
SELECT
|
||||
ts.oid, spcname AS name, spcowner as owner
|
||||
FROM pg_tablespace ts
|
||||
{% if tsid %}
|
||||
WHERE
|
||||
ts.oid={{ tsid|qtLiteral }}::OID
|
||||
{% endif %}
|
||||
ORDER BY name;
|
@ -2,7 +2,7 @@
|
||||
SELECT ts.oid, spcname AS name, spclocation, spcoptions, pg_get_userbyid(spcowner) as spcuser, spcacl,
|
||||
pg_catalog.shobj_description(oid, 'pg_tablespace') AS description
|
||||
FROM pg_tablespace ts
|
||||
{% if did %}
|
||||
WHERE ts.oid={{did}}::int
|
||||
{% if tsid %}
|
||||
WHERE ts.oid={{ tsid|qtLiteral }}::OID
|
||||
{% endif %}
|
||||
ORDER BY name
|
||||
ORDER BY name
|
||||
|
@ -1,2 +1,6 @@
|
||||
{### SQL to fetch tablespace object stats ###}
|
||||
SELECT pg_size_pretty(pg_tablespace_size({{did}})) AS tablespace_size
|
||||
{% if tsid %}
|
||||
SELECT pg_size_pretty(pg_tablespace_size({{ tsid|qtLiteral }}::OID)) AS size
|
||||
{% else %}
|
||||
SELECT ts.spcname as name, pg_size_pretty(pg_tablespace_size(ts.oid)) AS size FROM pg_catalog.pg_tablespace ts;
|
||||
{% endif %}
|
||||
|
@ -33,7 +33,7 @@ def parse_priv_from_db(db_privileges):
|
||||
return acl
|
||||
|
||||
|
||||
def parse_priv_to_db(str_privileges, object_type = None):
|
||||
def parse_priv_to_db(str_privileges, allowed_acls = []):
|
||||
"""
|
||||
Common utility function to parse privileges before sending to database.
|
||||
"""
|
||||
@ -51,18 +51,22 @@ def parse_priv_to_db(str_privileges, object_type = None):
|
||||
'U': 'USAGE',
|
||||
'X': 'EXECUTE'
|
||||
}
|
||||
privileges_max_cnt = {
|
||||
'DATABASE': 3,
|
||||
'TABLESPACE': 2,
|
||||
'SCHEMA': 2
|
||||
}
|
||||
|
||||
privileges = []
|
||||
allowed_acls_len = len(allowed_acls)
|
||||
|
||||
for priv in str_privileges:
|
||||
priv_with_grant = []
|
||||
priv_without_grant = []
|
||||
|
||||
for privilege in priv['privileges']:
|
||||
|
||||
if privilege['privilege_type'] not in db_privileges:
|
||||
continue
|
||||
|
||||
if privilege['privilege_type'] not in allowed_acls:
|
||||
continue
|
||||
|
||||
if privilege['with_grant']:
|
||||
priv_with_grant.append(
|
||||
db_privileges[privilege['privilege_type']]
|
||||
@ -72,19 +76,15 @@ def parse_priv_to_db(str_privileges, object_type = None):
|
||||
db_privileges[privilege['privilege_type']]
|
||||
)
|
||||
|
||||
if object_type in ("DATABASE", "SCHEMA", "TABLESPACE"):
|
||||
priv_with_grant = ", ".join(priv_with_grant) if (
|
||||
len(priv_with_grant) < privileges_max_cnt[object_type.upper()]
|
||||
) else 'ALL'
|
||||
priv_without_grant = ", ".join(priv_without_grant) if (
|
||||
len(priv_without_grant) < privileges_max_cnt[object_type.upper()]
|
||||
) else 'ALL'
|
||||
else:
|
||||
priv_with_grant = ", ".join(priv_with_grant)
|
||||
priv_without_grant = ", ".join(priv_without_grant)
|
||||
priv_with_grant = ", ".join(priv_with_grant) \
|
||||
if len(priv_with_grant) < allowed_acls_len else 'ALL'
|
||||
priv_without_grant = ", ".join(priv_without_grant) \
|
||||
if len(priv_without_grant) < allowed_acls_len else 'ALL'
|
||||
|
||||
privileges.append({'grantee': priv['grantee'],
|
||||
'with_grant': priv_with_grant,
|
||||
'without_grant': priv_without_grant})
|
||||
privileges.append({
|
||||
'grantee': priv['grantee'],
|
||||
'with_grant': priv_with_grant,
|
||||
'without_grant': priv_without_grant
|
||||
})
|
||||
|
||||
return privileges
|
||||
|
@ -19,7 +19,7 @@ from flask.ext.security import current_user
|
||||
|
||||
from ..abstract import BaseDriver, BaseConnection
|
||||
from pgadmin.settings.settings_model import Server, User
|
||||
from pgadmin.utils.crypto import encrypt, decrypt
|
||||
from pgadmin.utils.crypto import decrypt
|
||||
import random
|
||||
|
||||
from .keywords import ScanKeyword
|
||||
@ -453,7 +453,7 @@ Attempt to reconnect it failed with the below error:
|
||||
pg_conn = psycopg2.connect(
|
||||
host=mgr.host,
|
||||
port=mgr.port,
|
||||
database=db,
|
||||
database=self.db,
|
||||
user=mgr.user,
|
||||
password=password
|
||||
)
|
||||
@ -912,6 +912,7 @@ class Driver(BaseDriver):
|
||||
if type(val) == list:
|
||||
return map(lambda w: Driver.qtIdent(conn, w), val)
|
||||
|
||||
val = str(val)
|
||||
if len(val) == 0:
|
||||
continue
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user