From 782ac5288fdbab1fd1f7cdc3e8b93d4c0211a6d8 Mon Sep 17 00:00:00 2001 From: Warren Chan Date: Thu, 3 Sep 2020 11:16:14 +1000 Subject: [PATCH] changes to add new node (copy of sequence) under schema --- .../databases/schemas/foos/__init__.py | 965 ++++++++++++++++++ .../schemas/foos/static/img/coll-foo.svg | 1 + .../databases/schemas/foos/static/img/foo.svg | 1 + .../databases/schemas/foos/static/js/foo.js | 299 ++++++ .../templates/foos/sql/10_plus/get_def.sql | 11 + .../foos/templates/foos/sql/default/acl.sql | 30 + .../foos/sql/default/backend_support.sql | 15 + .../templates/foos/sql/default/coll_stats.sql | 9 + .../templates/foos/sql/default/create.sql | 16 + .../templates/foos/sql/default/delete.sql | 1 + .../templates/foos/sql/default/get_def.sql | 10 + .../foos/sql/default/get_dependencies.sql | 12 + .../templates/foos/sql/default/get_oid.sql | 7 + .../foos/templates/foos/sql/default/grant.sql | 26 + .../foos/templates/foos/sql/default/nodes.sql | 11 + .../templates/foos/sql/default/properties.sql | 17 + .../foos/templates/foos/sql/default/stats.sql | 7 + .../templates/foos/sql/default/update.sql | 97 ++ .../templates/foos/sql/gpdb_5.0_plus/acl.sql | 7 + .../databases/schemas/foos/tests/__init__.py | 15 + .../tests/pg/default/alter_neg_seq_props.sql | 13 + .../pg/default/alter_neg_seq_props_msql.sql | 4 + .../tests/pg/default/alter_seq_comment.sql | 16 + .../pg/default/alter_seq_comment_msql.sql | 2 + .../tests/pg/default/alter_seq_privs_add.sql | 21 + .../pg/default/alter_seq_privs_add_msql.sql | 1 + .../pg/default/alter_seq_privs_remove.sql | 19 + .../default/alter_seq_privs_remove_msql.sql | 1 + .../pg/default/alter_seq_privs_update.sql | 21 + .../default/alter_seq_privs_update_msql.sql | 2 + .../foos/tests/pg/default/alter_seq_props.sql | 17 + .../tests/pg/default/alter_seq_props_msql.sql | 8 + .../pg/default/create_negative_sequence.sql | 13 + .../default/create_negative_sequence_msql.sql | 9 + .../foos/tests/pg/default/create_sequence.sql | 13 + .../tests/pg/default/create_sequence_msql.sql | 9 + .../tests/pg/default/test_sequences_pg.json | 173 ++++ .../ppas/default/alter_neg_seq_props.sql | 13 + .../ppas/default/alter_neg_seq_props_msql.sql | 4 + .../tests/ppas/default/alter_seq_comment.sql | 16 + .../ppas/default/alter_seq_comment_msql.sql | 2 + .../ppas/default/alter_seq_privs_add.sql | 21 + .../ppas/default/alter_seq_privs_add_msql.sql | 1 + .../ppas/default/alter_seq_privs_remove.sql | 19 + .../default/alter_seq_privs_remove_msql.sql | 1 + .../ppas/default/alter_seq_privs_update.sql | 21 + .../default/alter_seq_privs_update_msql.sql | 2 + .../tests/ppas/default/alter_seq_props.sql | 17 + .../ppas/default/alter_seq_props_msql.sql | 8 + .../ppas/default/create_negative_sequence.sql | 13 + .../default/create_negative_sequence_msql.sql | 9 + .../tests/ppas/default/create_sequence.sql | 13 + .../ppas/default/create_sequence_msql.sql | 9 + .../ppas/default/test_sequences_ppas.json | 173 ++++ .../schemas/foos/tests/test_sequence_add.py | 126 +++ .../foos/tests/test_sequence_delete.py | 69 ++ .../tests/test_sequence_delete_multiple.py | 93 ++ .../schemas/foos/tests/test_sequence_get.py | 64 ++ .../schemas/foos/tests/test_sequence_put.py | 98 ++ .../databases/schemas/foos/tests/utils.py | 89 ++ web/webpack.config.js | 1 + web/webpack.shim.js | 1 + 62 files changed, 2782 insertions(+) create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/__init__.py create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/static/img/coll-foo.svg create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/static/img/foo.svg create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/static/js/foo.js create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/10_plus/get_def.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/acl.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/backend_support.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/coll_stats.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/create.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/delete.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/get_def.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/get_dependencies.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/get_oid.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/grant.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/nodes.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/properties.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/stats.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/update.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/gpdb_5.0_plus/acl.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/__init__.py create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_neg_seq_props.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_neg_seq_props_msql.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_comment.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_comment_msql.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_add.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_add_msql.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_remove.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_remove_msql.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_update.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_update_msql.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_props.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_props_msql.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_negative_sequence.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_negative_sequence_msql.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_sequence.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_sequence_msql.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/test_sequences_pg.json create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_neg_seq_props.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_neg_seq_props_msql.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_comment.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_comment_msql.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_add.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_add_msql.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_remove.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_remove_msql.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_update.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_update_msql.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_props.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_props_msql.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_negative_sequence.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_negative_sequence_msql.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_sequence.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_sequence_msql.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/test_sequences_ppas.json create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_add.py create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_delete.py create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_delete_multiple.py create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_get.py create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_put.py create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/utils.py diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/__init__.py new file mode 100644 index 000000000..3bc310d6f --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/__init__.py @@ -0,0 +1,965 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2020, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +"""Implements Foo Node""" + +from functools import wraps + +import simplejson as json +from flask import render_template, request, jsonify +from flask_babelex import gettext as _ + +import pgadmin.browser.server_groups.servers.databases as database +from config import PG_DEFAULT_DRIVER +from pgadmin.browser.server_groups.servers.databases.schemas.utils \ + import SchemaChildModule +from pgadmin.browser.server_groups.servers.utils import parse_priv_from_db, \ + parse_priv_to_db +from pgadmin.browser.utils import PGChildNodeView +from pgadmin.tools.schema_diff.compare import SchemaDiffObjectCompare +from pgadmin.tools.schema_diff.node_registry import SchemaDiffRegistry +from pgadmin.utils.ajax import make_json_response, internal_server_error, \ + make_response as ajax_response, gone +from pgadmin.utils.driver import get_driver + + +class FooModule(SchemaChildModule): + """ + class SequenceModule(CollectionNodeModule) + + A module class for Sequence node derived from CollectionNodeModule. + + Methods: + ------- + * __init__(*args, **kwargs) + - Method is used to initialize the SequenceModule and it's base module. + + * get_nodes(gid, sid, did) + - Method is used to generate the browser collection node. + + * script_load() + - Load the module script for sequence, when any of the database node is + initialized. + + * node_inode() + - Method is overridden from its base class to make the node as leaf node. + + """ + + _NODE_TYPE = 'foo' + _COLLECTION_LABEL = _("Foos Node") + + def __init__(self, *args, **kwargs): + super(FooModule, self).__init__(*args, **kwargs) + self.min_ver = None + self.max_ver = None + self.min_gpdbver = 1000000000 + + def get_nodes(self, gid, sid, did, scid): + """ + Generate the sequence node + """ + yield self.generate_browser_collection_node(scid) + + @property + def script_load(self): + """ + Load the module script for database, when any of the database node is + initialized. + """ + return database.DatabaseModule.node_type + + @property + def node_inode(self): + """ + Override this property to make the node a leaf node. + + Returns: False as this is the leaf node + """ + return False + + +blueprint = FooModule(__name__) + + +class FooView(PGChildNodeView, SchemaDiffObjectCompare): + 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': 'fooid'} + ] + + operations = dict({ + 'obj': [ + {'get': 'properties', 'delete': 'delete', 'put': 'update'}, + {'get': 'list', 'post': 'create', 'delete': 'delete'} + ], + 'delete': [{'delete': 'delete'}, {'delete': 'delete'}], + 'children': [{'get': 'children'}], + 'nodes': [{'get': 'nodes'}, {'get': 'nodes'}], + 'sql': [{'get': 'sql'}], + 'msql': [{'get': 'msql'}, {'get': 'msql'}], + 'stats': [{'get': 'statistics'}, {'get': 'statistics'}], + 'dependency': [{'get': 'dependencies'}], + 'dependent': [{'get': 'dependents'}] + }) + + def check_precondition(action=None): + """ + 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 + """ + + def wrap(f): + @wraps(f) + def wrapped(self, *args, **kwargs): + + driver = get_driver(PG_DEFAULT_DRIVER) + self.manager = driver.connection_manager(kwargs['sid']) + + if action and action in ["drop"]: + self.conn = self.manager.connection() + elif 'did' in kwargs: + self.conn = self.manager.connection(did=kwargs['did']) + else: + self.conn = self.manager.connection() + self.datlastsysoid = \ + self.manager.db_info[kwargs['did']]['datlastsysoid'] \ + if self.manager.db_info is not None and \ + kwargs['did'] in self.manager.db_info else 0 + + self.template_path = 'sequences/sql/#{0}#'.format( + self.manager.version + ) + self.acl = ['r', 'w', 'U'] + self.qtIdent = driver.qtIdent + + return f(self, *args, **kwargs) + return wrapped + return wrap + + @check_precondition(action='list') + def list(self, gid, sid, did, scid): + """ + This function is used to list all the sequence nodes within the + collection. + + Args: + gid: Server Group ID + sid: Server ID + did: Database ID + scid: Schema ID + + Returns: + + """ + SQL = render_template( + "/".join([self.template_path, self._PROPERTIES_SQL]), + scid=scid + ) + status, res = self.conn.execute_dict(SQL) + + if not status: + return internal_server_error(errormsg=res) + + sequence_nodes = self._get_sequence_nodes(res['rows']) + return ajax_response( + response=sequence_nodes, + status=200 + ) + + @check_precondition(action='nodes') + def nodes(self, gid, sid, did, scid, fooid=None): + """ + This function is used to create all the child nodes within the + collection, Here it will create all the sequence nodes. + + Args: + gid: Server Group ID + sid: Server ID + did: Database ID + scid: Schema ID + + Returns: + + """ + res = [] + SQL = render_template( + "/".join([self.template_path, self._NODES_SQL]), + scid=scid, + fooid=fooid + ) + status, rset = self.conn.execute_dict(SQL) + if not status: + return internal_server_error(errormsg=rset) + + if fooid is not None: + if len(rset['rows']) == 0: + return gone(errormsg=_("Could not find the sequence.")) + row = rset['rows'][0] + return make_json_response( + data=self.blueprint.generate_browser_node( + row['oid'], + scid, + row['name'], + icon="icon-%s" % self.node_type + ), + status=200 + ) + + sequence_nodes = self._get_sequence_nodes(rset['rows']) + for row in sequence_nodes: + res.append( + self.blueprint.generate_browser_node( + row['oid'], + scid, + row['name'], + icon="icon-%s" % self.node_type + )) + + return make_json_response( + data=res, + status=200 + ) + + def _get_sequence_nodes(self, nodes): + """ + This function is used to iterate through all the sequences node and + hiding sequences created as part of an IDENTITY column. + :param nodes: + :return: + """ + # If show_system_objects is true then no need to hide any sequences. + if self.blueprint.show_system_objects: + return nodes + + seq_nodes = [] + for row in nodes: + system_seq = self._get_dependency(row['oid'], + show_system_objects=True) + seq = filter(lambda dep: dep['type'] == 'column' and + dep['field'] == 'internal', system_seq) + if type(seq) is not list: + seq = list(seq) + if len(seq) > 0: + continue + + # Append the node into the newly created list + seq_nodes.append(row) + + return seq_nodes + + @check_precondition(action='properties') + def properties(self, gid, sid, did, scid, fooid): + """ + This function will show the properties of the selected sequence node. + + Args: + gid: Server Group ID + sid: Server ID + did: Database ID + scid: Schema ID + fooid: Sequence ID + + Returns: + + """ + status, res = self._fetch_properties(scid, fooid) + if not status: + return res + + return ajax_response( + response=res, + status=200 + ) + + def _fetch_properties(self, scid, fooid): + """ + This function is used to fetch the properties of the specified object. + :param scid: + :param fooid: + :return: + """ + + sql = render_template( + "/".join([self.template_path, self._PROPERTIES_SQL]), + scid=scid, fooid=fooid + ) + status, res = self.conn.execute_dict(sql) + + if not status: + return False, internal_server_error(errormsg=res) + elif len(res['rows']) == 0: + return False, gone( + _("Could not find the sequence in the database.")) + + res['rows'][0]['is_sys_obj'] = ( + res['rows'][0]['oid'] <= self.datlastsysoid) + + for row in res['rows']: + sql = render_template( + "/".join([self.template_path, 'get_def.sql']), + data=row + ) + status, rset1 = self.conn.execute_dict(sql) + if not status: + return False, internal_server_error(errormsg=rset1) + + row['current_value'] = rset1['rows'][0]['last_value'] + row['minimum'] = rset1['rows'][0]['min_value'] + row['maximum'] = rset1['rows'][0]['max_value'] + row['increment'] = rset1['rows'][0]['increment_by'] + row['start'] = rset1['rows'][0]['start_value'] + row['cache'] = rset1['rows'][0]['cache_value'] + row['cycled'] = rset1['rows'][0]['is_cycled'] + + self._add_securities_to_row(row) + + sql = render_template( + "/".join([self.template_path, self._ACL_SQL]), + scid=scid, fooid=fooid + ) + status, dataclres = self.conn.execute_dict(sql) + if not status: + return False, internal_server_error(errormsg=res) + + for row in dataclres['rows']: + priv = parse_priv_from_db(row) + if row['deftype'] in res['rows'][0]: + res['rows'][0][row['deftype']].append(priv) + else: + res['rows'][0][row['deftype']] = [priv] + + return True, res['rows'][0] + + def _add_securities_to_row(self, row): + sec_lbls = [] + if 'securities' in row and row['securities'] is not None: + for sec in row['securities']: + import re + sec = re.search(r'([^=]+)=(.*$)', sec) + sec_lbls.append({ + 'provider': sec.group(1), + 'label': sec.group(2) + }) + row['securities'] = sec_lbls + + @check_precondition(action="create") + def create(self, gid, sid, did, scid): + """ + Create the sequence. + + Args: + gid: Server Group ID + sid: Server ID + did: Database ID + scid: Schema ID + + Returns: + + """ + required_args = [ + u'name', + u'schema', + u'seqowner', + ] + + data = request.form if request.form else json.loads( + request.data, encoding='utf-8' + ) + + for arg in required_args: + if arg not in data: + return make_json_response( + status=400, + success=0, + errormsg=_( + "Could not find the required parameter ({})." + ).format(arg) + ) + + try: + # The SQL below will execute CREATE DDL only + sql = render_template( + "/".join([self.template_path, self._CREATE_SQL]), + data=data, conn=self.conn + ) + except Exception as e: + return internal_server_error(errormsg=e) + + status, msg = self.conn.execute_scalar(sql) + if not status: + return internal_server_error(errormsg=msg) + + if 'relacl' in data: + data['relacl'] = parse_priv_to_db(data['relacl'], self.acl) + + # The SQL below will execute rest DMLs because we cannot execute + # CREATE with any other + sql = render_template( + "/".join([self.template_path, self._GRANT_SQL]), + data=data, conn=self.conn + ) + sql = sql.strip('\n').strip(' ') + if sql and sql != "": + status, msg = self.conn.execute_scalar(sql) + if not status: + return internal_server_error(errormsg=msg) + + # We need oid of newly created sequence. + sql = render_template( + "/".join([self.template_path, self._OID_SQL]), + name=data['name'], + schema=data['schema'] + ) + sql = sql.strip('\n').strip(' ') + + status, rset = self.conn.execute_2darray(sql) + if not status: + return internal_server_error(errormsg=rset) + + row = rset['rows'][0] + return jsonify( + node=self.blueprint.generate_browser_node( + row['oid'], + row['relnamespace'], + data['name'], + icon="icon-%s" % self.node_type + ) + ) + + @check_precondition(action='delete') + def delete(self, gid, sid, did, scid, fooid=None, only_sql=False): + """ + This function will drop the object + + Args: + gid: Server Group ID + sid: Server ID + did: Database ID + scid: Schema ID + fooid: Sequence ID + only_sql: Return SQL only if True + + Returns: + + """ + if fooid is None: + data = request.form if request.form else json.loads( + request.data, encoding='utf-8' + ) + else: + data = {'ids': [fooid]} + + # Below will decide if it's simple drop or drop with cascade call + if self.cmd == 'delete': + # This is a cascade operation + cascade = True + else: + cascade = False + + try: + for fooid in data['ids']: + sql = render_template( + "/".join([self.template_path, self._PROPERTIES_SQL]), + scid=scid, fooid=fooid + ) + status, res = self.conn.execute_dict(sql) + if not status: + return internal_server_error(errormsg=res) + + elif not res['rows']: + return make_json_response( + success=0, + errormsg=_( + 'Error: Object not found.' + ), + info=_( + 'The specified sequence could not be found.\n' + ) + ) + + sql = render_template( + "/".join([self.template_path, self._DELETE_SQL]), + data=res['rows'][0], cascade=cascade + ) + + if only_sql: + return sql + + status, res = self.conn.execute_scalar(sql) + if not status: + return internal_server_error(errormsg=res) + + return make_json_response( + success=1, + info=_("Sequence dropped") + ) + + except Exception as e: + return internal_server_error(errormsg=str(e)) + + @check_precondition(action='update') + def update(self, gid, sid, did, scid, fooid): + """ + This function will update the object + + Args: + gid: Server Group ID + sid: Server ID + did: Database ID + scid: Schema ID + fooid: Sequence ID + + Returns: + + """ + data = request.form if request.form else json.loads( + request.data, encoding='utf-8' + ) + sql, name = self.get_SQL(gid, sid, did, data, scid, fooid) + # Most probably this is due to error + if not isinstance(sql, str): + return sql + + sql = sql.strip('\n').strip(' ') + + status, res = self.conn.execute_scalar(sql) + if not status: + return internal_server_error(errormsg=res) + + sql = render_template( + "/".join([self.template_path, self._NODES_SQL]), + fooid=fooid + ) + status, rset = self.conn.execute_2darray(sql) + if not status: + return internal_server_error(errormsg=rset) + row = rset['rows'][0] + + return jsonify( + node=self.blueprint.generate_browser_node( + fooid, + row['schema'], + row['name'], + icon="icon-%s" % self.node_type + ) + ) + + @check_precondition(action='msql') + def msql(self, gid, sid, did, scid, fooid=None): + """ + This function to return modified SQL. + + Args: + gid: Server Group ID + sid: Server ID + did: Database ID + scid: Schema ID + fooid: Sequence ID + """ + + data = {} + for k, v in request.args.items(): + try: + # comments should be taken as is because if user enters a + # json comment it is parsed by loads which should not happen + if k in ('comment',): + data[k] = v + else: + data[k] = json.loads(v, encoding='utf-8') + except ValueError: + data[k] = v + + if fooid is None: + required_args = [ + 'name', + 'schema' + ] + + for arg in required_args: + if arg not in data: + return make_json_response( + status=400, + success=0, + errormsg=_( + "Could not find the required parameter ({})." + ).format(arg) + ) + sql, name = self.get_SQL(gid, sid, did, data, scid, fooid) + # Most probably this is due to error + if not isinstance(sql, str): + return sql + + sql = sql.strip('\n').strip(' ') + if sql == '': + sql = "--modified SQL" + + return make_json_response( + data=sql, + status=200 + ) + + def get_SQL(self, gid, sid, did, data, scid, fooid=None): + """ + This function will generate sql from model data. + + Args: + gid: Server Group ID + sid: Server ID + did: Database ID + scid: Schema ID + fooid: Sequence ID + """ + + required_args = [ + u'name' + ] + + if fooid is not None: + sql = render_template( + "/".join([self.template_path, self._PROPERTIES_SQL]), + scid=scid, fooid=fooid + ) + status, res = self.conn.execute_dict(sql) + if not status: + return internal_server_error(errormsg=res) + elif len(res['rows']) == 0: + return gone(_("Could not find the sequence in the database.")) + + # Making copy of output for further processing + old_data = dict(res['rows'][0]) + old_data = self._formatter(old_data, scid, fooid) + + self._format_privilege_data(data) + + # If name is not present with in update data then copy it + # from old data + for arg in required_args: + if arg not in data: + data[arg] = old_data[arg] + sql = render_template( + "/".join([self.template_path, self._UPDATE_SQL]), + data=data, o_data=old_data, conn=self.conn + ) + return sql, data['name'] if 'name' in data else old_data['name'] + else: + # To format privileges coming from client + if 'relacl' in data: + data['relacl'] = parse_priv_to_db(data['relacl'], self.acl) + + sql = render_template( + "/".join([self.template_path, self._CREATE_SQL]), + data=data, conn=self.conn + ) + sql += render_template( + "/".join([self.template_path, self._GRANT_SQL]), + data=data, conn=self.conn + ) + return sql, data['name'] + + def _format_privilege_data(self, data): + # To format privileges data coming from client + for key in ['relacl']: + 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'], self.acl + ) + if 'changed' in data[key]: + data[key]['changed'] = parse_priv_to_db( + data[key]['changed'], self.acl + ) + if 'deleted' in data[key]: + data[key]['deleted'] = parse_priv_to_db( + data[key]['deleted'], self.acl + ) + + @check_precondition(action="sql") + def sql(self, gid, sid, did, scid, fooid, **kwargs): + """ + This function will generate sql for sql panel + + Args: + gid: Server Group ID + sid: Server ID + did: Database ID + scid: Schema ID + fooid: Sequence ID + json_resp: json response or plain text response + """ + json_resp = kwargs.get('json_resp', True) + + sql = render_template( + "/".join([self.template_path, self._PROPERTIES_SQL]), + scid=scid, fooid=fooid + ) + status, res = self.conn.execute_dict(sql) + if not status: + return internal_server_error(errormsg=res) + if len(res['rows']) == 0: + return gone(_("Could not find the sequence in the database.")) + + for row in res['rows']: + sql = render_template( + "/".join([self.template_path, 'get_def.sql']), + data=row + ) + status, rset1 = self.conn.execute_dict(sql) + if not status: + return internal_server_error(errormsg=rset1) + + row['current_value'] = rset1['rows'][0]['last_value'] + row['minimum'] = rset1['rows'][0]['min_value'] + row['maximum'] = rset1['rows'][0]['max_value'] + row['increment'] = rset1['rows'][0]['increment_by'] + row['start'] = rset1['rows'][0]['start_value'] + row['cache'] = rset1['rows'][0]['cache_value'] + row['cycled'] = rset1['rows'][0]['is_cycled'] + + result = res['rows'][0] + + result = self._formatter(result, scid, fooid) + sql, name = self.get_SQL(gid, sid, did, result, scid) + # Most probably this is due to error + if not isinstance(sql, str): + return sql + sql = sql.strip('\n').strip(' ') + + # Return sql for schema diff + if not json_resp: + return sql + + sql_header = u"""-- SEQUENCE: {0}.{1}\n\n""".format( + result['schema'], result['name']) + + sql_header += """-- DROP SEQUENCE {0}; + +""".format(self.qtIdent(self.conn, result['schema'], result['name'])) + + sql = sql_header + sql + + return ajax_response(response=sql) + + def _formatter(self, data, scid, fooid): + """ + Args: + data: dict of query result + scid: Schema ID + fooid: Sequence ID + + Returns: + It will return formatted output of sequence + """ + + # Need to format security labels according to client js collection + if 'securities' in data and data['securities'] is not None: + seclabels = [] + for seclbls in data['securities']: + k, v = seclbls.split('=') + seclabels.append({'provider': k, 'label': v}) + + data['securities'] = seclabels + + # We need to parse & convert ACL coming from database to json format + sql = render_template("/".join([self.template_path, self._ACL_SQL]), + scid=scid, fooid=fooid) + status, acl = self.conn.execute_dict(sql) + if not status: + return internal_server_error(errormsg=acl) + + # We will set get privileges from acl sql so we don't need + # it from properties sql + data['relacl'] = [] + + for row in acl['rows']: + priv = parse_priv_from_db(row) + data.setdefault(row['deftype'], []).append(priv) + + return data + + @check_precondition(action="dependents") + def dependents(self, gid, sid, did, scid, fooid): + """ + This function gets the dependents and returns an ajax response + for the sequence node. + + Args: + gid: Server Group ID + sid: Server ID + did: Database ID + scid: Schema ID + fooid: Sequence ID + """ + dependents_result = self.get_dependents(self.conn, fooid) + return ajax_response( + response=dependents_result, + status=200 + ) + + @check_precondition(action="dependencies") + def dependencies(self, gid, sid, did, scid, fooid): + """ + This function gets the dependencies and returns an ajax response + for the sequence node. + + Args: + gid: Server Group ID + sid: Server ID + did: Database ID + scid: Schema ID + fooid: Sequence ID + """ + + return ajax_response( + response=self._get_dependency(fooid), + status=200 + ) + + def _get_dependency(self, fooid, show_system_objects=None): + dependencies_result = self.get_dependencies(self.conn, fooid, None, + show_system_objects) + + # Get missing dependencies. + # A Corner case, reported by Guillaume Lelarge, could be found at: + # http://archives.postgresql.org/pgadmin-hackers/2009-03/msg00026.php + + sql = render_template("/".join([self.template_path, + 'get_dependencies.sql']), fooid=fooid) + + status, result = self.conn.execute_dict(sql) + if not status: + return internal_server_error(errormsg=result) + + for row in result['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' + + dependencies_result.append({'type': 'column', + 'name': ref_name, + 'field': dep_type}) + return dependencies_result + + @check_precondition(action="stats") + def statistics(self, gid, sid, did, scid, fooid=None): + """ + Statistics + + Args: + gid: Server Group Id + sid: Server Id + did: Database Id + scid: Schema Id + fooid: Sequence Id + + Returns the statistics for a particular object if fooid is specified + """ + if fooid is not None: + sql = 'stats.sql' + schema_name = None + else: + sql = 'coll_stats.sql' + # Get schema name + status, schema_name = self.conn.execute_scalar( + render_template( + 'schemas/pg/#{0}#/sql/get_name.sql'.format( + self.manager.version + ), + scid=scid + ) + ) + if not status: + return internal_server_error(errormsg=schema_name) + + status, res = self.conn.execute_dict( + render_template( + "/".join([self.template_path, sql]), + conn=self.conn, fooid=fooid, + schema_name=schema_name + ) + ) + + if not status: + return internal_server_error(errormsg=res) + + return make_json_response( + data=res, + status=200 + ) + + @check_precondition(action="fetch_objects_to_compare") + def fetch_objects_to_compare(self, sid, did, scid): + """ + This function will fetch the list of all the sequences for + specified schema id. + + :param sid: Server Id + :param did: Database Id + :param scid: Schema Id + :return: + """ + res = dict() + sql = render_template("/".join([self.template_path, + self._NODES_SQL]), scid=scid) + status, rset = self.conn.execute_2darray(sql) + if not status: + return internal_server_error(errormsg=res) + + for row in rset['rows']: + status, data = self._fetch_properties(scid, row['oid']) + if status: + res[row['name']] = data + + return res + + def get_sql_from_diff(self, **kwargs): + """ + This function is used to get the DDL/DML statements. + :param kwargs + :return: + """ + gid = kwargs.get('gid') + sid = kwargs.get('sid') + did = kwargs.get('did') + scid = kwargs.get('scid') + oid = kwargs.get('oid') + data = kwargs.get('data', None) + drop_sql = kwargs.get('drop_sql', False) + + if data: + sql, name = self.get_SQL(gid, sid, did, data, scid, oid) + else: + if drop_sql: + sql = self.delete(gid=gid, sid=sid, did=did, + scid=scid, fooid=oid, only_sql=True) + else: + sql = self.sql(gid=gid, sid=sid, did=did, scid=scid, fooid=oid, + json_resp=False) + return sql + + +SchemaDiffRegistry(blueprint.node_type, FooView) +FooView.register_node_view(blueprint) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/static/img/coll-foo.svg b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/static/img/coll-foo.svg new file mode 100644 index 000000000..9be12471d --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/static/img/coll-foo.svg @@ -0,0 +1 @@ +coll-sequence13.. \ No newline at end of file diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/static/img/foo.svg b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/static/img/foo.svg new file mode 100644 index 000000000..5072a1ca8 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/static/img/foo.svg @@ -0,0 +1 @@ +sequence13.. \ No newline at end of file diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/static/js/foo.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/static/js/foo.js new file mode 100644 index 000000000..162a34433 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/static/js/foo.js @@ -0,0 +1,299 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2020, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +define('pgadmin.node.foo', [ + 'sources/gettext', 'sources/url_for', 'jquery', 'underscore', + 'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform', + 'pgadmin.node.schema.dir/child', 'pgadmin.node.schema.dir/schema_child_tree_node', + 'pgadmin.browser.collection', +], function( + gettext, url_for, $, _, pgAdmin, pgBrowser, Backform, schemaChild, + schemaChildTreeNode +) { + + // Extend the browser's collection class for foo collection + if (!pgBrowser.Nodes['coll-foo']) { + pgBrowser.Nodes['coll-foo'] = + pgBrowser.Collection.extend({ + node: 'foo', + label: gettext('Foos'), + type: 'coll-foo', + columns: ['name', 'seqowner', 'comment'], + hasStatistics: true, + canDrop: schemaChildTreeNode.isTreeItemOfChildOfSchema, + canDropCascade: schemaChildTreeNode.isTreeItemOfChildOfSchema, + }); + } + + // Extend the browser's node class for foo node + if (!pgBrowser.Nodes['foo']) { + pgBrowser.Nodes['foo'] = schemaChild.SchemaChildNode.extend({ + type: 'foo', + sqlAlterHelp: 'sql-alterfoo.html', + sqlCreateHelp: 'sql-createfoo.html', + dialogHelp: url_for('help.static', {'filename': 'foo_dialog.html'}), + label: gettext('Foo'), + collection_type: 'coll-foo', + hasSQL: true, + hasDepends: true, + hasStatistics: true, + Init: function() { + /* Avoid mulitple registration of menus */ + if (this.initialized) + return; + + this.initialized = true; + + pgBrowser.add_menus([{ + name: 'create_foo_on_coll', node: 'coll-foo', module: this, + applies: ['object', 'context'], callback: 'show_obj_properties', + category: 'create', priority: 4, label: gettext('Foo...'), + icon: 'wcTabIcon icon-foo', data: {action: 'create', check: true}, + enable: 'canCreate', + },{ + name: 'create_foo', node: 'foo', module: this, + applies: ['object', 'context'], callback: 'show_obj_properties', + category: 'create', priority: 4, label: gettext('Foo...'), + icon: 'wcTabIcon icon-foo', data: {action: 'create', check: true}, + enable: 'canCreate', + },{ + name: 'create_foo', node: 'schema', module: this, + applies: ['object', 'context'], callback: 'show_obj_properties', + category: 'create', priority: 4, label: gettext('Foo...'), + icon: 'wcTabIcon icon-foo', data: {action: 'create', check: false}, + enable: 'canCreate', + }, + ]); + + }, + // Define the model for foo node. + model: pgBrowser.Node.Model.extend({ + idAttribute: 'oid', + defaults: { + name: undefined, + oid: undefined, + seqowner: undefined, + schema: undefined, + is_sys_obj: undefined, + comment: undefined, + increment: undefined, + start: undefined, + current_value: undefined, + minimum: undefined, + maximum: undefined, + cache: undefined, + cycled: undefined, + relacl: [], + securities: [], + }, + + // Default values! + initialize: function(attrs, args) { + var isNew = (_.size(attrs) === 0); + + if (isNew) { + var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user; + var schemaInfo = args.node_info.schema; + + this.set({'seqowner': userInfo.name}, {silent: true}); + this.set({'schema': schemaInfo._label}, {silent: true}); + } + pgBrowser.Node.Model.prototype.initialize.apply(this, arguments); + }, + + // Define the schema for foo node. + schema: [{ + id: 'name', label: gettext('Name'), cell: 'string', + type: 'text', mode: ['properties', 'create', 'edit'], + },{ + id: 'oid', label: gettext('OID'), cell: 'string', + type: 'text', mode: ['properties'], + },{ + id: 'seqowner', label: gettext('Owner'), cell: 'string', + type: 'text', mode: ['properties', 'create', 'edit'], node: 'role', + control: Backform.NodeListByNameControl, + },{ + id: 'schema', label: gettext('Schema'), cell: 'string', + control: 'node-list-by-name', node: 'schema', + type: 'text', mode: ['create', 'edit'], filter: function(d) { + // If schema name start with pg_* then we need to exclude them + if(d && d.label.match(/^pg_/)) + { + return false; + } + return true; + }, cache_node: 'database', cache_level: 'database', + },{ + id: 'is_sys_obj', label: gettext('System sequence?'), + cell:'boolean', type: 'switch', mode: ['properties'], + },{ + id: 'comment', label: gettext('Comment'), type: 'multiline', + mode: ['properties', 'create', 'edit'], + },{ + id: 'current_value', label: gettext('Current value'), type: 'int', + mode: ['properties', 'edit'], group: gettext('Definition'), + },{ + id: 'increment', label: gettext('Increment'), type: 'int', + mode: ['properties', 'create', 'edit'], group: gettext('Definition'), + },{ + id: 'start', label: gettext('Start'), type: 'int', + mode: ['properties', 'create'], group: gettext('Definition'), + readonly: function(m) { + return !m.isNew(); + }, + },{ + id: 'minimum', label: gettext('Minimum'), type: 'int', + mode: ['properties', 'create', 'edit'], group: gettext('Definition'), + },{ + id: 'maximum', label: gettext('Maximum'), type: 'int', + mode: ['properties', 'create', 'edit'], group: gettext('Definition'), + },{ + id: 'cache', label: gettext('Cache'), type: 'int', + mode: ['properties', 'create', 'edit'], group: gettext('Definition'), + min: 1, + },{ + id: 'cycled', label: gettext('Cycled'), type: 'switch', + mode: ['properties', 'create', 'edit'], group: gettext('Definition'), + }, pgBrowser.SecurityGroupSchema,{ + id: 'acl', label: gettext('Privileges'), type: 'text', + group: gettext('Security'), mode: ['properties'], + },{ + id: 'relacl', label: gettext('Privileges'), group: 'security', + model: pgBrowser.Node.PrivilegeRoleModel.extend({ + privileges: ['r', 'w', 'U'], + }), uniqueCol : ['grantee', 'grantor'], mode: ['edit', 'create'], + editable: false, type: 'collection', canAdd: true, canDelete: true, + control: 'unique-col-collection', + },{ + id: 'securities', label: gettext('Security labels'), canAdd: true, + model: pgBrowser.SecLabelModel, editable: false, + type: 'collection', canEdit: false, group: 'security', + mode: ['edit', 'create'], canDelete: true, + control: 'unique-col-collection', + min_version: 90200, uniqueCol : ['provider'], + }], + /* validate function is used to validate the input given by + * the user. In case of error, message will be displayed on + * the GUI for the respective control. + */ + validate: function() { + var msg = undefined, + minimum = this.get('minimum'), + maximum = this.get('maximum'), + start = this.get('start'); + + if (_.isUndefined(this.get('name')) + || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') { + msg = gettext('Name cannot be empty.'); + this.errorModel.set('name', msg); + return msg; + } else { + this.errorModel.unset('name'); + } + + if (_.isUndefined(this.get('seqowner')) + || String(this.get('seqowner')).replace(/^\s+|\s+$/g, '') == '') { + msg = gettext('Owner cannot be empty.'); + this.errorModel.set('seqowner', msg); + return msg; + } else { + this.errorModel.unset('seqowner'); + } + + if (_.isUndefined(this.get('schema')) + || String(this.get('schema')).replace(/^\s+|\s+$/g, '') == '') { + msg = gettext('Schema cannot be empty.'); + this.errorModel.set('schema', msg); + return msg; + } else { + this.errorModel.unset('schema'); + } + + if (!this.isNew()) { + if (_.isUndefined(this.get('current_value')) + || String(this.get('current_value')).replace(/^\s+|\s+$/g, '') == '') { + msg = gettext('Current value cannot be empty.'); + this.errorModel.set('current_value', msg); + return msg; + } else { + this.errorModel.unset('current_value'); + } + + if (_.isUndefined(this.get('increment')) + || String(this.get('increment')).replace(/^\s+|\s+$/g, '') == '') { + msg = gettext('Increment value cannot be empty.'); + this.errorModel.set('increment', msg); + return msg; + } else { + this.errorModel.unset('increment'); + } + + if (_.isUndefined(this.get('minimum')) + || String(this.get('minimum')).replace(/^\s+|\s+$/g, '') == '') { + msg = gettext('Minimum value cannot be empty.'); + this.errorModel.set('minimum', msg); + return msg; + } else { + this.errorModel.unset('minimum'); + } + + if (_.isUndefined(this.get('maximum')) + || String(this.get('maximum')).replace(/^\s+|\s+$/g, '') == '') { + msg = gettext('Maximum value cannot be empty.'); + this.errorModel.set('maximum', msg); + return msg; + } else { + this.errorModel.unset('maximum'); + } + + if (_.isUndefined(this.get('cache')) + || String(this.get('cache')).replace(/^\s+|\s+$/g, '') == '') { + msg = gettext('Cache value cannot be empty.'); + this.errorModel.set('cache', msg); + return msg; + } else { + this.errorModel.unset('cache'); + } + } + var min_lt = gettext('Minimum value must be less than maximum value.'), + start_lt = gettext('Start value cannot be less than minimum value.'), + start_gt = gettext('Start value cannot be greater than maximum value.'); + + if (_.isEmpty(minimum) || _.isEmpty(maximum)) + return null; + + if ((minimum == 0 && maximum == 0) || + (parseInt(minimum, 10) >= parseInt(maximum, 10))) { + this.errorModel.set('minimum', min_lt); + return min_lt; + } else { + this.errorModel.unset('minimum'); + } + + if (start && minimum && parseInt(start) < parseInt(minimum)) { + this.errorModel.set('start', start_lt); + return start_lt; + } else { + this.errorModel.unset('start'); + } + + if (start && maximum && parseInt(start) > parseInt(maximum)) { + this.errorModel.set('start', start_gt); + return start_gt; + } else { + this.errorModel.unset('start'); + } + return null; + }, + }), + }); + } + + return pgBrowser.Nodes['foo']; +}); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/10_plus/get_def.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/10_plus/get_def.sql new file mode 100644 index 000000000..91ca135d1 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/10_plus/get_def.sql @@ -0,0 +1,11 @@ +SELECT + last_value, + seqmin AS min_value, + seqmax AS max_value, + seqstart AS start_value, + seqcache AS cache_value, + seqcycle AS is_cycled, + seqincrement AS increment_by, + is_called +FROM pg_sequence, {{ conn|qtIdent(data.schema) }}.{{ conn|qtIdent(data.name) }} +WHERE seqrelid = {{data.oid}} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/acl.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/acl.sql new file mode 100644 index 000000000..e94f93b0e --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/acl.sql @@ -0,0 +1,30 @@ +SELECT 'relacl' as deftype, COALESCE(gt.rolname, 'PUBLIC') 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, + CASE d.privilege_type + WHEN 'CONNECT' THEN 'c' + WHEN 'CREATE' THEN 'C' + WHEN 'DELETE' THEN 'd' + WHEN 'EXECUTE' THEN 'X' + WHEN 'INSERT' THEN 'a' + WHEN 'REFERENCES' THEN 'x' + WHEN 'SELECT' THEN 'r' + WHEN 'TEMPORARY' THEN 'T' + WHEN 'TRIGGER' THEN 't' + WHEN 'TRUNCATE' THEN 'D' + WHEN 'UPDATE' THEN 'w' + WHEN 'USAGE' THEN 'U' + ELSE 'UNKNOWN' + END AS privilege_type + FROM + aclexplode((SELECT relacl + 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 = {{scid}}::oid + AND cl.oid = {{fooid}}::oid )) 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 +ORDER BY grantee diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/backend_support.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/backend_support.sql new file mode 100644 index 000000000..1c8a83213 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/backend_support.sql @@ -0,0 +1,15 @@ +SELECT + CASE WHEN nsp.nspname IN ('sys', 'dbo', 'information_schema') THEN true ELSE false END AS dbSupport +FROM pg_namespace nsp +WHERE nsp.oid={{scid}}::oid AND ( + (nspname = 'pg_catalog' AND EXISTS + (SELECT 1 FROM pg_class WHERE relname = 'pg_class' AND relnamespace = nsp.oid LIMIT 1)) + OR (nspname = 'pgagent' AND EXISTS + (SELECT 1 FROM pg_class WHERE relname = 'pga_job' AND relnamespace = nsp.oid LIMIT 1)) + OR (nspname = 'information_schema' AND EXISTS + (SELECT 1 FROM pg_class WHERE relname = 'tables' AND relnamespace = nsp.oid LIMIT 1)) + OR (nspname LIKE '_%' AND EXISTS + (SELECT 1 FROM pg_proc WHERE proname='slonyversion' AND pronamespace = nsp.oid LIMIT 1)) + ) AND + nspname NOT LIKE E'pg\\temp\\%' AND + nspname NOT LIKE E'pg\\toast_temp\\%' \ No newline at end of file diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/coll_stats.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/coll_stats.sql new file mode 100644 index 000000000..71d3c7059 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/coll_stats.sql @@ -0,0 +1,9 @@ +SELECT + relname AS {{ conn|qtIdent(_('Name')) }}, + blks_read AS {{ conn|qtIdent(_('Blocks read')) }}, + blks_hit AS {{ conn|qtIdent(_('Blocks hit')) }} +FROM + pg_statio_all_sequences +WHERE + schemaname = {{ schema_name|qtLiteral }} +ORDER BY relname; \ No newline at end of file diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/create.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/create.sql new file mode 100644 index 000000000..4a28806a4 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/create.sql @@ -0,0 +1,16 @@ +CREATE SEQUENCE {{ conn|qtIdent(data.schema, data.name) }}{% if data.increment is defined and data.cycled %} + + CYCLE{% endif %}{% if data.increment is defined %} + + INCREMENT {{data.increment|int}}{% endif %}{% if data.start is defined %} + + START {{data.start|int}}{% elif data.current_value is defined %} + + START {{data.current_value|int}}{% endif %}{% if data.minimum is defined %} + + MINVALUE {{data.minimum|int}}{% endif %}{% if data.maximum is defined %} + + MAXVALUE {{data.maximum|int}}{% endif %}{% if data.cache is defined and data.cache|int(-1) > -1%} + + CACHE {{data.cache|int}}{% endif %}; + diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/delete.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/delete.sql new file mode 100644 index 000000000..efd218edf --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/delete.sql @@ -0,0 +1 @@ +DROP SEQUENCE {{ conn|qtIdent(data.schema) }}.{{ conn|qtIdent(data.name) }}{% if cascade%} CASCADE{% endif %}; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/get_def.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/get_def.sql new file mode 100644 index 000000000..e0e9efba1 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/get_def.sql @@ -0,0 +1,10 @@ +SELECT + last_value, + min_value, + max_value, + start_value, + cache_value, + is_cycled, + increment_by, + is_called +FROM {{ conn|qtIdent(data.schema) }}.{{ conn|qtIdent(data.name) }} \ No newline at end of file diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/get_dependencies.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/get_dependencies.sql new file mode 100644 index 000000000..325ee79ea --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/get_dependencies.sql @@ -0,0 +1,12 @@ +SELECT + CASE WHEN att.attname IS NOT NULL AND ref.relname IS NOT NULL THEN ref.relname || '.' || att.attname + ELSE ref.relname + END AS refname, + d2.refclassid, d1.deptype AS deptype +FROM pg_depend d1 + LEFT JOIN pg_depend d2 ON d1.objid=d2.objid AND d1.refobjid != d2.refobjid + LEFT JOIN pg_class ref ON ref.oid = d2.refobjid + LEFT JOIN pg_attribute att ON d2.refobjid=att.attrelid AND d2.refobjsubid=att.attnum +WHERE d1.classid=(SELECT oid FROM pg_class WHERE relname='pg_attrdef') + AND d2.refobjid NOT IN (SELECT d3.refobjid FROM pg_depend d3 WHERE d3.objid=d1.refobjid) + AND d1.refobjid={{fooid}}::oid diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/get_oid.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/get_oid.sql new file mode 100644 index 000000000..340a66416 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/get_oid.sql @@ -0,0 +1,7 @@ +SELECT cl.oid as oid, relnamespace +FROM pg_class cl +LEFT OUTER JOIN pg_description des ON (des.objoid=cl.oid AND des.classoid='pg_class'::regclass) +LEFT OUTER JOIN pg_namespace nsp ON (nsp.oid = cl.relnamespace) +WHERE relkind = 'S' +AND relname = {{ name|qtLiteral }} +AND nspname = {{ schema|qtLiteral }} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/grant.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/grant.sql new file mode 100644 index 000000000..d4a382c66 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/grant.sql @@ -0,0 +1,26 @@ +{% import 'macros/schemas/security.macros' as SECLABEL %} +{% import 'macros/schemas/privilege.macros' as PRIVILEGE %} +{# Construct sequence name from name and schema #} +{% set seqname=conn|qtIdent(data.schema, data.name) %} +{% if data.seqowner %} + +ALTER SEQUENCE {{ seqname }} + OWNER TO {{ conn|qtIdent(data.seqowner) }}; +{% endif %} +{% if data.comment %} + +COMMENT ON SEQUENCE {{ seqname }} + IS {{ data.comment|qtLiteral }}; +{% endif %} +{% if data.securities %} + +{% for r in data.securities %} +{{ SECLABEL.SET(conn, 'SEQUENCE', data.name, r.provider, r.label, data.schema) }} +{% endfor %} +{% endif %} +{% if data.relacl %} + +{% for priv in data.relacl %} +{{ PRIVILEGE.SET(conn, 'SEQUENCE', priv.grantee, data.name, priv.without_grant, priv.with_grant, data.schema) }} +{% endfor %} +{% endif %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/nodes.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/nodes.sql new file mode 100644 index 000000000..f418ca133 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/nodes.sql @@ -0,0 +1,11 @@ +SELECT cl.oid as oid, relname as name, relnamespace as schema +FROM pg_class cl +WHERE + relkind = 'S' +{% if scid %} + AND relnamespace = {{scid|qtLiteral}}::oid +{% endif %} +{% if fooid %} + AND cl.oid = {{fooid|qtLiteral}}::oid +{% endif %} +ORDER BY relname diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/properties.sql new file mode 100644 index 000000000..ff186b71c --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/properties.sql @@ -0,0 +1,17 @@ +{% if scid %} +SELECT + cl.oid as oid, + relname as name, + nsp.nspname as schema, + pg_get_userbyid(relowner) AS seqowner, + description as comment, + array_to_string(relacl::text[], ', ') as acl, + (SELECT array_agg(provider || '=' || label) FROM pg_seclabels sl1 WHERE sl1.objoid=cl.oid) AS securities +FROM pg_class cl + LEFT OUTER JOIN pg_namespace nsp ON cl.relnamespace = nsp.oid + LEFT OUTER JOIN pg_description des ON (des.objoid=cl.oid + AND des.classoid='pg_class'::regclass) +WHERE relkind = 'S' AND relnamespace = {{scid}}::oid +{% if fooid %}AND cl.oid = {{fooid}}::oid {% endif %} +ORDER BY relname +{% endif %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/stats.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/stats.sql new file mode 100644 index 000000000..cd9b0154a --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/stats.sql @@ -0,0 +1,7 @@ +SELECT + blks_read AS {{ conn|qtIdent(_('Blocks read')) }}, + blks_hit AS {{ conn|qtIdent(_('Blocks hit')) }} +FROM + pg_statio_all_sequences +WHERE + relid = {{ seid }}::OID \ No newline at end of file diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/update.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/update.sql new file mode 100644 index 000000000..2d42249b5 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/update.sql @@ -0,0 +1,97 @@ +{% import 'macros/schemas/security.macros' as SECLABEL %} +{% import 'macros/schemas/privilege.macros' as PRIVILEGE %} +{% if data %} +{% if data.name != o_data.name %} +ALTER SEQUENCE {{ conn|qtIdent(o_data.schema, o_data.name) }} + RENAME TO {{ conn|qtIdent(data.name) }}; + +{% endif %} +{% if data.seqowner and data.seqowner != o_data.seqowner %} +ALTER SEQUENCE {{ conn|qtIdent(o_data.schema, data.name) }} + OWNER TO {{ conn|qtIdent(data.seqowner) }}; + +{% endif %} +{% if data.current_value is defined %} +{% set seqname = conn|qtIdent(o_data.schema, data.name) %} +SELECT setval({{ seqname|qtLiteral }}, {{ data.current_value }}, true); + +{% endif %} +{% set defquery = '' %} +{% if data.increment is defined %} +{% set defquery = defquery+'\n INCREMENT '+data.increment|string %} +{% endif %} +{% if data.start is defined %} +{% set defquery = defquery+'\n START '+data.start|string %} +{% endif %} +{% if data.minimum is defined %} +{% set defquery = defquery+'\n MINVALUE '+data.minimum|string %} +{% endif %} +{% if data.maximum is defined %} +{% set defquery = defquery+'\n MAXVALUE '+data.maximum|string %} +{% endif %} +{% if data.cache is defined %} +{% set defquery = defquery+'\n CACHE '+data.cache|string %} +{% endif %} +{% if data.cycled == True %} +{% set defquery = defquery+'\n CYCLE' %} +{% elif data.cycled == False %} +{% set defquery = defquery+'\n NO CYCLE' %} +{% endif %} +{% if defquery and defquery != '' %} +ALTER SEQUENCE {{ conn|qtIdent(o_data.schema, data.name) }}{{ defquery }}; + +{% endif %} +{% if data.schema and data.schema != o_data.schema %} +ALTER SEQUENCE {{ conn|qtIdent(o_data.schema, data.name) }} + SET SCHEMA {{ conn|qtIdent(data.schema) }}; + +{% set seqname = conn|qtIdent(data.schema, data.name) %} +{% set schema = data.schema %} +{% else %} +{% set seqname = conn|qtIdent(o_data.schema, data.name) %} +{% set schema = o_data.schema %} +{% endif %} +{% if data.comment is defined and data.comment != o_data.comment %} +COMMENT ON SEQUENCE {{ seqname }} + IS {{ data.comment|qtLiteral }}; + +{% endif %} +{% if data.securities and data.securities|length > 0 %} + +{% set seclabels = data.securities %} +{% if 'deleted' in seclabels and seclabels.deleted|length > 0 %} +{% for r in seclabels.deleted %} +{{ SECLABEL.UNSET(conn, 'SEQUENCE', data.name, r.provider, schema) }} +{% endfor %} +{% endif %} +{% if 'added' in seclabels and seclabels.added|length > 0 %} +{% for r in seclabels.added %} +{{ SECLABEL.SET(conn, 'SEQUENCE', data.name, r.provider, r.label, schema) }} +{% endfor %} +{% endif %} +{% if 'changed' in seclabels and seclabels.changed|length > 0 %} +{% for r in seclabels.changed %} +{{ SECLABEL.SET(conn, 'SEQUENCE', data.name, r.provider, r.label, schema) }} +{% endfor %} +{% endif %} +{% endif %} +{% if data.relacl %} + +{% if 'deleted' in data.relacl %} +{% for priv in data.relacl.deleted %} +{{ PRIVILEGE.UNSETALL(conn, 'SEQUENCE', priv.grantee, data.name, schema) }} +{% endfor %} +{% endif %} +{% if 'changed' in data.relacl %} +{% for priv in data.relacl.changed %} +{{ PRIVILEGE.UNSETALL(conn, 'SEQUENCE', priv.grantee, data.name, schema) }} +{{ PRIVILEGE.SET(conn, 'SEQUENCE', priv.grantee, data.name, priv.without_grant, priv.with_grant, schema) }} +{% endfor %} +{% endif %} +{% if 'added' in data.relacl %} +{% for priv in data.relacl.added %} +{{ PRIVILEGE.SET(conn, 'SEQUENCE', priv.grantee, data.name, priv.without_grant, priv.with_grant, schema) }} +{% endfor %} +{% endif %} +{% endif %} +{% endif %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/gpdb_5.0_plus/acl.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/gpdb_5.0_plus/acl.sql new file mode 100644 index 000000000..167184011 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/gpdb_5.0_plus/acl.sql @@ -0,0 +1,7 @@ +SELECT + 'relacl' AS deftype, + 'PUBLIC' AS grantee, + NULL AS grantor, + NULL AS privileges, + NULL AS grantable +LIMIT 0; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/__init__.py new file mode 100644 index 000000000..512b71da3 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/__init__.py @@ -0,0 +1,15 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2020, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +from pgadmin.utils.route import BaseTestGenerator + + +class SequenceTestGenerator(BaseTestGenerator): + def runTest(self): + return [] diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_neg_seq_props.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_neg_seq_props.sql new file mode 100644 index 000000000..ce1a63de0 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_neg_seq_props.sql @@ -0,0 +1,13 @@ +-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/# + +-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"; + +CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + INCREMENT -7 + START -30 + MINVALUE -35 + MAXVALUE -15 + CACHE 1; + +ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + OWNER TO postgres; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_neg_seq_props_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_neg_seq_props_msql.sql new file mode 100644 index 000000000..f56eab153 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_neg_seq_props_msql.sql @@ -0,0 +1,4 @@ +ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + INCREMENT -7 + MINVALUE -35 + MAXVALUE -15; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_comment.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_comment.sql new file mode 100644 index 000000000..b98eb4871 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_comment.sql @@ -0,0 +1,16 @@ +-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/# + +-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"; + +CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + INCREMENT 5 + START 5 + MINVALUE 5 + MAXVALUE 999 + CACHE 1; + +ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + OWNER TO postgres; + +COMMENT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + IS 'Some comment'; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_comment_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_comment_msql.sql new file mode 100644 index 000000000..7a5efbd92 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_comment_msql.sql @@ -0,0 +1,2 @@ +COMMENT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + IS 'Some comment'; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_add.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_add.sql new file mode 100644 index 000000000..16abe7497 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_add.sql @@ -0,0 +1,21 @@ +-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/# + +-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"; + +CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + CYCLE + INCREMENT 12 + START 5 + MINVALUE 2 + MAXVALUE 9992 + CACHE 2; + +ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + OWNER TO postgres; + +COMMENT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + IS 'Some comment'; + +GRANT ALL ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" TO PUBLIC; + +GRANT ALL ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" TO postgres; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_add_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_add_msql.sql new file mode 100644 index 000000000..66d9aa002 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_add_msql.sql @@ -0,0 +1 @@ +GRANT ALL ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" TO PUBLIC; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_remove.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_remove.sql new file mode 100644 index 000000000..b392b3e31 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_remove.sql @@ -0,0 +1,19 @@ +-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/# + +-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"; + +CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + CYCLE + INCREMENT 12 + START 5 + MINVALUE 2 + MAXVALUE 9992 + CACHE 2; + +ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + OWNER TO postgres; + +COMMENT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + IS 'Some comment'; + +GRANT ALL ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" TO postgres; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_remove_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_remove_msql.sql new file mode 100644 index 000000000..e8b94bad8 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_remove_msql.sql @@ -0,0 +1 @@ +REVOKE ALL ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" FROM PUBLIC; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_update.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_update.sql new file mode 100644 index 000000000..9b379e9ab --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_update.sql @@ -0,0 +1,21 @@ +-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/# + +-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"; + +CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + CYCLE + INCREMENT 12 + START 5 + MINVALUE 2 + MAXVALUE 9992 + CACHE 2; + +ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + OWNER TO postgres; + +COMMENT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + IS 'Some comment'; + +GRANT SELECT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" TO PUBLIC; + +GRANT ALL ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" TO postgres; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_update_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_update_msql.sql new file mode 100644 index 000000000..c3c2a5b9a --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_update_msql.sql @@ -0,0 +1,2 @@ +REVOKE ALL ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" FROM PUBLIC; +GRANT SELECT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" TO PUBLIC; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_props.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_props.sql new file mode 100644 index 000000000..78122be35 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_props.sql @@ -0,0 +1,17 @@ +-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/# + +-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"; + +CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + CYCLE + INCREMENT 12 + START 5 + MINVALUE 2 + MAXVALUE 9992 + CACHE 2; + +ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + OWNER TO postgres; + +COMMENT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + IS 'Some comment'; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_props_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_props_msql.sql new file mode 100644 index 000000000..3ed0c8c1d --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_props_msql.sql @@ -0,0 +1,8 @@ +SELECT setval('public."Seq1_$%{}[]()&*^!@""''`\/#"', 7, true); + +ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + INCREMENT 12 + MINVALUE 2 + MAXVALUE 9992 + CACHE 2 + CYCLE; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_negative_sequence.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_negative_sequence.sql new file mode 100644 index 000000000..7cd0881d7 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_negative_sequence.sql @@ -0,0 +1,13 @@ +-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/# + +-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"; + +CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + INCREMENT -5 + START -30 + MINVALUE -40 + MAXVALUE -10 + CACHE 1; + +ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + OWNER TO postgres; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_negative_sequence_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_negative_sequence_msql.sql new file mode 100644 index 000000000..f62613c8f --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_negative_sequence_msql.sql @@ -0,0 +1,9 @@ +CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + INCREMENT -5 + START -30 + MINVALUE -40 + MAXVALUE -10 + CACHE 1; + +ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + OWNER TO postgres; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_sequence.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_sequence.sql new file mode 100644 index 000000000..b159ab9d3 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_sequence.sql @@ -0,0 +1,13 @@ +-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/# + +-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"; + +CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + INCREMENT 5 + START 5 + MINVALUE 5 + MAXVALUE 999 + CACHE 1; + +ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + OWNER TO postgres; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_sequence_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_sequence_msql.sql new file mode 100644 index 000000000..67e09cd68 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_sequence_msql.sql @@ -0,0 +1,9 @@ +CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + INCREMENT 5 + START 5 + MINVALUE 5 + MAXVALUE 999 + CACHE 1; + +ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + OWNER TO postgres; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/test_sequences_pg.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/test_sequences_pg.json new file mode 100644 index 000000000..9687cf838 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/test_sequences_pg.json @@ -0,0 +1,173 @@ +{ + "scenarios": [ + { + "type": "create", + "name": "Create Sequence", + "endpoint": "NODE-sequence.obj", + "sql_endpoint": "NODE-sequence.sql_id", + "msql_endpoint": "NODE-sequence.msql", + "data": { + "name": "Seq1_$%{}[]()&*^!@\"'`\\/#", + "seqowner": "postgres", + "schema": "public", + "increment": "5", + "start": "5", + "maximum": "999", + "minimum": "5", + "cache": "1", + "cycled": false, + "relacl": [], + "securities": [] + }, + "expected_sql_file": "create_sequence.sql", + "expected_msql_file": "create_sequence_msql.sql" + },{ + "type": "alter", + "name": "Alter Sequence comment", + "endpoint": "NODE-sequence.obj_id", + "sql_endpoint": "NODE-sequence.sql_id", + "msql_endpoint": "NODE-sequence.msql_id", + "data": { + "comment": "Some comment" + }, + "expected_sql_file": "alter_seq_comment.sql", + "expected_msql_file": "alter_seq_comment_msql.sql" + },{ + "type": "alter", + "name": "Alter Sequence properties", + "endpoint": "NODE-sequence.obj_id", + "sql_endpoint": "NODE-sequence.sql_id", + "msql_endpoint": "NODE-sequence.msql_id", + "data": { + "current_value": "7", "increment": "12", "minimum": "2", "maximum": "9992", "cache": "2", "cycled": true + }, + "expected_sql_file": "alter_seq_props.sql", + "expected_msql_file": "alter_seq_props_msql.sql" + },{ + "type": "alter", + "name": "Alter Sequence add privileges", + "endpoint": "NODE-sequence.obj_id", + "sql_endpoint": "NODE-sequence.sql_id", + "msql_endpoint": "NODE-sequence.msql_id", + "data": { + "relacl": { + "added":[{ + "grantee": "PUBLIC", + "grantor": "postgres", + "privileges":[{ + "privilege_type": "r", + "privilege": true, + "with_grant": false + },{ + "privilege_type": "U", + "privilege": true, + "with_grant": false + },{ + "privilege_type": "w", + "privilege": true, + "with_grant": false + }] + }] + } + }, + "expected_sql_file": "alter_seq_privs_add.sql", + "expected_msql_file": "alter_seq_privs_add_msql.sql" + },{ + "type": "alter", + "name": "Alter Sequence update privileges", + "endpoint": "NODE-sequence.obj_id", + "sql_endpoint": "NODE-sequence.sql_id", + "msql_endpoint": "NODE-sequence.msql_id", + "data": { + "relacl": { + "changed":[{ + "grantee": "PUBLIC", + "grantor": "postgres", + "privileges":[{ + "privilege_type": "r", + "privilege": true, + "with_grant": false + }] + }] + } + }, + "expected_sql_file": "alter_seq_privs_update.sql", + "expected_msql_file": "alter_seq_privs_update_msql.sql" + },{ + "type": "alter", + "name": "Alter Sequence remove privileges", + "endpoint": "NODE-sequence.obj_id", + "sql_endpoint": "NODE-sequence.sql_id", + "msql_endpoint": "NODE-sequence.msql_id", + "data": { + "relacl": { + "deleted":[{ + "grantee": "PUBLIC", + "grantor": "postgres", + "privileges":[{ + "privilege_type": "r", + "privilege": true, + "with_grant": false + },{ + "privilege_type": "U", + "privilege": true, + "with_grant": false + },{ + "privilege_type": "w", + "privilege": true, + "with_grant": false + }] + }] + } + }, + "expected_sql_file": "alter_seq_privs_remove.sql", + "expected_msql_file": "alter_seq_privs_remove_msql.sql" + }, { + "type": "delete", + "name": "Drop sequence", + "endpoint": "NODE-sequence.delete_id", + "data": { + "name": "Seq1_$%{}[]()&*^!@\"'`\\/#" + } + }, { + "type": "create", + "name": "Create Sequence with Negative value", + "endpoint": "NODE-sequence.obj", + "sql_endpoint": "NODE-sequence.sql_id", + "msql_endpoint": "NODE-sequence.msql", + "data": { + "name": "Seq1_$%{}[]()&*^!@\"'`\\/#", + "seqowner": "postgres", + "schema": "public", + "increment": "-5", + "start": "-30", + "maximum": "-10", + "minimum": "-40", + "cache": "1", + "cycled": false, + "relacl": [], + "securities": [] + }, + "expected_sql_file": "create_negative_sequence.sql", + "expected_msql_file": "create_negative_sequence_msql.sql" + }, { + "type": "alter", + "name": "Alter Sequence properties with negative value", + "endpoint": "NODE-sequence.obj_id", + "sql_endpoint": "NODE-sequence.sql_id", + "msql_endpoint": "NODE-sequence.msql_id", + "data": { + "increment": "-7", "minimum": "-35", "maximum": "-15" + }, + "expected_sql_file": "alter_neg_seq_props.sql", + "expected_msql_file": "alter_neg_seq_props_msql.sql" + }, { + "type": "delete", + "name": "Drop negative sequence", + "endpoint": "NODE-sequence.delete_id", + "data": { + "name": "Seq1_$%{}[]()&*^!@\"'`\\/#" + } + } + ] +} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_neg_seq_props.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_neg_seq_props.sql new file mode 100644 index 000000000..01424cf9a --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_neg_seq_props.sql @@ -0,0 +1,13 @@ +-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/# + +-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"; + +CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + INCREMENT -7 + START -30 + MINVALUE -35 + MAXVALUE -15 + CACHE 1; + +ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + OWNER TO enterprisedb; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_neg_seq_props_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_neg_seq_props_msql.sql new file mode 100644 index 000000000..f56eab153 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_neg_seq_props_msql.sql @@ -0,0 +1,4 @@ +ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + INCREMENT -7 + MINVALUE -35 + MAXVALUE -15; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_comment.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_comment.sql new file mode 100644 index 000000000..cc47ed079 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_comment.sql @@ -0,0 +1,16 @@ +-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/# + +-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"; + +CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + INCREMENT 5 + START 5 + MINVALUE 5 + MAXVALUE 999 + CACHE 1; + +ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + OWNER TO enterprisedb; + +COMMENT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + IS 'Some comment'; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_comment_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_comment_msql.sql new file mode 100644 index 000000000..7a5efbd92 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_comment_msql.sql @@ -0,0 +1,2 @@ +COMMENT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + IS 'Some comment'; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_add.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_add.sql new file mode 100644 index 000000000..457f48101 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_add.sql @@ -0,0 +1,21 @@ +-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/# + +-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"; + +CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + CYCLE + INCREMENT 12 + START 5 + MINVALUE 2 + MAXVALUE 9992 + CACHE 2; + +ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + OWNER TO enterprisedb; + +COMMENT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + IS 'Some comment'; + +GRANT ALL ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" TO PUBLIC; + +GRANT ALL ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" TO enterprisedb; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_add_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_add_msql.sql new file mode 100644 index 000000000..66d9aa002 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_add_msql.sql @@ -0,0 +1 @@ +GRANT ALL ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" TO PUBLIC; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_remove.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_remove.sql new file mode 100644 index 000000000..ac21e667f --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_remove.sql @@ -0,0 +1,19 @@ +-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/# + +-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"; + +CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + CYCLE + INCREMENT 12 + START 5 + MINVALUE 2 + MAXVALUE 9992 + CACHE 2; + +ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + OWNER TO enterprisedb; + +COMMENT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + IS 'Some comment'; + +GRANT ALL ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" TO enterprisedb; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_remove_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_remove_msql.sql new file mode 100644 index 000000000..e8b94bad8 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_remove_msql.sql @@ -0,0 +1 @@ +REVOKE ALL ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" FROM PUBLIC; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_update.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_update.sql new file mode 100644 index 000000000..fea961543 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_update.sql @@ -0,0 +1,21 @@ +-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/# + +-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"; + +CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + CYCLE + INCREMENT 12 + START 5 + MINVALUE 2 + MAXVALUE 9992 + CACHE 2; + +ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + OWNER TO enterprisedb; + +COMMENT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + IS 'Some comment'; + +GRANT SELECT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" TO PUBLIC; + +GRANT ALL ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" TO enterprisedb; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_update_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_update_msql.sql new file mode 100644 index 000000000..c3c2a5b9a --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_update_msql.sql @@ -0,0 +1,2 @@ +REVOKE ALL ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" FROM PUBLIC; +GRANT SELECT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" TO PUBLIC; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_props.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_props.sql new file mode 100644 index 000000000..bc59956a6 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_props.sql @@ -0,0 +1,17 @@ +-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/# + +-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"; + +CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + CYCLE + INCREMENT 12 + START 5 + MINVALUE 2 + MAXVALUE 9992 + CACHE 2; + +ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + OWNER TO enterprisedb; + +COMMENT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + IS 'Some comment'; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_props_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_props_msql.sql new file mode 100644 index 000000000..3ed0c8c1d --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_props_msql.sql @@ -0,0 +1,8 @@ +SELECT setval('public."Seq1_$%{}[]()&*^!@""''`\/#"', 7, true); + +ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + INCREMENT 12 + MINVALUE 2 + MAXVALUE 9992 + CACHE 2 + CYCLE; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_negative_sequence.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_negative_sequence.sql new file mode 100644 index 000000000..6ad4989c5 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_negative_sequence.sql @@ -0,0 +1,13 @@ +-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/# + +-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"; + +CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + INCREMENT -5 + START -30 + MINVALUE -40 + MAXVALUE -10 + CACHE 1; + +ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + OWNER TO enterprisedb; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_negative_sequence_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_negative_sequence_msql.sql new file mode 100644 index 000000000..64e75266f --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_negative_sequence_msql.sql @@ -0,0 +1,9 @@ +CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + INCREMENT -5 + START -30 + MINVALUE -40 + MAXVALUE -10 + CACHE 1; + +ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + OWNER TO enterprisedb; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_sequence.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_sequence.sql new file mode 100644 index 000000000..611226a14 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_sequence.sql @@ -0,0 +1,13 @@ +-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/# + +-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"; + +CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + INCREMENT 5 + START 5 + MINVALUE 5 + MAXVALUE 999 + CACHE 1; + +ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + OWNER TO enterprisedb; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_sequence_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_sequence_msql.sql new file mode 100644 index 000000000..f926dbec2 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_sequence_msql.sql @@ -0,0 +1,9 @@ +CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + INCREMENT 5 + START 5 + MINVALUE 5 + MAXVALUE 999 + CACHE 1; + +ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" + OWNER TO enterprisedb; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/test_sequences_ppas.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/test_sequences_ppas.json new file mode 100644 index 000000000..1639aac04 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/test_sequences_ppas.json @@ -0,0 +1,173 @@ +{ + "scenarios": [ + { + "type": "create", + "name": "Create Sequence", + "endpoint": "NODE-sequence.obj", + "sql_endpoint": "NODE-sequence.sql_id", + "msql_endpoint": "NODE-sequence.msql", + "data": { + "name": "Seq1_$%{}[]()&*^!@\"'`\\/#", + "seqowner": "enterprisedb", + "schema": "public", + "increment": "5", + "start": "5", + "maximum": "999", + "minimum": "5", + "cache": "1", + "cycled": false, + "relacl": [], + "securities": [] + }, + "expected_sql_file": "create_sequence.sql", + "expected_msql_file": "create_sequence_msql.sql" + },{ + "type": "alter", + "name": "Alter Sequence comment", + "endpoint": "NODE-sequence.obj_id", + "sql_endpoint": "NODE-sequence.sql_id", + "msql_endpoint": "NODE-sequence.msql_id", + "data": { + "comment": "Some comment" + }, + "expected_sql_file": "alter_seq_comment.sql", + "expected_msql_file": "alter_seq_comment_msql.sql" + },{ + "type": "alter", + "name": "Alter Sequence properties", + "endpoint": "NODE-sequence.obj_id", + "sql_endpoint": "NODE-sequence.sql_id", + "msql_endpoint": "NODE-sequence.msql_id", + "data": { + "current_value": "7", "increment": "12", "minimum": "2", "maximum": "9992", "cache": "2", "cycled": true + }, + "expected_sql_file": "alter_seq_props.sql", + "expected_msql_file": "alter_seq_props_msql.sql" + },{ + "type": "alter", + "name": "Alter Sequence add privileges", + "endpoint": "NODE-sequence.obj_id", + "sql_endpoint": "NODE-sequence.sql_id", + "msql_endpoint": "NODE-sequence.msql_id", + "data": { + "relacl": { + "added":[{ + "grantee": "PUBLIC", + "grantor": "enterprisedb", + "privileges":[{ + "privilege_type": "r", + "privilege": true, + "with_grant": false + },{ + "privilege_type": "U", + "privilege": true, + "with_grant": false + },{ + "privilege_type": "w", + "privilege": true, + "with_grant": false + }] + }] + } + }, + "expected_sql_file": "alter_seq_privs_add.sql", + "expected_msql_file": "alter_seq_privs_add_msql.sql" + },{ + "type": "alter", + "name": "Alter Sequence update privileges", + "endpoint": "NODE-sequence.obj_id", + "sql_endpoint": "NODE-sequence.sql_id", + "msql_endpoint": "NODE-sequence.msql_id", + "data": { + "relacl": { + "changed":[{ + "grantee": "PUBLIC", + "grantor": "enterprisedb", + "privileges":[{ + "privilege_type": "r", + "privilege": true, + "with_grant": false + }] + }] + } + }, + "expected_sql_file": "alter_seq_privs_update.sql", + "expected_msql_file": "alter_seq_privs_update_msql.sql" + },{ + "type": "alter", + "name": "Alter Sequence remove privileges", + "endpoint": "NODE-sequence.obj_id", + "sql_endpoint": "NODE-sequence.sql_id", + "msql_endpoint": "NODE-sequence.msql_id", + "data": { + "relacl": { + "deleted":[{ + "grantee": "PUBLIC", + "grantor": "enterprisedb", + "privileges":[{ + "privilege_type": "r", + "privilege": true, + "with_grant": false + },{ + "privilege_type": "U", + "privilege": true, + "with_grant": false + },{ + "privilege_type": "w", + "privilege": true, + "with_grant": false + }] + }] + } + }, + "expected_sql_file": "alter_seq_privs_remove.sql", + "expected_msql_file": "alter_seq_privs_remove_msql.sql" + }, { + "type": "delete", + "name": "Drop sequence", + "endpoint": "NODE-sequence.delete_id", + "data": { + "name": "Seq1_$%{}[]()&*^!@\"'`\\/#" + } + }, { + "type": "create", + "name": "Create Sequence with Negative value", + "endpoint": "NODE-sequence.obj", + "sql_endpoint": "NODE-sequence.sql_id", + "msql_endpoint": "NODE-sequence.msql", + "data": { + "name": "Seq1_$%{}[]()&*^!@\"'`\\/#", + "seqowner": "enterprisedb", + "schema": "public", + "increment": "-5", + "start": "-30", + "maximum": "-10", + "minimum": "-40", + "cache": "1", + "cycled": false, + "relacl": [], + "securities": [] + }, + "expected_sql_file": "create_negative_sequence.sql", + "expected_msql_file": "create_negative_sequence_msql.sql" + }, { + "type": "alter", + "name": "Alter Sequence properties with negative value", + "endpoint": "NODE-sequence.obj_id", + "sql_endpoint": "NODE-sequence.sql_id", + "msql_endpoint": "NODE-sequence.msql_id", + "data": { + "increment": "-7", "minimum": "-35", "maximum": "-15" + }, + "expected_sql_file": "alter_neg_seq_props.sql", + "expected_msql_file": "alter_neg_seq_props_msql.sql" + }, { + "type": "delete", + "name": "Drop negative sequence", + "endpoint": "NODE-sequence.delete_id", + "data": { + "name": "Seq1_$%{}[]()&*^!@\"'`\\/#" + } + } + ] +} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_add.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_add.py new file mode 100644 index 000000000..7c1e8aaac --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_add.py @@ -0,0 +1,126 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2020, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +import json +import uuid + +from pgadmin.browser.server_groups.servers.databases.schemas.tests import \ + utils as schema_utils +from pgadmin.browser.server_groups.servers.databases.tests import utils as \ + database_utils +from pgadmin.utils.route import BaseTestGenerator +from regression import parent_node_dict +from regression.python_test_utils import test_utils as utils + + +class SequenceAddTestCase(BaseTestGenerator): + """ This class will add new sequence(s) under schema node. """ + skip_on_database = ['gpdb'] + scenarios = [ + # Fetching default URL for sequence node. + ( + 'Create sequence with positive values', + dict( + url='/browser/sequence/obj/', + # Valid optional data + data={ + "cache": "1", + "cycled": True, + "increment": "1", + "maximum": "100000", + "minimum": "1", + "name": "test_sequence_add_%s" % (str(uuid.uuid4())[1:8]), + "securities": [], + "start": "100" + } + ) + ), + ( + 'Create sequence with negative values', + dict( + url='/browser/sequence/obj/', + # Valid optional data + data={ + "cache": "1", + "cycled": True, + "increment": "-5", + "maximum": "-10", + "minimum": "-40", + "name": "test_sequence_add_%s" % (str(uuid.uuid4())[1:8]), + "securities": [], + "start": "-30" + } + ) + ) + ] + + def setUp(self): + super(SequenceAddTestCase, self).setUp() + + def runTest(self): + """This function will add sequence(s) under schema node.""" + db_name = parent_node_dict["database"][-1]["db_name"] + schema_info = parent_node_dict["schema"][-1] + self.server_id = schema_info["server_id"] + self.db_id = schema_info["db_id"] + db_con = database_utils.connect_database(self, utils.SERVER_GROUP, + self.server_id, self.db_id) + if not db_con['data']["connected"]: + raise Exception("Could not connect to database to add sequence.") + schema_id = schema_info["schema_id"] + schema_name = schema_info["schema_name"] + schema_response = schema_utils.verify_schemas(self.server, + db_name, + schema_name) + if not schema_response: + raise Exception("Could not find the schema to add sequence.") + db_user = self.server["username"] + + common_data = { + "relacl": [ + { + "grantee": db_user, + "grantor": db_user, + "privileges": + [ + { + "privilege_type": "r", + "privilege": True, + "with_grant": True + }, + { + "privilege_type": "w", + "privilege": True, + "with_grant": False + }, + { + "privilege_type": "U", + "privilege": True, + "with_grant": False + } + ] + } + ], + "schema": schema_name, + "seqowner": db_user, + } + + self.data.update(common_data) + + response = self.tester.post( + self.url + str(utils.SERVER_GROUP) + '/' + + str(self.server_id) + '/' + str(self.db_id) + + '/' + str(schema_id) + '/', + data=json.dumps(self.data), + content_type='html/json') + self.assertEquals(response.status_code, 200) + + def tearDown(self): + # Disconnect the database + database_utils.disconnect_database(self, self.server_id, self.db_id) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_delete.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_delete.py new file mode 100644 index 000000000..294bc4d63 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_delete.py @@ -0,0 +1,69 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2020, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +import uuid + +from pgadmin.browser.server_groups.servers.databases.schemas.tests import \ + utils as schema_utils +from pgadmin.browser.server_groups.servers.databases.tests import utils as \ + database_utils +from pgadmin.utils.route import BaseTestGenerator +from regression import parent_node_dict +from regression.python_test_utils import test_utils as utils +from . import utils as sequence_utils + + +class SequenceDeleteTestCase(BaseTestGenerator): + """This class will delete added sequence under schema node.""" + skip_on_database = ['gpdb'] + scenarios = [ + # Fetching default URL for sequence node. + ('Fetch sequence Node URL', dict(url='/browser/sequence/obj/')) + ] + + def setUp(self): + super(SequenceDeleteTestCase, self).setUp() + self.db_name = parent_node_dict["database"][-1]["db_name"] + schema_info = parent_node_dict["schema"][-1] + self.server_id = schema_info["server_id"] + self.db_id = schema_info["db_id"] + db_con = database_utils.connect_database(self, utils.SERVER_GROUP, + self.server_id, self.db_id) + if not db_con['data']["connected"]: + raise Exception("Could not connect to database to add sequence.") + self.schema_id = schema_info["schema_id"] + self.schema_name = schema_info["schema_name"] + schema_response = schema_utils.verify_schemas(self.server, + self.db_name, + self.schema_name) + if not schema_response: + raise Exception("Could not find the schema to add sequence.") + self.sequence_name = "test_sequence_delete_%s" % str(uuid.uuid4())[1:8] + self.sequence_id = sequence_utils.create_sequences( + self.server, self.db_name, self.schema_name, self.sequence_name) + + def runTest(self): + """ This function will delete added sequence under schema node. """ + sequence_response = sequence_utils.verify_sequence(self.server, + self.db_name, + self.sequence_name) + if not sequence_response: + raise Exception("Could not find the sequence to delete.") + response = self.tester.delete( + self.url + str(utils.SERVER_GROUP) + '/' + + str(self.server_id) + '/' + + str(self.db_id) + '/' + + str(self.schema_id) + '/' + + str(self.sequence_id), + follow_redirects=True) + self.assertEquals(response.status_code, 200) + + def tearDown(self): + # Disconnect the database + database_utils.disconnect_database(self, self.server_id, self.db_id) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_delete_multiple.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_delete_multiple.py new file mode 100644 index 000000000..f5cadd8d5 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_delete_multiple.py @@ -0,0 +1,93 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2020, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +import uuid +import json + +from pgadmin.browser.server_groups.servers.databases.schemas.tests import \ + utils as schema_utils +from pgadmin.browser.server_groups.servers.databases.tests import utils as \ + database_utils +from pgadmin.utils.route import BaseTestGenerator +from regression import parent_node_dict +from regression.python_test_utils import test_utils as utils +from . import utils as sequence_utils + + +class SequenceDeleteMultipleTestCase(BaseTestGenerator): + """This class will delete added sequence under schema node.""" + skip_on_database = ['gpdb'] + scenarios = [ + # Fetching default URL for sequence node. + ('Fetch sequence Node URL', dict(url='/browser/sequence/obj/')) + ] + + def setUp(self): + super(SequenceDeleteMultipleTestCase, self).setUp() + self.db_name = parent_node_dict["database"][-1]["db_name"] + schema_info = parent_node_dict["schema"][-1] + self.server_id = schema_info["server_id"] + self.db_id = schema_info["db_id"] + db_con = database_utils.connect_database(self, utils.SERVER_GROUP, + self.server_id, self.db_id) + if not db_con['data']["connected"]: + raise Exception("Could not connect to database to add sequence.") + self.schema_id = schema_info["schema_id"] + self.schema_name = schema_info["schema_name"] + schema_response = schema_utils.verify_schemas(self.server, + self.db_name, + self.schema_name) + if not schema_response: + raise Exception("Could not find the schema to add sequence.") + self.sequence_name = "test_sequence_delete_%s" % str(uuid.uuid4())[1:8] + self.sequence_name_1 = "test_sequence_delete_%s" %\ + str(uuid.uuid4())[1:8] + + self.sequence_ids = [sequence_utils.create_sequences( + self.server, + self.db_name, + self.schema_name, + self.sequence_name), + sequence_utils.create_sequences( + self.server, + self.db_name, + self.schema_name, + self.sequence_name_1) + ] + + def runTest(self): + """ This function will delete added sequence under schema node. """ + sequence_response = sequence_utils.verify_sequence(self.server, + self.db_name, + self.sequence_name) + if not sequence_response: + raise Exception("Could not find the sequence to delete.") + + sequence_response = sequence_utils.verify_sequence(self.server, + self.db_name, + self.sequence_name_1 + ) + if not sequence_response: + raise Exception("Could not find the sequence to delete.") + + data = json.dumps({'ids': self.sequence_ids}) + response = self.tester.delete( + self.url + str(utils.SERVER_GROUP) + '/' + + str(self.server_id) + '/' + + str(self.db_id) + '/' + + str(self.schema_id) + '/', + follow_redirects=True, + data=data, + content_type='html/json' + ) + self.assertEquals(response.status_code, 200) + + def tearDown(self): + # Disconnect the database + database_utils.disconnect_database(self, self.server_id, self.db_id) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_get.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_get.py new file mode 100644 index 000000000..9120a8900 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_get.py @@ -0,0 +1,64 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2020, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +import uuid + +from pgadmin.browser.server_groups.servers.databases.schemas.tests import \ + utils as schema_utils +from pgadmin.browser.server_groups.servers.databases.tests import utils as \ + database_utils +from pgadmin.utils.route import BaseTestGenerator +from regression import parent_node_dict +from regression.python_test_utils import test_utils as utils +from . import utils as sequence_utils + + +class SequenceGetTestCase(BaseTestGenerator): + """This class will fetch added sequence under schema node.""" + skip_on_database = ['gpdb'] + scenarios = [ + # Fetching default URL for sequence node. + ('Fetch sequence Node URL', dict(url='/browser/sequence/obj/')) + ] + + def setUp(self): + super(SequenceGetTestCase, self).setUp() + self.db_name = parent_node_dict["database"][-1]["db_name"] + schema_info = parent_node_dict["schema"][-1] + self.server_id = schema_info["server_id"] + self.db_id = schema_info["db_id"] + db_con = database_utils.connect_database(self, utils.SERVER_GROUP, + self.server_id, self.db_id) + if not db_con['data']["connected"]: + raise Exception("Could not connect to database to add sequence.") + self.schema_id = schema_info["schema_id"] + self.schema_name = schema_info["schema_name"] + schema_response = schema_utils.verify_schemas(self.server, + self.db_name, + self.schema_name) + if not schema_response: + raise Exception("Could not find the schema to add sequence.") + self.sequence_name = "test_sequence_delete_%s" % str(uuid.uuid4())[1:8] + self.sequence_id = sequence_utils.create_sequences( + self.server, self.db_name, self.schema_name, self.sequence_name) + + def runTest(self): + """This function will fetch added sequence under schema node.""" + response = self.tester.get( + self.url + str(utils.SERVER_GROUP) + '/' + + str(self.server_id) + '/' + + str(self.db_id) + '/' + + str(self.schema_id) + '/' + + str(self.sequence_id), + follow_redirects=True) + self.assertEquals(response.status_code, 200) + + def tearDown(self): + # Disconnect the database + database_utils.disconnect_database(self, self.server_id, self.db_id) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_put.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_put.py new file mode 100644 index 000000000..1eeedd106 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_put.py @@ -0,0 +1,98 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2020, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +import json +import uuid + +from pgadmin.browser.server_groups.servers.databases.schemas.tests import \ + utils as schema_utils +from pgadmin.browser.server_groups.servers.databases.tests import utils as \ + database_utils +from pgadmin.utils.route import BaseTestGenerator +from regression import parent_node_dict +from regression.python_test_utils import test_utils as utils +from . import utils as sequence_utils + + +class SequencePutTestCase(BaseTestGenerator): + """This class will update added sequence under schema node.""" + skip_on_database = ['gpdb'] + scenarios = [ + # Fetching default URL for sequence node. + ('Alter positive sequence comment, increment, max and min value', + dict( + url='/browser/sequence/obj/', + data={ + "comment": "This is sequence update comment", + "increment": "5", + "maximum": "1000", + "minimum": "10", + }, + positive_seq=True + )), + ('Alter negative sequence comment, increment, max and min value', + dict( + url='/browser/sequence/obj/', + data={ + "comment": "This is sequence update comment", + "increment": "-7", + "maximum": "-15", + "minimum": "-35", + }, + positive_seq=False + )) + ] + + def setUp(self): + super(SequencePutTestCase, self).setUp() + self.db_name = parent_node_dict["database"][-1]["db_name"] + schema_info = parent_node_dict["schema"][-1] + self.server_id = schema_info["server_id"] + self.db_id = schema_info["db_id"] + db_con = database_utils.connect_database(self, utils.SERVER_GROUP, + self.server_id, self.db_id) + if not db_con['data']["connected"]: + raise Exception("Could not connect to database to add sequence.") + self.schema_id = schema_info["schema_id"] + self.schema_name = schema_info["schema_name"] + schema_response = schema_utils.verify_schemas(self.server, + self.db_name, + self.schema_name) + if not schema_response: + raise Exception("Could not find the schema to add sequence.") + self.sequence_name = "test_sequence_delete_%s" % str(uuid.uuid4())[1:8] + self.sequence_id = sequence_utils.create_sequences( + self.server, self.db_name, self.schema_name, self.sequence_name, + self.positive_seq + ) + + def runTest(self): + """This function will update added sequence under schema node.""" + sequence_response = sequence_utils.verify_sequence(self.server, + self.db_name, + self.sequence_name) + if not sequence_response: + raise Exception("Could not find the sequence to delete.") + + # Add sequence id. + self.data["id"] = self.sequence_id + + response = self.tester.put( + self.url + str(utils.SERVER_GROUP) + '/' + + str(self.server_id) + '/' + + str(self.db_id) + '/' + + str(self.schema_id) + '/' + + str(self.sequence_id), + data=json.dumps(self.data), + follow_redirects=True) + self.assertEquals(response.status_code, 200) + + def tearDown(self): + # Disconnect the database + database_utils.disconnect_database(self, self.server_id, self.db_id) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/utils.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/utils.py new file mode 100644 index 000000000..d47688026 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/utils.py @@ -0,0 +1,89 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2020, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + + +import sys +import traceback + +from regression.python_test_utils import test_utils as utils + + +def create_sequences(server, db_name, schema_name, sequence_name, + positive_seq=True): + """ + This function used to create sequence in schema provided. + :param server: server details + :type server: dict + :param db_name: database name + :type db_name: str + :param schema_name: schema name + :type schema_name: str + :param sequence_name: sequence name + :type sequence_name: str + :param positive_seq: True is sequence will be created using positive values + :type positive_seq: boolean + :return sequence_id: sequence id + :rtype: int + """ + try: + connection = utils.get_db_connection(db_name, + server['username'], + server['db_password'], + server['host'], + server['port'], + server['sslmode']) + pg_cursor = connection.cursor() + + query = "CREATE SEQUENCE %s.%s INCREMENT 5 START 30 " \ + "MINVALUE 10 MAXVALUE 100" % (schema_name, sequence_name) + if not positive_seq: + query = "CREATE SEQUENCE %s.%s INCREMENT -5 START -30 " \ + "MINVALUE -40 MAXVALUE -10" % (schema_name, sequence_name) + pg_cursor.execute(query) + connection.commit() + # Get 'oid' from newly created sequence + pg_cursor.execute("select oid from pg_class where relname='%s'" % + sequence_name) + sequence = pg_cursor.fetchone() + sequence_id = '' + if sequence: + sequence_id = sequence[0] + connection.close() + return sequence_id + except Exception: + traceback.print_exc(file=sys.stderr) + + +def verify_sequence(server, db_name, sequence_name): + """ + This function verifies the sequence in database + :param server: server details + :type server: dict + :param db_name: database name + :type db_name: str + :param sequence_name: sequence name + :type sequence_name: str + :return sequence: sequence record from database + :rtype: tuple + """ + try: + connection = utils.get_db_connection(db_name, + server['username'], + server['db_password'], + server['host'], + server['port'], + server['sslmode']) + pg_cursor = connection.cursor() + pg_cursor.execute("select * from pg_class where relname='%s'" % + sequence_name) + sequence = pg_cursor.fetchone() + connection.close() + return sequence + except Exception: + traceback.print_exc(file=sys.stderr) diff --git a/web/webpack.config.js b/web/webpack.config.js index 18ec4a65f..885fd64d3 100644 --- a/web/webpack.config.js +++ b/web/webpack.config.js @@ -449,6 +449,7 @@ module.exports = [{ ',pgadmin.node.catalog_object' + ',pgadmin.node.collation' + ',pgadmin.node.domain' + + ',pgadmin.node.foo' + ',pgadmin.node.domain_constraints' + ',pgadmin.node.foreign_table' + ',pgadmin.node.fts_configuration' + diff --git a/web/webpack.shim.js b/web/webpack.shim.js index da19b6897..7b51de4cf 100644 --- a/web/webpack.shim.js +++ b/web/webpack.shim.js @@ -220,6 +220,7 @@ var webpackShimConfig = { 'pgadmin.node.exclusion_constraint': path.join(__dirname, './pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/static/js/exclusion_constraint'), 'pgadmin.node.extension': path.join(__dirname, './pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension'), 'pgadmin.node.external_table': path.join(__dirname, './pgadmin/static/js/browser/server_groups/servers/databases/external_tables/index'), + 'pgadmin.node.foo': path.join(__dirname, './pgadmin/browser/server_groups/servers/databases/schemas/foos/static/js/foo'), 'pgadmin.node.foreign_data_wrapper': path.join(__dirname, './pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/static/js/foreign_data_wrapper'), 'pgadmin.node.foreign_key': path.join(__dirname, './pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/static/js/foreign_key'), 'pgadmin.node.foreign_server': path.join(__dirname, './pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/foreign_servers/static/js/foreign_server'), -- 2.22.0.windows.1