Grant wizard.

This commit is contained in:
Surinder Kumar
2016-04-13 16:11:43 +01:00
committed by Dave Page
parent 6e237d16ca
commit 40c592a988
25 changed files with 2377 additions and 1 deletions

View File

@@ -0,0 +1,461 @@
##########################################################################
#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2016, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#
##########################################################################
"""Implements Grant Wizard"""
import simplejson as json
from flask import render_template, request, current_app
from flask.ext.babel import gettext
from pgadmin.utils.ajax import make_response as ajax_response, \
make_json_response, internal_server_error
from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER
from pgadmin.browser.server_groups.servers.utils import parse_priv_to_db
from pgadmin.utils import PgAdminModule
from flask import Response, url_for
from flask.ext.security import login_required
from urllib import unquote
from pgadmin.utils.ajax import precondition_required
from functools import wraps
from pgadmin.utils.preferences import Preferences
# set template path for sql scripts
MODULE_NAME = 'grant_wizard'
server_info = {}
class GrantWizardModule(PgAdminModule):
"""
class GrantWizardModule(Object):
It is a wizard which inherits PgAdminModule
class and define methods to load its own
javascript file.
LABEL = gettext('Browser')
"""
def get_own_stylesheets(self):
"""
Returns:
list: the stylesheets used by this module.
"""
stylesheets = [
url_for('browser.static', filename='css/wizard.css'),
url_for('grant_wizard.static', filename='css/grant_wizard.css')
]
return stylesheets
def get_own_javascripts(self):
""""
Returns:
list: js files used by this module
"""
scripts = []
scripts.append({
'name': 'pgadmin.tools.grant_wizard',
'path': url_for('grant_wizard.index') + 'grant_wizard',
'when': None
})
scripts.append({
'name': 'pgadmin.browser.wizard',
'path': url_for('browser.static', filename='js/wizard'),
'when': None
})
return scripts
def show_system_objects(self):
"""
return system preference objects
"""
return self.pref_show_system_objects
def register_preferences(self):
"""
Get show_system_objects preference
"""
self.browser_preference = Preferences.module('browser')
self.pref_show_system_objects = self.browser_preference.preference(
'show_system_objects'
)
# Create blueprint for GrantWizardModule class
blueprint = GrantWizardModule(
MODULE_NAME, __name__, static_url_path='')
def check_precondition(f):
"""
This function will behave as a decorator which will checks
database connection before running view, it will also attaches
manager,conn & template_path properties to instance of the method.
Assumptions:
This function will always be used as decorator of a class method.
"""
@wraps(f)
def wrap(*args, **kwargs):
# Here args[0] will hold self & kwargs will hold gid,sid,did
server_info.clear()
server_info['manager'] = get_driver(
PG_DEFAULT_DRIVER).connection_manager(
kwargs['sid']
)
server_info['conn'] = server_info['manager'].connection(
did=kwargs['did']
)
# If DB not connected then return error to browser
if not server_info['conn'].connected():
return precondition_required(
gettext("Connection to the server has been lost!")
)
# Set template path for sql scripts
server_info['server_type'] = server_info['manager'].server_type
server_info['version'] = server_info['manager'].version
if server_info['server_type'] == 'pg':
server_info['template_path'] = 'grant_wizard/pg/9.1_plus'
elif server_info['server_type'] == 'ppas':
server_info['template_path'] = 'grant_wizard/ppas/9.1_plus'
return f(*args, **kwargs)
return wrap
@blueprint.route("/")
@login_required
def index():
pass
@blueprint.route("/grant_wizard.js")
@login_required
def script():
"""render own javascript"""
return Response(response=render_template(
"grant_wizard/js/grant_wizard.js", _=gettext),
status=200,
mimetype="application/javascript")
@blueprint.route(
'/acl/<int:gid>/<int:sid>/<int:did>/', methods=('GET', 'POST'))
@login_required
@check_precondition
def acl_list(gid, sid, did):
"""render list of acls"""
server_prop = server_info
return Response(response=render_template(
server_prop['template_path']+"/acl.json", _=gettext),
status=200,
mimetype="application/json")
@blueprint.route(
'/properties/<int:gid>/<int:sid>/<int:did>'
'/<int:node_id>/<node_type>/',
methods=('GET', 'POST'))
@login_required
@check_precondition
def properties(gid, sid, did, node_id, node_type):
"""It fetches the properties of object types
and render into selection page of wizard
"""
# unquote encoded url parameter
node_type = unquote(node_type)
server_prop = server_info
res_data = []
manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
conn = manager.connection(did=did)
node_types = []
nspname = ''
show_sysobj = blueprint.show_system_objects().get()
if node_type == 'database':
# Fetch list of schemas
# Get sys_obj_values and get list of schemas
ntype = 'schema'
SQL = render_template("/".join(
[server_prop['template_path'], '/sql/get_schemas.sql']),
show_sysobj=show_sysobj)
status, res = conn.execute_dict(SQL)
if not status:
return internal_server_error(errormsg=res)
node_types = res['rows']
else:
SQL = render_template("/".join(
[server_prop['template_path'], '/sql/get_schemas.sql']),
nspid=node_id, show_sysobj=False)
status, res = conn.execute_dict(SQL)
if not status:
return internal_server_error(errormsg=res)
node_types = res['rows']
ntype = node_type
nspname = node_types[0]['name']
for row in node_types:
if 'oid' in row:
node_id = row['oid']
nspname = row['name']
# Fetch functions against schema
if ntype in ['schema', 'function']:
SQL = render_template("/".join(
[server_prop['template_path'], '/sql/function.sql']),
node_id=node_id, nspname=nspname, type='function')
status, res = conn.execute_dict(SQL)
if not status:
return internal_server_error(errormsg=res)
res_data.extend(res['rows'])
# Fetch trigger functions
if ntype in ['schema', 'trigger_function']:
SQL = render_template("/".join(
[server_prop['template_path'], '/sql/function.sql']),
node_id=node_id, nspname=nspname, type='trigger_function')
status, res = conn.execute_dict(SQL)
if not status:
return internal_server_error(errormsg=res)
res_data.extend(res['rows'])
# Fetch Sequences against schema
if ntype in ['schema', 'sequence']:
SQL = render_template("/".join(
[server_prop['template_path'], '/sql/sequence.sql']),
node_id=node_id, nspname=nspname)
status, res = conn.execute_dict(SQL)
if not status:
return internal_server_error(errormsg=res)
res_data.extend(res['rows'])
# Fetch Tables against schema
if ntype in ['schema', 'table']:
SQL = render_template("/".join(
[server_prop['template_path'], '/sql/table.sql']),
node_id=node_id, nspname=nspname)
status, res = conn.execute_dict(SQL)
if not status:
return internal_server_error(errormsg=res)
res_data.extend(res['rows'])
# Fetch Views against schema
if ntype in ['schema', 'view']:
SQL = render_template("/".join(
[server_prop['template_path'], '/sql/view.sql']),
node_id=node_id, nspname=nspname)
status, res = conn.execute_dict(SQL)
if not status:
return internal_server_error(errormsg=res)
res_data.extend(res['rows'])
return ajax_response(
response=res_data,
status=200
)
@blueprint.route(
'/msql/<int:gid>/<int:sid>/<int:did>/',
methods=('GET', 'POST'))
@login_required
@check_precondition
def msql(gid, sid, did):
"""
This function will return modified SQL
"""
server_prop = server_info
data = {}
for k, v in request.args.items():
try:
data[k] = json.loads(v)
except ValueError:
data[k] = v
# Form db connection
manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
conn = manager.connection(did=did)
acls = []
try:
acls = render_template(
"/".join([server_prop['template_path'], '/acl.json'])
)
acls = json.loads(acls)
except Exception as e:
current_app.logger.exception(e)
try:
# Parse privileges
data['priv'] = {}
if 'acl' in data:
# Get function acls
data['priv']['function'] = parse_priv_to_db(
data['acl'],
acls['function']['acl'])
data['priv']['sequence'] = parse_priv_to_db(
data['acl'],
acls['sequence']['acl'])
data['priv']['table'] = parse_priv_to_db(
data['acl'],
acls['table']['acl'])
# Pass database objects and get SQL for privileges
SQL_data = ''
data_func = {}
data_func['objects'] = data['objects']
data_func['priv'] = data['priv']['function']
SQL = render_template(
"/".join([server_prop['template_path'],
'/sql/grant_function.sql']),
data=data_func, conn=conn)
if SQL and SQL.strip('\n') != '':
SQL_data += SQL
data_seq = {}
data_seq['objects'] = data['objects']
data_seq['priv'] = data['priv']['sequence']
SQL = render_template(
"/".join([server_prop['template_path'],
'/sql/grant_sequence.sql']),
data=data_seq, conn=conn)
if SQL and SQL.strip('\n') != '':
SQL_data += SQL
data_table = {}
data_table['objects'] = data['objects']
data_table['priv'] = data['priv']['table']
SQL = render_template(
"/".join([server_prop['template_path'], '/sql/grant_table.sql']),
data=data_table, conn=conn)
if SQL and SQL.strip('\n') != '':
SQL_data += SQL
res = {'data': SQL_data}
return ajax_response(
response=res,
status=200
)
except Exception as e:
return make_json_response(
status=410,
success=0,
errormsg=e.message
)
@blueprint.route(
'/save/<int:gid>/<int:sid>/<int:did>/',
methods=('GET', 'POST'))
@login_required
@check_precondition
def save(gid, sid, did):
"""
This function will apply the privileges to the selected
Database Objects
"""
server_prop = server_info
data = request.form if request.form else json.loads(request.data.decode())
# Form db connection and we use conn to execute sql
manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
conn = manager.connection(did=did)
acls = []
try:
acls = render_template(
"/".join([server_prop['template_path'], 'acl.json']),
)
acls = json.loads(acls)
except Exception as e:
current_app.logger.exception(e)
try:
# Parse privileges
data['priv'] = {}
if 'acl' in data:
# Get function acls
data['priv']['function'] = parse_priv_to_db(
data['acl'],
acls['function']['acl'])
data['priv']['sequence'] = parse_priv_to_db(
data['acl'],
acls['sequence']['acl'])
data['priv']['table'] = parse_priv_to_db(
data['acl'],
acls['table']['acl'])
# Pass database objects and get SQL for privileges
# Pass database objects and get SQL for privileges
SQL_data = ''
data_func = {}
data_func['objects'] = data['objects']
data_func['priv'] = data['priv']['function']
SQL = render_template(
"/".join([server_prop['template_path'],
'/sql/grant_function.sql']),
data=data_func, conn=conn)
if SQL and SQL.strip('\n') != '':
SQL_data += SQL
data_seq = {}
data_seq['objects'] = data['objects']
data_seq['priv'] = data['priv']['sequence']
SQL = render_template(
"/".join([server_prop['template_path'],
'/sql/grant_sequence.sql']),
data=data_seq, conn=conn)
if SQL and SQL.strip('\n') != '':
SQL_data += SQL
data_table = {}
data_table['objects'] = data['objects']
data_table['priv'] = data['priv']['table']
SQL = render_template(
"/".join([server_prop['template_path'], '/sql/grant_table.sql']),
data=data_table, conn=conn)
if SQL and SQL.strip('\n') != '':
SQL_data += SQL
status, res = conn.execute_dict(SQL_data)
if not status:
return internal_server_error(errormsg=res)
return make_json_response(
success=1,
info="Privileges applied"
)
except Exception as e:
return internal_server_error(errormsg=e.message)

View File

@@ -0,0 +1,109 @@
/** Grant Wizard CSS **/
/**
CSS to make db object type table
fixed so that tbody content may
scroll
*/
.db_objects_container {
height: 100%;
}
.object_type_table {
display: inline-block;
height: 100%;
border: 0 !important;
}
.object_type_table thead tr {
position: relative;
display: block;
width: 100%;
}
.object_type_table tbody {
display: block;
overflow: scroll;
border: 1px solid #ddd;
width: 100%;
min-height: 100%;
max-height: 66%;
height: 66%;
}
.object_type_table tbody tr {
display: table;
max-width: 100%;
width: 100%;
}
.object_type_table tbody tr td {
background-position: 4px 4px;
border-radius: 0;
}
.object_type_table tbody tr td:nth-child(1),
.object_type_table thead tr th:nth-child(1) {
width: 28px;
min-width: 28px;
}
.object_type_table tbody tr td:nth-child(2) {
width: 161px;
min-width: 161px;
max-width: 161px;
}
.object_type_table thead tr th:nth-child(2) {
width: 161px;
min-width: 161px;
max-width: 161px;
}
.object_type_table tbody tr td:nth-child(3) {
width: 109px;
min-width: 109px;
max-width: 109px;
}
.object_type_table thead tr th:nth-child(3) {
width: 109px;
min-width: 109px;
max-width: 109px;
}
.object_type_table thead tr th:nth-child(4) {
width: 100%;
}
.object_type_table tbody tr td:nth-child(4) {
width: 100%;
max-width: 100%;
}
/** Override Backgrid filter CSS **/
.db_objects_container .backgrid-filter.form-search {
float: left;
margin: 0px 5px 5px 0;
}
/** Custom styling for Codemirror field **/
.wizard-right-panel_content {
border: 1px solide #ccc;
}
.wizard-right-panel_content .CodeMirror {
border: 1px solid #ccc;
height: 285px !important;
min-height: 285px !important;
}
.wizard-right-panel_content .CodeMirror-linenumber {
background: #F7F7F7;
border-right: 1px solid #DDDDDD;
}
.wizard-right-panel_content .CodeMirror-gutters {
min-height: 285px !important;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,30 @@
{# List of allowed privileges of Schema, table sequence, function and view #}
{#
Format for allowed privileges are:
"node_name": {
"type": "name",
"acl": [...]
}
#}
{
"schema": {
"type": "SCHEMA",
"acl": ["a", "r", "w", "d", "D", "x", "t", "U", "X"]
},
"table": {
"type": "TABLE",
"acl": ["a", "w", "d", "D", "x", "t"]
},
"view": {
"type": "VIEW",
"acl": ["a", "w", "d", "D", "x", "t"]
},
"sequence": {
"type": "SEQUENCE",
"acl": ["w", "U"]
},
"function": {
"type": "FUNCTION",
"acl": ["X"]
}
}

View File

@@ -0,0 +1,23 @@
{# ===== Fetch list of Database object types(Functions) ====== #}
{% if type and node_id and nspname %}
{% set func_type = 'Trigger Function' if type == 'trigger_function' else 'Function' %}
SELECT
pr.oid,
pg_get_function_identity_arguments(pr.oid) AS proargs,
{# pr.proname || '(' || pg_get_function_identity_arguments(pr.oid) || ')' AS name,#}
pr.proname AS name,
'{{ nspname }}' AS nspname,
'{{ func_type }}' AS object_type,
'{{ "icon-function" if type != "trigger_function" else "icon-trigger_function" }}' AS icon
FROM
pg_proc pr
JOIN pg_type typ ON typ.oid=prorettype
JOIN pg_namespace typns ON typns.oid=typ.typnamespace
JOIN pg_language lng ON lng.oid=prolang
LEFT OUTER JOIN pg_description des ON (des.objoid=pr.oid AND des.classoid='pg_proc'::regclass)
WHERE
proisagg = FALSE AND pronamespace = {{ node_id }}::oid
AND typname {{ 'NOT' if type != 'trigger_function' else '' }} IN ('trigger', 'event_trigger')
ORDER BY
proname
{% endif %}

View File

@@ -0,0 +1,19 @@
{# ===== Fetch list of all schemas ===== #}
{% import 'catalog/pg/macros/catalogs.sql' as CATALOGS %}
SELECT
nsp.oid,
nsp.nspname as name
FROM
pg_namespace nsp
WHERE
{% if nspid %}
nsp.oid={{nspid}}::int AND
{% else %}
{% if not show_sysobj %}
nspname NOT LIKE E'pg\_%' AND
{% endif %}
{% endif %}
NOT (
{{ CATALOGS.LIST('nsp') }}
)
ORDER BY nspname;

View File

@@ -0,0 +1,10 @@
{# ===== Grant Permissions on Database Objects Selected ==== #}
{% import 'macros/functions/privilege.macros' as PRIVILEGE_FUNCTION %}
{% for obj in data.objects -%}
{% for priv in data.priv -%}
{# ===== if object_type is Function then apply function marcros ===== #}
{% if (obj.object_type == 'Function' or obj.object_type == 'Trigger Function') %}
{{ PRIVILEGE_FUNCTION.SET(conn, 'FUNCTION', priv['grantee'], obj.name, priv['without_grant'], priv['with_grant'], obj.nspname, obj.proargs)}}
{% endif -%}
{% endfor -%}
{% endfor -%}

View File

@@ -0,0 +1,9 @@
{# ===== Grant Permissions on Database Objects Selected ==== #}
{% import 'macros/schemas/privilege.macros' as PRIVILEGE %}
{% for obj in data.objects -%}
{% for priv in data.priv -%}
{% if obj.object_type == 'Sequence' %}
{{ PRIVILEGE.SET(conn, 'SEQUENCE', priv['grantee'], obj.name, priv['without_grant'], priv['with_grant'], obj.nspname ) }}
{% endif %}
{% endfor -%}
{% endfor -%}

View File

@@ -0,0 +1,9 @@
{# ===== Grant Permissions on Database Objects Selected ==== #}
{% import 'macros/schemas/privilege.macros' as PRIVILEGE %}
{% for obj in data.objects -%}
{% for priv in data.priv -%}
{% if obj.object_type == 'Table' or obj.object_type == 'View' %}
{{ PRIVILEGE.SET(conn, 'TABLE', priv['grantee'], obj.name, priv['without_grant'], priv['with_grant'], obj.nspname ) }}
{% endif %}
{% endfor -%}
{% endfor -%}

View File

@@ -0,0 +1,15 @@
{# ===== Fetch list of Database object types(Sequence) ===== #}
{% if node_id, nspname %}
SELECT
cl.relname AS name,
'Sequence' AS object_type,
'icon-sequence' AS icon,
'{{ nspname }}' AS nspname
FROM
pg_class cl
LEFT OUTER JOIN pg_description des ON (des.objoid=cl.oid AND des.classoid='pg_class'::regclass)
WHERE
relkind = 'S' AND relnamespace = {{ node_id }}::oid
ORDER BY
cl.relname
{% endif %}

View File

@@ -0,0 +1,19 @@
{# ===== Fetch list of Database object types(Tables) ===== #}
{% if node_id and nspname %}
SELECT
rel.relname AS name,
'Table' AS object_type,
'icon-table' AS icon,
'{{ nspname }}' AS nspname
FROM
pg_class rel
LEFT OUTER JOIN pg_tablespace spc ON spc.oid=rel.reltablespace
LEFT OUTER JOIN pg_description des ON (des.objoid=rel.oid AND des.objsubid=0 AND des.classoid='pg_class'::regclass)
LEFT OUTER JOIN pg_constraint con ON con.conrelid=rel.oid AND con.contype='p'
LEFT OUTER JOIN pg_class tst ON tst.oid = rel.reltoastrelid
LEFT JOIN pg_type typ ON rel.reloftype=typ.oid
WHERE
rel.relkind IN ('r','s','t') AND rel.relnamespace = {{ node_id }}::oid
ORDER BY
rel.relname
{% endif %}

View File

@@ -0,0 +1,28 @@
{# ===== Fetch list of Database object types(View) ===== #}
{% if node_id %}
SELECT
c.relname AS name,
'View' AS object_type,
'icon-view' AS icon,
'{{ nspname }}' AS nspname
FROM
pg_class c
LEFT OUTER JOIN pg_tablespace spc ON spc.oid=c.reltablespace
LEFT OUTER JOIN pg_description des ON (des.objoid=c.oid and des.objsubid=0 AND des.classoid='pg_class'::regclass)
LEFT OUTER JOIN pg_class tst ON tst.oid = c.reltoastrelid
WHERE
((c.relhasrules AND (EXISTS (
SELECT
r.rulename
FROM
pg_rewrite r
WHERE
((r.ev_class = c.oid)
AND (bpchar(r.ev_type) = '1'::bpchar))
))
) OR (c.relkind = 'v'::char)
)
AND c.relnamespace = {{ node_id }}::oid
ORDER BY
c.relname
{% endif %}

View File

@@ -0,0 +1,30 @@
{# List of allowed privileges of Schema, table sequence, function and view #}
{#
Format for allowed privileges are:
"node_name": {
"type": "name",
"acl": [...]
}
#}
{
"schema": {
"type": "SCHEMA",
"acl": ["a", "r", "w", "d", "D", "x", "t", "U", "X"]
},
"table": {
"type": "TABLE",
"acl": ["a", "w", "d", "D", "x", "t"]
},
"view": {
"type": "VIEW",
"acl": ["a", "w", "d", "D", "x", "t"]
},
"sequence": {
"type": "SEQUENCE",
"acl": ["w", "U"]
},
"function": {
"type": "FUNCTION",
"acl": ["X"]
}
}

View File

@@ -0,0 +1,23 @@
{# ===== Fetch list of Database object types(Functions) ====== #}
{% if type and node_id and nspname %}
{% set func_type = 'Trigger Function' if type == 'trigger_function' else 'Function' %}
SELECT
pr.oid,
pg_get_function_identity_arguments(pr.oid) AS proargs,
{# pr.proname || '(' || pg_get_function_identity_arguments(pr.oid) || ')' AS name,#}
pr.proname AS name,
'{{ nspname }}' AS nspname,
'{{ func_type }}' AS object_type,
'{{ "icon-function" if type != "trigger_function" else "icon-trigger_function" }}' AS icon
FROM
pg_proc pr
JOIN pg_type typ ON typ.oid=prorettype
JOIN pg_namespace typns ON typns.oid=typ.typnamespace
JOIN pg_language lng ON lng.oid=prolang
LEFT OUTER JOIN pg_description des ON (des.objoid=pr.oid AND des.classoid='pg_proc'::regclass)
WHERE
proisagg = FALSE AND pronamespace = {{ node_id }}::oid
AND typname {{ 'NOT' if type != 'trigger_function' else '' }} IN ('trigger', 'event_trigger')
ORDER BY
proname
{% endif %}

View File

@@ -0,0 +1,19 @@
{# ===== Fetch list of all schemas ===== #}
{% import 'catalog/pg/macros/catalogs.sql' as CATALOGS %}
SELECT
nsp.oid,
nsp.nspname as name
FROM
pg_namespace nsp
WHERE
{% if nspid %}
nsp.oid={{nspid}}::int AND
{% else %}
{% if not show_sysobj %}
nspname NOT LIKE E'pg\_%' AND
{% endif %}
{% endif %}
NOT (
{{ CATALOGS.LIST('nsp') }}
)
ORDER BY nspname;

View File

@@ -0,0 +1,10 @@
{# ===== Grant Permissions on Database Objects Selected ==== #}
{% import 'macros/functions/privilege.macros' as PRIVILEGE_FUNCTION %}
{% for obj in data.objects -%}
{% for priv in data.priv -%}
{# ===== if object_type is Function then apply function marcros ===== #}
{% if (obj.object_type == 'Function' or obj.object_type == 'Trigger Function') %}
{{ PRIVILEGE_FUNCTION.SET(conn, 'FUNCTION', priv['grantee'], obj.name, priv['without_grant'], priv['with_grant'], obj.nspname, obj.proargs)}}
{% endif -%}
{% endfor -%}
{% endfor -%}

View File

@@ -0,0 +1,9 @@
{# ===== Grant Permissions on Database Objects Selected ==== #}
{% import 'macros/schemas/privilege.macros' as PRIVILEGE %}
{% for obj in data.objects -%}
{% for priv in data.priv -%}
{% if obj.object_type == 'Sequence' %}
{{ PRIVILEGE.SET(conn, 'SEQUENCE', priv['grantee'], obj.name, priv['without_grant'], priv['with_grant'], obj.nspname ) }}
{% endif %}
{% endfor -%}
{% endfor -%}

View File

@@ -0,0 +1,9 @@
{# ===== Grant Permissions on Database Objects Selected ==== #}
{% import 'macros/schemas/privilege.macros' as PRIVILEGE %}
{% for obj in data.objects -%}
{% for priv in data.priv -%}
{% if obj.object_type == 'Table' or obj.object_type == 'View' %}
{{ PRIVILEGE.SET(conn, 'TABLE', priv['grantee'], obj.name, priv['without_grant'], priv['with_grant'], obj.nspname ) }}
{% endif %}
{% endfor -%}
{% endfor -%}

View File

@@ -0,0 +1,15 @@
{# ===== Fetch list of Database object types(Sequence) ===== #}
{% if node_id, nspname %}
SELECT
cl.relname AS name,
'Sequence' AS object_type,
'icon-sequence' AS icon,
'{{ nspname }}' AS nspname
FROM
pg_class cl
LEFT OUTER JOIN pg_description des ON (des.objoid=cl.oid AND des.classoid='pg_class'::regclass)
WHERE
relkind = 'S' AND relnamespace = {{ node_id }}::oid
ORDER BY
cl.relname
{% endif %}

View File

@@ -0,0 +1,19 @@
{# ===== Fetch list of Database object types(Tables) ===== #}
{% if node_id and nspname %}
SELECT
rel.relname AS name,
'Table' AS object_type,
'icon-table' AS icon,
'{{ nspname }}' AS nspname
FROM
pg_class rel
LEFT OUTER JOIN pg_tablespace spc ON spc.oid=rel.reltablespace
LEFT OUTER JOIN pg_description des ON (des.objoid=rel.oid AND des.objsubid=0 AND des.classoid='pg_class'::regclass)
LEFT OUTER JOIN pg_constraint con ON con.conrelid=rel.oid AND con.contype='p'
LEFT OUTER JOIN pg_class tst ON tst.oid = rel.reltoastrelid
LEFT JOIN pg_type typ ON rel.reloftype=typ.oid
WHERE
rel.relkind IN ('r','s','t') AND rel.relnamespace = {{ node_id }}::oid
ORDER BY
rel.relname
{% endif %}

View File

@@ -0,0 +1,28 @@
{# ===== Fetch list of Database object types(View) ===== #}
{% if node_id %}
SELECT
c.relname AS name,
'View' AS object_type,
'icon-view' AS icon,
'{{ nspname }}' AS nspname
FROM
pg_class c
LEFT OUTER JOIN pg_tablespace spc ON spc.oid=c.reltablespace
LEFT OUTER JOIN pg_description des ON (des.objoid=c.oid and des.objsubid=0 AND des.classoid='pg_class'::regclass)
LEFT OUTER JOIN pg_class tst ON tst.oid = c.reltoastrelid
WHERE
((c.relhasrules AND (EXISTS (
SELECT
r.rulename
FROM
pg_rewrite r
WHERE
((r.ev_class = c.oid)
AND (bpchar(r.ev_type) = '1'::bpchar))
))
) OR (c.relkind = 'v'::char)
)
AND c.relnamespace = {{ node_id }}::oid
ORDER BY
c.relname
{% endif %}