From 5347bdb886ca321bfb36d6b7662e70af5af3ef52 Mon Sep 17 00:00:00 2001 From: Murtuza Zabuawala Date: Fri, 11 Mar 2016 01:08:21 +0530 Subject: [PATCH] Added support for the catalog objects under special catalogs. (also, added support for columns under it). --- .../schemas/catalog_objects/__init__.py | 300 +++++++++++++++ .../catalog_objects/columns/__init__.py | 343 ++++++++++++++++++ .../static/img/catalog_object_column.png | Bin 0 -> 435 bytes .../static/img/coll-catalog_object_column.png | Bin 0 -> 400 bytes .../js/catalog_object_column.js | 73 ++++ .../sql/9.1_plus/depend.sql | 10 + .../sql/9.1_plus/nodes.sql | 7 + .../sql/9.1_plus/properties.sql | 41 +++ .../static/img/catalog_object.png | Bin 0 -> 409 bytes .../static/img/coll-catalog_object.png | Bin 0 -> 419 bytes .../catalog_object/js/catalog_object.js | 56 +++ .../catalog_object/sql/pg/9.1_plus/nodes.sql | 6 + .../sql/pg/9.1_plus/properties.sql | 12 + .../sql/ppas/9.1_plus/nodes.sql | 11 + .../sql/ppas/9.1_plus/properties.sql | 23 ++ 15 files changed, 882 insertions(+) create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/__init__.py create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/__init__.py create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/static/img/catalog_object_column.png create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/static/img/coll-catalog_object_column.png create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/templates/catalog_object_column/js/catalog_object_column.js create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/templates/catalog_object_column/sql/9.1_plus/depend.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/templates/catalog_object_column/sql/9.1_plus/nodes.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/templates/catalog_object_column/sql/9.1_plus/properties.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/static/img/catalog_object.png create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/static/img/coll-catalog_object.png create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/templates/catalog_object/js/catalog_object.js create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/templates/catalog_object/sql/pg/9.1_plus/nodes.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/templates/catalog_object/sql/pg/9.1_plus/properties.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/templates/catalog_object/sql/ppas/9.1_plus/nodes.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/templates/catalog_object/sql/ppas/9.1_plus/properties.sql diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/__init__.py new file mode 100644 index 000000000..6437f6ae7 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/__init__.py @@ -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) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/__init__.py new file mode 100644 index 000000000..8f5a734d2 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/__init__.py @@ -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) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/static/img/catalog_object_column.png b/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/static/img/catalog_object_column.png new file mode 100644 index 0000000000000000000000000000000000000000..bd9f81df98fe27d81ade5144d66b3b09b96123c1 GIT binary patch literal 435 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}X@F0NE09*4`h3Ev&s(m&yLCXv$t$X?M<;s;SSFBjEcJ12r>({?} z_3FWc2M-@UeDvti>eZ{)tXZ>Z)20s}KD>VY`qQURpFe;8`t|F#Z{K$8*s)>5hK(CH ze*gac?c2BS-o49eKe!ZVF=I)PUoeBivm0qZ4rhT!WHFHT0Ash4*>*risi%u$h{WaE z^B0Ah6a-om4Rm-iuV3+XfEpM)UHx3vIVCg! E0NRqnZ~y=R literal 0 HcmV?d00001 diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/static/img/coll-catalog_object_column.png b/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/static/img/coll-catalog_object_column.png new file mode 100644 index 0000000000000000000000000000000000000000..89d758834d4176c1df2548db10b46b1f6b2e4ec5 GIT binary patch literal 400 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}cz{ocE09*4`h3Ev&s(m&yL({S;_3G90=g%KJ zc<}o5>kl73eEaro$BrEvHf-3qapU*z-`~D{TatgM6KFJJNswPKgTu2MX+REVfk$L9 zkoEv$x0Bg+Kt_S5i(`ny<=FG?VhsvBt`}W4E@ZQg__p6qm@nby;qrG1j0_I@c^(;r zuhP)2X?)FK#IZ0 zz|cU~&`8(7FvQ5f%EZ{p#6;V`)XKoXVy3DbiiX_$l+3hBhz0{oum+H7D+4o#hEvl+ R*8nvzc)I$ztaD0e0s#BYr!@co literal 0 HcmV?d00001 diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/templates/catalog_object_column/js/catalog_object_column.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/templates/catalog_object_column/js/catalog_object_column.js new file mode 100644 index 000000000..3c6a9ffd7 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/templates/catalog_object_column/js/catalog_object_column.js @@ -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']; +}); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/templates/catalog_object_column/sql/9.1_plus/depend.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/templates/catalog_object_column/sql/9.1_plus/depend.sql new file mode 100644 index 000000000..024103f09 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/templates/catalog_object_column/sql/9.1_plus/depend.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/templates/catalog_object_column/sql/9.1_plus/nodes.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/templates/catalog_object_column/sql/9.1_plus/nodes.sql new file mode 100644 index 000000000..66c25bf0a --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/templates/catalog_object_column/sql/9.1_plus/nodes.sql @@ -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 diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/templates/catalog_object_column/sql/9.1_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/templates/catalog_object_column/sql/9.1_plus/properties.sql new file mode 100644 index 000000000..5a6c0d8c1 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/columns/templates/catalog_object_column/sql/9.1_plus/properties.sql @@ -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 diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/static/img/catalog_object.png b/web/pgadmin/browser/server_groups/servers/databases/schemas/catalog_objects/static/img/catalog_object.png new file mode 100644 index 0000000000000000000000000000000000000000..54ed7389c128fdcdcd86bc504311b9ed62e890ff GIT binary patch literal 409 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}QGic~E09*4`n>nT|4HY6FS`77 z*NwLq@4vkN`1#Xk&!0VecI)BOHRqluZ+xLQ`$hNp|E*{K)t&fLdiYn)z8{G@zJ+c2 z?7ilL!}53L3*P9?d8IbvW$T&0+53JtE_-LT@QvP_S6i;V`}u8J`~K&*j@bWvKj-(& zo4+qyn4y_82WTr}NswPKgTu2MX+REVfk$L9koEv$x0Bg+Kt`OWi(`ny<>Z6}7e*c) zo*thwI%{&?$jq4&bH`?n0;63WqoZP?V4z_kr{@MPJ55H%%mocSYh+v;;u!fv4l;3h zFz78{aWi04RS0O9aOL`DhzbWT`uD$x{ z)SXxN9zTEf{Q0wI&yL=BR<`qn!JHQzXa5Cl__X=z+n?X2HJ|=hb?kTkfuG4czlCl3 z?78}b?b5e~^IogZeA#^ZuNRQJDm=t0E5ucyF7nz8Xt`>M zYeY#(Vo9o1a#1RfVlXl=G|)9P(lsy)F*2|+F}5->(Kax(GBB{1sVaw}AvZrIGp!P$ f!N3x%0i@c>zzm|{)b!9bKn)C@u6{1-oD!M