mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Added support for the catalog objects under special catalogs. (also,
added support for columns under it).
This commit is contained in:
parent
87623cb997
commit
5347bdb886
@ -0,0 +1,300 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2016, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
""" Implements Catalog objects Node."""
|
||||
|
||||
from flask import render_template
|
||||
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 PGChildNodeView
|
||||
from pgadmin.browser.server_groups.servers.databases.schemas.utils \
|
||||
import SchemaChildModule
|
||||
import pgadmin.browser.server_groups.servers.databases as database
|
||||
from pgadmin.utils.ajax import precondition_required
|
||||
from pgadmin.utils.driver import get_driver
|
||||
from config import PG_DEFAULT_DRIVER
|
||||
from functools import wraps
|
||||
|
||||
|
||||
class CatalogObjectModule(SchemaChildModule):
|
||||
"""
|
||||
class CatalogObjectModule(SchemaChildModule)
|
||||
|
||||
A module class for Catalog objects node derived from SchemaChildModule.
|
||||
|
||||
Methods:
|
||||
-------
|
||||
* __init__(*args, **kwargs)
|
||||
- Method is used to initialize the Catalog objects and it's base module.
|
||||
|
||||
* get_nodes(gid, sid, did, scid, coid)
|
||||
- Method is used to generate the browser collection node.
|
||||
|
||||
* script_load()
|
||||
- Load the module script for Catalog objects, when any of the server node
|
||||
is initialized.
|
||||
"""
|
||||
NODE_TYPE = 'catalog_object'
|
||||
COLLECTION_LABEL = gettext("Catalog Objects")
|
||||
|
||||
# Flag for not to show node under Schema/Catalog node
|
||||
# By default its set to True to display node in schema/catalog
|
||||
# We do not want to display 'Catalog Objects' under Schema/Catalog
|
||||
# but only in information_schema/sys/dbo
|
||||
CATALOG_DB_SUPPORTED = False
|
||||
SUPPORTED_SCHEMAS = ['information_schema', 'sys', 'dbo']
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""
|
||||
Method is used to initialize the CatalogObjectModule and it's base module.
|
||||
|
||||
Args:
|
||||
*args:
|
||||
**kwargs:
|
||||
"""
|
||||
super(CatalogObjectModule, self).__init__(*args, **kwargs)
|
||||
self.min_ver = None
|
||||
self.max_ver = None
|
||||
|
||||
def get_nodes(self, gid, sid, did, scid):
|
||||
"""
|
||||
Generate the collection node
|
||||
"""
|
||||
yield self.generate_browser_collection_node(scid)
|
||||
|
||||
@property
|
||||
def script_load(self):
|
||||
"""
|
||||
Load the module script for server, when any of the database node is
|
||||
initialized.
|
||||
"""
|
||||
return database.DatabaseModule.NODE_TYPE
|
||||
|
||||
blueprint = CatalogObjectModule(__name__)
|
||||
|
||||
|
||||
class CatalogObjectView(PGChildNodeView):
|
||||
"""
|
||||
This class is responsible for generating routes for Catalog objects node.
|
||||
|
||||
Methods:
|
||||
-------
|
||||
* check_precondition()
|
||||
- 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 self
|
||||
|
||||
* list()
|
||||
- Lists all the Catalog objects nodes within that collection.
|
||||
|
||||
* nodes()
|
||||
- Creates all the nodes of type Catalog objects.
|
||||
|
||||
* properties(gid, sid, did, scid, coid)
|
||||
- Shows the properties of the selected Catalog objects node.
|
||||
|
||||
* dependency(gid, sid, did, scid):
|
||||
- Returns the dependencies list for the given catalog object node.
|
||||
|
||||
* dependent(gid, sid, did, scid):
|
||||
- Returns the dependents list for the given Catalog objects node.
|
||||
"""
|
||||
node_type = blueprint.node_type
|
||||
|
||||
parent_ids = [
|
||||
{'type': 'int', 'id': 'gid'},
|
||||
{'type': 'int', 'id': 'sid'},
|
||||
{'type': 'int', 'id': 'did'},
|
||||
{'type': 'int', 'id': 'scid'}
|
||||
]
|
||||
ids = [
|
||||
{'type': 'int', 'id': 'coid'}
|
||||
]
|
||||
|
||||
operations = dict({
|
||||
'obj': [{'get': 'properties'}, {'get': 'list'}],
|
||||
'children': [{'get': 'children'}],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
'dependency': [{'get': 'dependencies'}],
|
||||
'dependent': [{'get': 'dependents'}],
|
||||
'module.js': [{}, {}, {'get': 'module_js'}]
|
||||
})
|
||||
|
||||
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 self
|
||||
"""
|
||||
@wraps(f)
|
||||
def wrap(*args, **kwargs):
|
||||
# Here args[0] will hold self & kwargs will hold gid,sid,did
|
||||
self = args[0]
|
||||
self.manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(
|
||||
kwargs['sid']
|
||||
)
|
||||
self.conn = self.manager.connection(did=kwargs['did'])
|
||||
# If DB not connected then return error to browser
|
||||
if not self.conn.connected():
|
||||
return precondition_required(
|
||||
gettext(
|
||||
"Connection to the server has been lost!"
|
||||
)
|
||||
)
|
||||
|
||||
self.template_path = 'catalog_object/sql/{0}/9.1_plus'.format(
|
||||
'ppas' if self.manager.server_type == 'ppas' else 'pg'
|
||||
)
|
||||
|
||||
return f(*args, **kwargs)
|
||||
|
||||
return wrap
|
||||
|
||||
@check_precondition
|
||||
def list(self, gid, sid, did, scid):
|
||||
"""
|
||||
This function is used to list all the catalog objects
|
||||
nodes within that collection.
|
||||
|
||||
Args:
|
||||
gid: Server group ID
|
||||
sid: Server ID
|
||||
did: Database ID
|
||||
scid: Schema ID
|
||||
|
||||
Returns:
|
||||
JSON of available catalog objects nodes
|
||||
"""
|
||||
|
||||
SQL = render_template("/".join([
|
||||
self.template_path, 'properties.sql'
|
||||
]), scid=scid
|
||||
)
|
||||
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
return ajax_response(
|
||||
response=res['rows'],
|
||||
status=200
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
def nodes(self, gid, sid, did, scid):
|
||||
"""
|
||||
This function will used to create all the child node within that collection.
|
||||
Here it will create all the catalog objects node.
|
||||
|
||||
Args:
|
||||
gid: Server Group ID
|
||||
sid: Server ID
|
||||
did: Database ID
|
||||
scid: Schema ID
|
||||
|
||||
Returns:
|
||||
JSON of available catalog objects child nodes
|
||||
"""
|
||||
res = []
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'nodes.sql']), scid=scid
|
||||
)
|
||||
|
||||
status, rset = self.conn.execute_2darray(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=rset)
|
||||
|
||||
for row in rset['rows']:
|
||||
res.append(
|
||||
self.blueprint.generate_browser_node(
|
||||
row['oid'],
|
||||
scid,
|
||||
row['name'],
|
||||
icon="icon-catalog_object"
|
||||
))
|
||||
|
||||
return make_json_response(
|
||||
data=res,
|
||||
status=200
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
def properties(self, gid, sid, did, scid, coid):
|
||||
"""
|
||||
This function will show the properties of the selected
|
||||
catalog objects node.
|
||||
|
||||
Args:
|
||||
gid: Server Group ID
|
||||
sid: Server ID
|
||||
did: Database ID
|
||||
scid: Schema ID
|
||||
scid: Schema ID
|
||||
coid: Catalog object ID
|
||||
|
||||
Returns:
|
||||
JSON of selected catalog objects node
|
||||
"""
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, 'properties.sql']),
|
||||
scid=scid, coid=coid
|
||||
)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return ajax_response(
|
||||
response=res['rows'][0],
|
||||
status=200
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
def dependents(self, gid, sid, did, scid, coid):
|
||||
"""
|
||||
This function get the dependents and return ajax response
|
||||
for the catalog objects node.
|
||||
|
||||
Args:
|
||||
gid: Server Group ID
|
||||
sid: Server ID
|
||||
did: Database ID
|
||||
scid: Schema ID
|
||||
coid: catalog objects ID
|
||||
"""
|
||||
dependents_result = self.get_dependents(self.conn, coid)
|
||||
|
||||
return ajax_response(
|
||||
response=dependents_result,
|
||||
status=200
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
def dependencies(self, gid, sid, did, scid, coid):
|
||||
"""
|
||||
This function get the dependencies and return ajax response
|
||||
for the catalog objects node.
|
||||
|
||||
Args:
|
||||
gid: Server Group ID
|
||||
sid: Server ID
|
||||
did: Database ID
|
||||
scid: Schema ID
|
||||
coid: catalog objects ID
|
||||
"""
|
||||
dependencies_result = self.get_dependencies(self.conn, coid)
|
||||
|
||||
return ajax_response(
|
||||
response=dependencies_result,
|
||||
status=200
|
||||
)
|
||||
|
||||
CatalogObjectView.register_node_view(blueprint)
|
@ -0,0 +1,343 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2016, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
""" Implements Columns Node (For Catalog objects) """
|
||||
|
||||
from flask import render_template
|
||||
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 PGChildNodeView
|
||||
from pgadmin.browser.collection import CollectionNodeModule
|
||||
import pgadmin.browser.server_groups.servers.databases as database
|
||||
from pgadmin.utils.ajax import precondition_required
|
||||
from pgadmin.utils.driver import get_driver
|
||||
from config import PG_DEFAULT_DRIVER
|
||||
from functools import wraps
|
||||
|
||||
|
||||
class CatalogObjectColumnsModule(CollectionNodeModule):
|
||||
"""
|
||||
class ColumnModule(CollectionNodeModule)
|
||||
|
||||
A module class for column node derived from CollectionNodeModule.
|
||||
|
||||
Methods:
|
||||
-------
|
||||
* __init__(*args, **kwargs)
|
||||
- Method is used to initialize the column and it's base module.
|
||||
|
||||
* get_nodes(gid, sid, did, scid, coid)
|
||||
- Method is used to generate the browser collection node.
|
||||
|
||||
* node_inode()
|
||||
- Method is overridden from its base class to make the node as leaf node.
|
||||
|
||||
* script_load()
|
||||
- Load the module script for column, when any of the server node is
|
||||
initialized.
|
||||
"""
|
||||
|
||||
NODE_TYPE = 'catalog_object_column'
|
||||
COLLECTION_LABEL = gettext("Columns")
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""
|
||||
Method is used to initialize the ColumnModule and it's base module.
|
||||
|
||||
Args:
|
||||
*args:
|
||||
**kwargs:
|
||||
"""
|
||||
super(CatalogObjectColumnsModule, self).__init__(*args, **kwargs)
|
||||
self.min_ver = None
|
||||
self.max_ver = None
|
||||
|
||||
def get_nodes(self, gid, sid, did, scid, coid):
|
||||
"""
|
||||
Generate the collection node
|
||||
"""
|
||||
yield self.generate_browser_collection_node(coid)
|
||||
|
||||
@property
|
||||
def script_load(self):
|
||||
"""
|
||||
Load the module script for server, when any of the database node is
|
||||
initialized.
|
||||
"""
|
||||
return database.DatabaseModule.NODE_TYPE
|
||||
|
||||
@property
|
||||
def node_inode(self):
|
||||
"""
|
||||
Load the module node as a leaf node
|
||||
"""
|
||||
return False
|
||||
|
||||
blueprint = CatalogObjectColumnsModule(__name__)
|
||||
|
||||
|
||||
class CatalogObjectColumnsView(PGChildNodeView):
|
||||
"""
|
||||
This class is responsible for generating routes for column node
|
||||
|
||||
Methods:
|
||||
-------
|
||||
* __init__(**kwargs)
|
||||
- Method is used to initialize the ColumnView and it's base view.
|
||||
|
||||
* check_precondition()
|
||||
- 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 self
|
||||
|
||||
* list()
|
||||
- Returns the properties of all the columns for the catalog object.
|
||||
|
||||
* nodes()
|
||||
- Creates and returns all the children nodes of type - catalog object
|
||||
column.
|
||||
|
||||
* properties(gid, sid, did, scid, coid, clid)
|
||||
- Returns the properties of the given catalog-object column node.
|
||||
|
||||
* dependency(gid, sid, did, scid, coid, clid):
|
||||
- Returns the dependencies list of the given node.
|
||||
|
||||
* dependent(gid, sid, did, scid, coid, clid):
|
||||
- Returns the dependents list of the given node.
|
||||
"""
|
||||
|
||||
node_type = blueprint.node_type
|
||||
|
||||
parent_ids = [
|
||||
{'type': 'int', 'id': 'gid'},
|
||||
{'type': 'int', 'id': 'sid'},
|
||||
{'type': 'int', 'id': 'did'},
|
||||
{'type': 'int', 'id': 'scid'},
|
||||
{'type': 'int', 'id': 'coid'}
|
||||
]
|
||||
ids = [
|
||||
{'type': 'int', 'id': 'clid'}
|
||||
]
|
||||
|
||||
operations = dict({
|
||||
'obj': [{'get': 'properties'}, {'get': 'list'}],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
'dependency': [{'get': 'dependencies'}],
|
||||
'dependent': [{'get': 'dependents'}],
|
||||
'module.js': [{}, {}, {'get': 'module_js'}]
|
||||
})
|
||||
|
||||
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 self
|
||||
"""
|
||||
@wraps(f)
|
||||
def wrap(*args, **kwargs):
|
||||
# Here args[0] will hold self & kwargs will hold gid,sid,did
|
||||
self = args[0]
|
||||
self.manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(
|
||||
kwargs['sid']
|
||||
)
|
||||
self.conn = self.manager.connection(did=kwargs['did'])
|
||||
# If DB not connected then return error to browser
|
||||
if not self.conn.connected():
|
||||
return precondition_required(
|
||||
gettext(
|
||||
"Connection to the server has been lost!"
|
||||
)
|
||||
)
|
||||
|
||||
self.template_path = 'catalog_object_column/sql/9.1_plus'
|
||||
|
||||
return f(*args, **kwargs)
|
||||
|
||||
return wrap
|
||||
|
||||
@check_precondition
|
||||
def list(self, gid, sid, did, scid, coid):
|
||||
"""
|
||||
This function is used to list all the column
|
||||
nodes within that collection.
|
||||
|
||||
Args:
|
||||
gid: Server group ID
|
||||
sid: Server ID
|
||||
did: Database ID
|
||||
scid: Schema ID
|
||||
coid: Catalog objects ID
|
||||
|
||||
Returns:
|
||||
JSON of available column nodes
|
||||
"""
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'properties.sql']), coid=coid)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
return ajax_response(
|
||||
response=res['rows'],
|
||||
status=200
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
def nodes(self, gid, sid, did, scid, coid):
|
||||
"""
|
||||
This function will used to create all the child node within that collection.
|
||||
Here it will create all the column node.
|
||||
|
||||
Args:
|
||||
gid: Server Group ID
|
||||
sid: Server ID
|
||||
did: Database ID
|
||||
scid: Schema ID
|
||||
coid: Catalog objects ID
|
||||
|
||||
Returns:
|
||||
JSON of available column child nodes
|
||||
"""
|
||||
res = []
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'nodes.sql']), coid=coid)
|
||||
status, rset = self.conn.execute_2darray(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=rset)
|
||||
|
||||
for row in rset['rows']:
|
||||
res.append(
|
||||
self.blueprint.generate_browser_node(
|
||||
row['atttypid'],
|
||||
coid,
|
||||
row['attname'],
|
||||
icon="icon-catalog_object_column"
|
||||
))
|
||||
|
||||
return make_json_response(
|
||||
data=res,
|
||||
status=200
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
def properties(self, gid, sid, did, scid, coid, clid):
|
||||
"""
|
||||
This function will show the properties of the selected
|
||||
column node.
|
||||
|
||||
Args:
|
||||
gid: Server Group ID
|
||||
sid: Server ID
|
||||
did: Database ID
|
||||
scid: Schema ID
|
||||
scid: Schema ID
|
||||
coid: Catalog object ID
|
||||
clid: Column ID
|
||||
|
||||
Returns:
|
||||
JSON of selected column node
|
||||
"""
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'properties.sql']),coid=coid, clid=clid)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return ajax_response(
|
||||
response=res['rows'][0],
|
||||
status=200
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
def dependents(self, gid, sid, did, scid, coid, clid):
|
||||
"""
|
||||
This function get the dependents and return ajax response
|
||||
for the column node.
|
||||
|
||||
Args:
|
||||
gid: Server Group ID
|
||||
sid: Server ID
|
||||
did: Database ID
|
||||
scid: Schema ID
|
||||
coid: Catalog object ID
|
||||
clid: Column ID
|
||||
"""
|
||||
# Specific condition for column which we need to append
|
||||
where = "WHERE dep.refobjid={0}::OID AND dep.refobjsubid={1}".format(
|
||||
coid, clid
|
||||
)
|
||||
|
||||
dependents_result = self.get_dependents(
|
||||
self.conn, clid, where=where
|
||||
)
|
||||
|
||||
# Specific sql to run againt column to fetch dependents
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
'depend.sql']), where=where)
|
||||
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
for row in res['rows']:
|
||||
ref_name = row['refname']
|
||||
if ref_name is None:
|
||||
continue
|
||||
|
||||
dep_type = ''
|
||||
dep_str = row['deptype']
|
||||
if dep_str == 'a':
|
||||
dep_type = 'auto'
|
||||
elif dep_str == 'n':
|
||||
dep_type = 'normal'
|
||||
elif dep_str == 'i':
|
||||
dep_type = 'internal'
|
||||
|
||||
dependents_result.append({'type': 'sequence', 'name': ref_name, 'field': dep_type})
|
||||
|
||||
return ajax_response(
|
||||
response=dependents_result,
|
||||
status=200
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
def dependencies(self, gid, sid, did, scid, coid, clid):
|
||||
"""
|
||||
This function get the dependencies and return ajax response
|
||||
for the column node.
|
||||
|
||||
Args:
|
||||
gid: Server Group ID
|
||||
sid: Server ID
|
||||
did: Database ID
|
||||
scid: Schema ID
|
||||
coid: Catalog objects ID
|
||||
clid: Column ID
|
||||
|
||||
"""
|
||||
# Specific condition for column which we need to append
|
||||
where = "WHERE dep.objid={0}::OID AND dep.objsubid={1}".format(
|
||||
coid, clid
|
||||
)
|
||||
|
||||
dependencies_result = self.get_dependencies(
|
||||
self.conn, clid, where=where
|
||||
)
|
||||
|
||||
return ajax_response(
|
||||
response=dependencies_result,
|
||||
status=200
|
||||
)
|
||||
|
||||
|
||||
CatalogObjectColumnsView.register_node_view(blueprint)
|
Binary file not shown.
After Width: | Height: | Size: 435 B |
Binary file not shown.
After Width: | Height: | Size: 400 B |
@ -0,0 +1,73 @@
|
||||
define(
|
||||
['jquery', 'underscore', 'underscore.string', 'pgadmin', 'pgadmin.browser', 'alertify', 'pgadmin.browser.collection'],
|
||||
function($, _, S, pgAdmin, pgBrowser, alertify) {
|
||||
|
||||
if (!pgBrowser.Nodes['coll-catalog_object_column']) {
|
||||
var databases = pgAdmin.Browser.Nodes['coll-catalog_object_column'] =
|
||||
pgAdmin.Browser.Collection.extend({
|
||||
node: 'catalog_object_column',
|
||||
label: '{{ _('catalog_object_column') }}',
|
||||
type: 'coll-catalog_object_column'
|
||||
});
|
||||
};
|
||||
|
||||
if (!pgBrowser.Nodes['catalog_object_column']) {
|
||||
pgAdmin.Browser.Nodes['catalog_object_column'] =
|
||||
pgAdmin.Browser.Node.extend({
|
||||
parent_type: 'catalog_object',
|
||||
type: 'catalog_object_column',
|
||||
label: '{{ _('catalog_object_column') }}',
|
||||
hasSQL: false,
|
||||
hasDepends: true,
|
||||
Init: function() {
|
||||
/* Avoid mulitple registration of menus */
|
||||
if (this.initialized)
|
||||
return;
|
||||
|
||||
this.initialized = true;
|
||||
|
||||
},
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
defaults: {
|
||||
attname: undefined,
|
||||
attowner: undefined,
|
||||
atttypid: undefined,
|
||||
attnum: undefined,
|
||||
cltype: undefined,
|
||||
collspcname: undefined,
|
||||
attacl: undefined,
|
||||
description: undefined
|
||||
},
|
||||
schema: [{
|
||||
id: 'attname', label: '{{ _('Column') }}', cell: 'string',
|
||||
type: 'text', disabled: true
|
||||
},{
|
||||
id: 'atttypid', label: '{{ _('Oid') }}', cell: 'string',
|
||||
type: 'text', disabled: true
|
||||
},{
|
||||
id: 'attowner', label: '{{ _('Owner') }}', cell: 'string',
|
||||
type: 'text', disabled: true
|
||||
},{
|
||||
id: 'attnum', label:'{{ _('Position') }}', cell: 'string',
|
||||
type: 'text', disabled: true
|
||||
},{
|
||||
id: 'cltype', label:'{{ _('Data type') }}', cell: 'string',
|
||||
type: 'text', disabled: true
|
||||
},{
|
||||
id: 'collspcname', label:'{{ _('Collation') }}', cell: 'string',
|
||||
type: 'text', disabled: true
|
||||
},{
|
||||
id: 'attacl', label:'{{ _('ACL') }}', cell: 'string',
|
||||
type: 'text', disabled: true
|
||||
},{
|
||||
id: 'description', label:'{{ _('Comment') }}', cell: 'string',
|
||||
type: 'multiline', disabled: true
|
||||
}
|
||||
]
|
||||
})
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return pgBrowser.Nodes['catalog_object_column'];
|
||||
});
|
@ -0,0 +1,10 @@
|
||||
SELECT
|
||||
ref.relname AS refname, d2.refclassid, dep.deptype AS deptype
|
||||
FROM pg_depend dep
|
||||
LEFT JOIN pg_depend d2 ON dep.objid=d2.objid AND dep.refobjid != d2.refobjid
|
||||
LEFT JOIN pg_class ref ON ref.oid=d2.refobjid
|
||||
LEFT JOIN pg_attribute att ON d2.refclassid=att.attrelid AND d2.refobjsubid=att.attnum
|
||||
{{ where }} AND
|
||||
dep.classid=(SELECT oid FROM pg_class WHERE relname='pg_attrdef') AND
|
||||
dep.refobjid NOT IN (SELECT d3.refobjid FROM pg_depend d3 WHERE d3.objid=d2.refobjid)
|
||||
ORDER BY refname;
|
@ -0,0 +1,7 @@
|
||||
SELECT
|
||||
atttypid, attname
|
||||
FROM pg_attribute att
|
||||
WHERE att.attrelid = {{coid}}::oid
|
||||
AND att.attnum > 0
|
||||
AND att.attisdropped IS FALSE
|
||||
ORDER BY att.attnum
|
@ -0,0 +1,41 @@
|
||||
SELECT
|
||||
att.*, def.*, pg_catalog.pg_get_expr(def.adbin, def.adrelid) AS defval,
|
||||
CASE WHEN att.attndims > 0 THEN 1 ELSE 0 END AS isarray,
|
||||
format_type(ty.oid,NULL) AS typname,
|
||||
format_type(ty.oid,att.atttypmod) AS displaytypname,
|
||||
tn.nspname as typnspname, et.typname as elemtypname,
|
||||
ty.typstorage AS defaultstorage, cl.relname, na.nspname,
|
||||
att.attstattarget, description, cs.relname AS sername,
|
||||
ns.nspname AS serschema,
|
||||
(SELECT count(1) FROM pg_type t2 WHERE t2.typname=ty.typname) > 1 AS isdup,
|
||||
indkey, coll.collname, nspc.nspname as collnspname , attoptions,
|
||||
-- Start pgAdmin4, added to save time on client side parsing
|
||||
CASE WHEN length(coll.collname) > 0 AND length(nspc.nspname) > 0 THEN
|
||||
concat(coll.collname,'."',nspc.nspname,'"')
|
||||
ELSE '' END AS collspcname,
|
||||
CASE WHEN strpos(format_type(ty.oid,att.atttypmod), '.') > 0 THEN
|
||||
split_part(format_type(ty.oid,att.atttypmod), '.', 2)
|
||||
ELSE format_type(ty.oid,att.atttypmod) END AS cltype,
|
||||
-- End pgAdmin4
|
||||
EXISTS(SELECT 1 FROM pg_constraint WHERE conrelid=att.attrelid AND contype='f' AND att.attnum=ANY(conkey)) As isfk,
|
||||
(SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=att.attrelid AND sl1.objsubid=att.attnum) AS labels,
|
||||
(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=att.attrelid AND sl2.objsubid=att.attnum) AS providers
|
||||
FROM pg_attribute att
|
||||
JOIN pg_type ty ON ty.oid=atttypid
|
||||
JOIN pg_namespace tn ON tn.oid=ty.typnamespace
|
||||
JOIN pg_class cl ON cl.oid=att.attrelid
|
||||
JOIN pg_namespace na ON na.oid=cl.relnamespace
|
||||
LEFT OUTER JOIN pg_type et ON et.oid=ty.typelem
|
||||
LEFT OUTER JOIN pg_attrdef def ON adrelid=att.attrelid AND adnum=att.attnum
|
||||
LEFT OUTER JOIN pg_description des ON (des.objoid=att.attrelid AND des.objsubid=att.attnum AND des.classoid='pg_class'::regclass)
|
||||
LEFT OUTER JOIN (pg_depend JOIN pg_class cs ON objid=cs.oid AND cs.relkind='S') ON refobjid=att.attrelid AND refobjsubid=att.attnum
|
||||
LEFT OUTER JOIN pg_namespace ns ON ns.oid=cs.relnamespace
|
||||
LEFT OUTER JOIN pg_index pi ON pi.indrelid=att.attrelid AND indisprimary
|
||||
LEFT OUTER JOIN pg_collation coll ON att.attcollation=coll.oid
|
||||
LEFT OUTER JOIN pg_namespace nspc ON coll.collnamespace=nspc.oid
|
||||
WHERE att.attrelid = {{coid}}::oid{% if clid %}
|
||||
AND att.atttypid = {{clid}}::oid
|
||||
{% endif %}
|
||||
AND att.attnum > 0
|
||||
AND att.attisdropped IS FALSE
|
||||
ORDER BY att.attnum
|
Binary file not shown.
After Width: | Height: | Size: 409 B |
Binary file not shown.
After Width: | Height: | Size: 419 B |
@ -0,0 +1,56 @@
|
||||
define(
|
||||
['jquery', 'underscore', 'underscore.string', 'pgadmin', 'pgadmin.browser', 'alertify', 'pgadmin.browser.collection'],
|
||||
function($, _, S, pgAdmin, pgBrowser, alertify) {
|
||||
|
||||
if (!pgBrowser.Nodes['coll-catalog_object']) {
|
||||
var databases = pgAdmin.Browser.Nodes['coll-catalog_object'] =
|
||||
pgAdmin.Browser.Collection.extend({
|
||||
node: 'catalog_object',
|
||||
label: '{{ _('Catalog Objects') }}',
|
||||
type: 'coll-catalog_object'
|
||||
});
|
||||
};
|
||||
|
||||
if (!pgBrowser.Nodes['catalog_object']) {
|
||||
pgAdmin.Browser.Nodes['catalog_object'] = pgAdmin.Browser.Node.extend({
|
||||
parent_type: 'catalog',
|
||||
type: 'catalog_object',
|
||||
label: '{{ _('Catalog Object') }}',
|
||||
hasSQL: false,
|
||||
hasDepends: true,
|
||||
Init: function() {
|
||||
/* Avoid mulitple registration of menus */
|
||||
if (this.initialized)
|
||||
return;
|
||||
|
||||
this.initialized = true;
|
||||
|
||||
},
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
defaults: {
|
||||
name: undefined,
|
||||
namespaceowner: undefined,
|
||||
nspacl: undefined,
|
||||
description: undefined,
|
||||
},
|
||||
schema: [{
|
||||
id: 'name', label: '{{ _('Name') }}', cell: 'string',
|
||||
type: 'text', disabled: true
|
||||
},{
|
||||
id: 'oid', label:'{{ _('Oid') }}', cell: 'string',
|
||||
type: 'text', disabled: true
|
||||
},{
|
||||
id: 'owner', label:'{{ _('Owner') }}', cell: 'string',
|
||||
type: 'text', disabled: true
|
||||
},{
|
||||
id: 'description', label:'{{ _('Comment') }}', cell: 'string',
|
||||
type: 'multiline' , disabled: true
|
||||
}
|
||||
]
|
||||
})
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return pgBrowser.Nodes['catalog_object'];
|
||||
});
|
@ -0,0 +1,6 @@
|
||||
SELECT
|
||||
c.oid, c.relname as name
|
||||
FROM
|
||||
pg_class c
|
||||
WHERE relnamespace = {{scid}}::int
|
||||
ORDER BY relname;
|
@ -0,0 +1,12 @@
|
||||
SELECT
|
||||
c.oid, c.relname as name, r.rolname AS owner, description
|
||||
FROM
|
||||
pg_class c
|
||||
LEFT OUTER JOIN pg_description d
|
||||
ON d.objoid=c.oid AND d.classoid='pg_class'::regclass
|
||||
LEFT JOIN pg_roles r ON c.relowner = r.oid
|
||||
WHERE
|
||||
relnamespace = {{scid}}::int
|
||||
{% if coid %} AND
|
||||
c.oid = {{coid}}::int
|
||||
{% endif %} ORDER BY relname;
|
@ -0,0 +1,11 @@
|
||||
SELECT
|
||||
c.oid, c.relname as name
|
||||
FROM pg_class c
|
||||
WHERE relnamespace = {{scid}}::int
|
||||
OR (
|
||||
-- On EnterpriseDB we need to ignore some objects in the catalog, namely, _*, dual and type_object_source.
|
||||
select 'sys' ~ (SELECT nsp.nspname FROM pg_namespace nsp WHERE nsp.oid = {{scid}}::int)
|
||||
AND
|
||||
(c.relname NOT LIKE '\\_%' AND c.relname = 'dual' AND c.relname = 'type_object_source')
|
||||
)
|
||||
ORDER BY relname;
|
@ -0,0 +1,23 @@
|
||||
SELECT
|
||||
c.oid, c.relname as name, r.rolname AS owner, description
|
||||
FROM
|
||||
pg_class c
|
||||
LEFT OUTER JOIN pg_description d
|
||||
ON d.objoid=c.oid AND d.classoid='pg_class'::regclass
|
||||
LEFT JOIN pg_roles r ON c.relowner = r.oid
|
||||
WHERE
|
||||
relnamespace = {{scid}}::int
|
||||
{% if coid %} AND
|
||||
c.oid = {{coid}}::int
|
||||
{% endif %} OR (
|
||||
-- On EnterpriseDB - ignore some objects in the catalog, whose name starts
|
||||
-- with _*, dual and type_object_source.
|
||||
SELECT 'sys' ~ (
|
||||
SELECT nsp.nspname FROM pg_namespace nsp
|
||||
WHERE nsp.oid = {{scid}}::int
|
||||
) AND (
|
||||
c.relname NOT LIKE '\\_%' AND c.relname = 'dual' AND
|
||||
c.relname = 'type_object_source'
|
||||
)
|
||||
)
|
||||
ORDER BY relname;
|
Loading…
Reference in New Issue
Block a user