Hi,

PFA updated patch for sequence node.

Changes: 1] Added changes related to schema child node.
               2] re-based with latest code.
               3] Added dependencies and dependents functionality.


-- 
*Harshal Dhumal*
*Software Engineer *



EenterpriseDB <http://www.enterprisedb.com>

On Wed, Feb 10, 2016 at 7:11 PM, Harshal Dhumal <
harshal.dhu...@enterprisedb.com> wrote:

> Hi,
>
> PFA updated patch for sequence node.
>
> *Changes:* Updated sql files to refer macros from
> schemas/templates/macros/schemas folder instead of servers/templates/macros
>
>
> --
> *Harshal Dhumal*
> *Software Engineer *
>
>
>
> EenterpriseDB <http://www.enterprisedb.com>
>
> On Wed, Feb 10, 2016 at 5:46 PM, Harshal Dhumal <
> harshal.dhu...@enterprisedb.com> wrote:
>
>> Hi,
>>
>> Here is updated patch for sequence node. As macros are changed for
>> security and privileges.
>>
>>
>> --
>> *Harshal Dhumal*
>> *Software Engineer *
>>
>>
>>
>> EenterpriseDB <http://www.enterprisedb.com>
>>
>> On Tue, Feb 9, 2016 at 4:19 PM, Harshal Dhumal <
>> harshal.dhu...@enterprisedb.com> wrote:
>>
>>> Hi,
>>>
>>> PFA patch for sequence node.
>>>
>>>
>>> --
>>> *Harshal Dhumal*
>>> *Software Engineer *
>>>
>>>
>>>
>>> EenterpriseDB <http://www.enterprisedb.com>
>>>
>>
>>
>
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/__init__.py
new file mode 100644
index 0000000..e57ef65
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/__init__.py
@@ -0,0 +1,680 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2016, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+"""Implements Sequence Node"""
+
+import json
+from flask import render_template, make_response, request, jsonify
+from flask.ext.babel import gettext as _
+from pgadmin.utils.ajax import make_json_response, \
+    make_response as ajax_response, internal_server_error
+from pgadmin.browser.utils import PGChildNodeView
+from pgadmin.browser.server_groups.servers.utils import parse_priv_from_db, \
+    parse_priv_to_db
+from pgadmin.browser.server_groups.servers.databases.schemas.utils \
+    import SchemaChildModule
+import pgadmin.browser.server_groups.servers.databases as database
+from pgadmin.utils.ajax import precondition_required
+from pgadmin.utils.driver import get_driver
+from config import PG_DEFAULT_DRIVER
+from functools import wraps
+
+
+class SequenceModule(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_TYPE = 'sequence'
+    COLLECTION_LABEL = _("Sequences")
+
+    def __init__(self, *args, **kwargs):
+        super(SequenceModule, self).__init__(*args, **kwargs)
+        self.min_ver = None
+        self.max_ver = None
+
+    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
+
+blueprint = SequenceModule(__name__)
+
+
+class SequenceView(PGChildNodeView):
+    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': 'seid'}
+            ]
+
+    operations = dict({
+        'obj': [
+            {'get': 'properties', 'delete': 'delete', 'put': 'update'},
+            {'get': 'list', 'post': 'create'}
+        ],
+        'delete': [{'delete': 'delete'}],
+        'children': [{'get': 'children'}],
+        'nodes': [{'get': 'node'}, {'get': 'nodes'}],
+        'sql': [{'get': 'sql'}],
+        'msql': [{'get': 'msql'}, {'get': 'msql'}],
+        'stats': [{'get': 'statistics'}],
+        'dependency': [{'get': 'dependencies'}],
+        'dependent': [{'get': 'dependents'}],
+        'module.js': [{}, {}, {'get': 'module_js'}]
+    })
+
+    def module_js(self):
+        """
+        This property defines (if javascript) exists for this node.
+        Override this property for your own logic.
+        """
+        return make_response(
+                render_template(
+                    "sequence/js/sequence.js",
+                    _=_
+                    ),
+                200, {'Content-Type': 'application/x-javascript'}
+                )
+
+    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):
+
+                self.manager = get_driver(PG_DEFAULT_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()
+                # If DB not connected then return error to browser
+                if not self.conn.connected():
+                    return precondition_required(
+                        _(
+                                "Connection to the server has been lost!"
+                        )
+                    )
+
+                self.template_path = 'sequence/sql/9.1_plus'
+
+                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 that collection.
+
+        Args:
+          gid: Server Group ID
+          sid: Server ID
+          did: Database ID
+          scid: Schema ID
+
+        Returns:
+
+        """
+        SQL = render_template("/".join([self.template_path, 'properties.sql']), scid=scid)
+        status, res = self.conn.execute_dict(SQL)
+
+        if not status:
+            return internal_server_error(errormsg=res)
+        return ajax_response(
+                response=res['rows'],
+                status=200
+                )
+
+    @check_precondition(action='nodes')
+    def nodes(self, gid, sid, did, scid):
+        """
+        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, 'nodes.sql']), scid=scid)
+        status, rset = self.conn.execute_dict(SQL)
+        if not status:
+            return internal_server_error(errormsg=rset)
+
+        for row in rset['rows']:
+            res.append(
+                    self.blueprint.generate_browser_node(
+                        row['oid'],
+                        sid,
+                        row['name'],
+                        icon="icon-%s" % self.node_type
+                    ))
+
+        return make_json_response(
+                data=res,
+                status=200
+                )
+
+    @check_precondition(action='properties')
+    def properties(self, gid, sid, did, scid, seid):
+        """
+        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
+          seid: Sequence ID
+
+        Returns:
+
+        """
+        SQL = render_template("/".join([self.template_path, 'properties.sql']), scid=scid, seid=seid)
+        status, res = self.conn.execute_dict(SQL)
+
+        if not status:
+            return internal_server_error(errormsg=res)
+
+        sec_lbls = []
+        if 'securities' in res and res['securities'] is not None:
+            for sec in res['seclabels']:
+                sec = re.search(r'([^=]+)=(.*$)', sec)
+                sec_lbls.append({
+                    'provider': sec.group(1),
+                    'security_label': sec.group(2)
+                    })
+        res['securities'] = sec_lbls
+
+        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['cache'] = rset1['rows'][0]['cache_value']
+            row['cycled'] = rset1['rows'][0]['is_cycled']
+
+        SQL = render_template("/".join([self.template_path, 'acl.sql']), scid=scid, seid=seid)
+        status, dataclres = self.conn.execute_dict(SQL)
+        if not status:
+            return 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 ajax_response(
+                response=res['rows'][0],
+                status=200
+                )
+
+    @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.decode())
+
+        for arg in required_args:
+            if arg not in data:
+                return make_json_response(
+                    status=400,
+                    success=0,
+                    errormsg=_(
+                        "Couldn't find the required parameter (%s)." % arg
+                    )
+                )
+        try:
+            # The SQL below will execute CREATE DDL only
+            SQL = render_template("/".join([self.template_path, 'create.sql']), data=data, conn=self.conn)
+            status, msg = self.conn.execute_scalar(SQL)
+            if not status:
+                return internal_server_error(errormsg=msg)
+
+            if 'relacl' in data:
+                data['relacl'] = parse_priv_to_db(data['relacl'], 'DATABASE')
+
+            # The SQL below will execute rest DMLs because we can not execute CREATE with any other
+            SQL = render_template("/".join([self.template_path, 'grant.sql']), data=data, conn=self.conn)
+            SQL = 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, 'get_oid.sql']), name=data['name'], scid=scid)
+            SQL = SQL.strip('\n').strip(' ')
+            if SQL and SQL != "":
+                status, seid = self.conn.execute_scalar(SQL)
+                if not status:
+                    return internal_server_error(errormsg=res)
+
+            return jsonify(
+                node=self.blueprint.generate_browser_node(
+                    seid,
+                    scid,
+                    data['name'],
+                    icon="icon-%s" % self.node_type
+                    )
+                )
+
+        except Exception as e:
+            return make_json_response(
+                status=500,
+                success=0,
+                errormsg=str(e)
+            )
+
+    @check_precondition(action='delete')
+    def delete(self, gid, sid, did, scid, seid):
+        """
+        This function will drop the object
+
+        Args:
+          gid: Server Group ID
+          sid: Server ID
+          did: Database ID
+          scid: Schema ID
+          seid: Sequence ID
+
+        Returns:
+
+        """
+        # 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:
+            SQL = render_template("/".join([self.template_path, 'properties.sql']), scid=scid, seid=seid)
+            status, res = self.conn.execute_dict(SQL)
+            if not status:
+                return internal_server_error(errormsg=res)
+
+            SQL = render_template("/".join([self.template_path, 'delete.sql']), data=res['rows'][0], cascade=cascade)
+            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"),
+                data={
+                    'id': seid,
+                    'scid': scid,
+                    'sid': sid,
+                    'gid': gid,
+                    'did': did
+                }
+            )
+
+        except Exception as e:
+            return internal_server_error(errormsg=str(e))
+
+    @check_precondition(action='update')
+    def update(self, gid, sid, did, scid, seid):
+        """
+        This function will update the object
+
+        Args:
+          gid: Server Group ID
+          sid: Server ID
+          did: Database ID
+          scid: Schema ID
+          seid: Sequence ID
+
+        Returns:
+
+        """
+        data = request.form if request.form else json.loads(request.data.decode())
+        try:
+            SQL = self.getSQL(gid, sid, did, data, scid, seid)
+            SQL = SQL.strip('\n').strip(' ')
+            if 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 updated",
+                    data={
+                        'id': seid,
+                        'scid': scid,
+                        'sid': sid,
+                        'gid': gid,
+                        'did': did
+                    }
+                )
+            else:
+                return make_json_response(
+                    success=1,
+                    info="Nothing to update",
+                    data={
+                        'id': seid,
+                        'scid': scid,
+                        'sid': sid,
+                        'gid': gid,
+                        'did': did
+                    }
+                )
+
+        except Exception as e:
+            return internal_server_error(errormsg=str(e))
+
+    @check_precondition(action='msql')
+    def msql(self, gid, sid, did, scid, seid=None):
+        """
+        This function to return modified SQL.
+
+        Args:
+            gid: Server Group ID
+            sid: Server ID
+            did: Database ID
+            scid: Schema ID
+            seid: Sequence ID
+        """
+
+        data = {}
+        for k, v in request.args.items():
+            try:
+                data[k] = json.loads(v)
+            except ValueError:
+                data[k] = v
+
+        if seid 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=_(
+                            "Couldn't find the required parameter (%s)." % arg
+                        )
+                    )
+        try:
+            SQL = self.getSQL(gid, sid, did, data, scid, seid)
+            SQL = SQL.strip('\n').strip(' ')
+            return make_json_response(
+                    data=SQL,
+                    status=200
+                    )
+        except Exception as e:
+            return make_json_response(
+                    data="-- modified SQL",
+                    status=200
+                    )
+
+    def getSQL(self, gid, sid, did, data, scid, seid=None):
+        """
+        This function will generate sql from model data.
+
+        Args:
+            gid: Server Group ID
+            sid: Server ID
+            did: Database ID
+            scid: Schema ID
+            seid: Sequence ID
+        """
+
+        required_args = [
+            u'name'
+        ]
+
+        if seid is not None:
+            SQL = render_template("/".join([self.template_path, 'properties.sql']), scid=scid, seid=seid)
+            status, res = self.conn.execute_dict(SQL)
+            if not status:
+                return internal_server_error(errormsg=res)
+            # Making copy of output for further processing
+            old_data = dict(res['rows'][0])
+            old_data = self._formatter(old_data, scid, seid)
+
+            # 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'], 'SEQUENCE')
+                    if 'changed' in data[key]:
+                      data[key]['changed'] = parse_priv_to_db(data[key]['changed'], 'SEQUENCE')
+                    if 'deleted' in data[key]:
+                      data[key]['deleted'] = parse_priv_to_db(data[key]['deleted'], 'SEQUENCE')
+
+            # 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, 'update.sql']),
+                                  data=data, o_data=old_data, conn=self.conn)
+        else:
+            # To format privileges coming from client
+            if 'relacl' in data:
+                data['relacl'] = parse_priv_to_db(data['relacl'], 'SEQUENCE')
+
+            SQL = render_template("/".join([self.template_path, 'create.sql']), data=data, conn=self.conn)
+            SQL += render_template("/".join([self.template_path, 'grant.sql']), data=data, conn=self.conn)
+        return SQL
+
+    @check_precondition(action="sql")
+    def sql(self, gid, sid, did, scid, seid):
+        """
+        This function will generate sql for sql panel
+
+        Args:
+            gid: Server Group ID
+            sid: Server ID
+            did: Database ID
+            scid: Schema ID
+            seid: Sequence ID
+        """
+
+        SQL = render_template("/".join([self.template_path, 'properties.sql']), scid=scid, seid=seid)
+        status, res = self.conn.execute_dict(SQL)
+        if not status:
+            return internal_server_error(errormsg=res)
+
+        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['cache'] = rset1['rows'][0]['cache_value']
+            row['cycled'] = rset1['rows'][0]['is_cycled']
+
+        result = res['rows'][0]
+        result = self._formatter(result, scid, seid)
+        SQL = self.getSQL(gid, sid, did, result, scid)
+        SQL = SQL.strip('\n').strip(' ')
+        return ajax_response(response=SQL)
+
+    def _formatter(self, data, scid, seid):
+        """
+        Args:
+            data: dict of query result
+            scid: Schema ID
+            seid: 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, 'security_label': v})
+
+            data['securities'] = seclabels
+
+        # We need to parse & convert ACL coming from database to json format
+        SQL = render_template("/".join([self.template_path, 'acl.sql']),
+                              scid=scid, seid=seid)
+        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, seid):
+        """
+        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
+            seid: Sequence ID
+        """
+        dependents_result = self.get_dependents(self.conn, seid)
+        return ajax_response(
+                response=dependents_result,
+                status=200
+                )
+
+    @check_precondition(action="dependencies")
+    def dependencies(self, gid, sid, did, scid, seid):
+        """
+        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
+            seid: Sequence ID
+        """
+        dependencies_result = self.get_dependencies(self.conn, seid)
+
+        # 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']), seid=seid)
+
+        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 ajax_response(
+                response=dependencies_result,
+                status=200
+                )
+
+
+SequenceView.register_node_view(blueprint)
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/static/img/coll-sequence.png b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/static/img/coll-sequence.png
new file mode 100644
index 0000000000000000000000000000000000000000..905554d8c6bcb27e0392b615a954a79dac53573b
GIT binary patch
literal 359
zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!eSlAhE0Es4{7y^ekzap+;NSn>
z|Ns8}|L)a~4fAfUoqlIZ&G~t4*XMOy|M2R^+}3NiE__(pf8)@mrw2DaTRr{W+UfVy
zeAN_yMlhBH`2{mLJiCzw<Zu>vL>2>S4={E+nQaGT#Cy6phDcmaJs-{2puppD@!Ssw
zSH_Ef*M|z2g#5lfTiC;urDY3q*{%)pZreCbCc8ZlU%E)ZLZ5ZvyKC!wPUI}TV0pY}
z&-ZdhX6{?bYnCp0Tyw8ha8|!@(=Lrac~^d0i-);09Y~X6xCpdLwZt`|BqgyV)hf9t
z6-Y4{85kPq8XD;u7={=bSeY1GnV4!Dm|7Va%zLM|3PnS1eoAIqB}9XPC0GMcwTYF1
X8AQXW>7i?Y8W=oX{an^LB{Ts5VbzJn

literal 0
HcmV?d00001

diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/static/img/sequence.png b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/static/img/sequence.png
new file mode 100644
index 0000000000000000000000000000000000000000..1ce216c07b2ede8fc5e0ed93df65d20a33475f80
GIT binary patch
literal 405
zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}W`IwKE0Es4{7y^ekyFPW-M|0-
z;r+Ld?!Ei{_xGPae}4V>^Y{1vKY#xH|NZ~ns~;a;{rd3g$E^z=Zk_vZaO1N>o1U(o
zerMH;yKAT4Sv~#U+UfTebX=bYL~YmSwq9G>e`9I?txb#WZd`b8!-Bi}Ha(t`$KDOJ
zjIkuhFPOpM*^M+HhqJ&VvKUBvfU(=jY&#$$+0(@_MB;L4|4Ata10J^7H@sKgir%{S
zzw;xfLwC~n{!iy9WaMaKlGwl`;by2iLnU+CL?(^YIFGQ9l_5vF)@{AEM&h!>XORQj
zUbj#DkurDlk>|6^8UH@oo8J9;TYa8=-TlJ!Iea@=Tm!f?@`2W=mbgZgq$HN4S|t~y
z0x1R~149E{LnB=S!w@3_D-&ZY6H{#iQ!4|5dGGXAp=ij>PsvQHglI6Z1Zx1QHnB1=
WgJ?K4J#-CF1B0ilpUXO@geCwH#jsHT

literal 0
HcmV?d00001

diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/js/sequence.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/js/sequence.js
new file mode 100644
index 0000000..ed5320f
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/js/sequence.js
@@ -0,0 +1,231 @@
+define(
+        ['jquery', 'underscore', 'underscore.string', 'pgadmin', 'pgadmin.browser', 'alertify', 'pgadmin.browser.collection'],
+function($, _, S, pgAdmin, pgBrowser, alertify) {
+
+  // Extend the browser's node model class to create a security model
+  var SecurityModel = pgAdmin.Browser.Node.Model.extend({
+    defaults: {
+      provider: undefined,
+      securitylabel: undefined
+    },
+    // Define the schema for the Security Label
+    schema: [{
+      id: 'provider', label: '{{ _('Provider') }}',
+      type: 'text', editable: true
+    },{
+      id: 'security_label', label: '{{ _('Security Label') }}',
+      type: 'text', editable: true
+    }],
+    /* 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 err = {},
+          errmsg = null,
+          data = this.toJSON();
+
+      if (_.isUndefined(data.label) ||
+        _.isNull(data.label) ||
+        String(data.label).replace(/^\s+|\s+$/g, '') == '') {
+        return _("Please specify the value for all the security providers.");
+      }
+      return null;
+    }
+  });
+
+  // Extend the browser's collection class for sequence collection
+  if (!pgBrowser.Nodes['coll-sequence']) {
+    var databases = pgAdmin.Browser.Nodes['coll-sequence'] =
+      pgAdmin.Browser.Collection.extend({
+        node: 'sequence',
+        label: '{{ _('Sequences') }}',
+        type: 'coll-sequence',
+        columns: ['oid', 'name', 'seqowner', 'comment']
+      });
+  };
+
+  // Extend the browser's node class for sequence node
+  if (!pgBrowser.Nodes['sequence']) {
+    pgAdmin.Browser.Nodes['sequence'] = pgBrowser.Node.extend({
+      type: 'sequence',
+      label: '{{ _('Sequence') }}',
+      collection_type: 'coll-sequence',
+      hasSQL: true,
+      hasDepends: true,
+      parent_type: ['schema'],
+      Init: function() {
+        /* Avoid mulitple registration of menus */
+        if (this.initialized)
+            return;
+
+        this.initialized = true;
+
+        pgBrowser.add_menus([{
+          name: 'create_sequence_on_coll', node: 'coll-sequence', module: this,
+          applies: ['object', 'context'], callback: 'show_obj_properties',
+          category: 'create', priority: 4, label: '{{ _('Sequence...') }}',
+          icon: 'wcTabIcon icon-sequence', data: {action: 'create', check: true},
+          enable: 'canCreate'
+        },{
+          name: 'create_sequence', node: 'sequence', module: this,
+          applies: ['object', 'context'], callback: 'show_obj_properties',
+          category: 'create', priority: 4, label: '{{ _('Sequence...') }}',
+          icon: 'wcTabIcon icon-sequence', data: {action: 'create', check: true},
+          enable: 'canCreate'
+        },{
+          name: 'create_sequence', node: 'schema', module: this,
+          applies: ['object', 'context'], callback: 'show_obj_properties',
+          category: 'create', priority: 4, label: '{{ _('Sequence...') }}',
+          icon: 'wcTabIcon icon-sequence', data: {action: 'create', check: false},
+          enable: 'canCreate'
+        }
+        ]);
+
+      },
+      canDrop: pgBrowser.Nodes['schema'].canChildDrop,
+      canDropCascade: pgBrowser.Nodes['schema'].canChildDrop,
+      canCreate: function(itemData, item, data) {
+          //If check is false then , we will allow create menu
+          if (data && data.check == false)
+            return true;
+
+          var t = pgBrowser.tree, i = item, d = itemData;
+          // To iterate over tree to check parent node
+          while (i) {
+            // If it is schema then allow user to create collation
+            if (_.indexOf(['schema'], d._type) > -1)
+              return true;
+
+            if ('coll-sequence' == d._type) {
+              //Check if we are not child of catalog
+              prev_i = t.hasParent(i) ? t.parent(i) : null;
+              prev_d = prev_i ? t.itemData(prev_i) : null;
+              if( prev_d._type == 'catalog') {
+                return false;
+              } else {
+                return true;
+              }
+            }
+            i = t.hasParent(i) ? t.parent(i) : null;
+            d = i ? t.itemData(i) : null;
+          }
+          // by default we want to allow create menu
+          return true;
+      },
+      // Define the model for sequence node.
+      model: pgAdmin.Browser.Node.Model.extend({
+        defaults: {
+          name: undefined,
+          oid: undefined,
+          seqowner: undefined,
+          schema: undefined,
+          comment: undefined,
+          increment: undefined,
+          start: undefined,
+          current_value: undefined,
+          minimum: undefined,
+          maximum: undefined,
+          cache: undefined,
+          cycled: undefined,
+          relacl: [],
+          securities: []
+        },
+        // Define the schema for sequence node.
+        schema: [{
+          id: 'name', label: '{{ _('Name') }}', cell: 'string',
+          type: 'text', mode: ['properties', 'create', 'edit']
+        },{
+          id: 'oid', label:'{{ _('Oid') }}', cell: 'string',
+          type: 'text' , mode: ['properties']
+        },{
+          id: 'seqowner', label:'{{ _('Owner') }}', cell: 'string',
+          type: 'text', mode: ['properties', 'create', 'edit'], node: 'role',
+          control: Backform.NodeListByNameControl
+        },{
+          id: 'schema', label:'{{ _('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;
+            }
+        },{
+          id: 'comment', label:'{{ _('Comment') }}', type: 'multiline',
+          mode: ['properties', 'create', 'edit']
+        },{
+          id: 'increment', label: '{{ _('Increment') }}', type: 'int',
+          mode: ['properties', 'create', 'edit'], group: '{{ _('Definition') }}'
+        },{
+          id: 'start', label: '{{ _('Start') }}', type: 'int',
+          mode: ['create'], group: '{{ _('Definition') }}'
+        },{
+          id: 'current_value', label: '{{ _('Current value') }}', type: 'int',
+          mode: ['properties', 'edit'], group: '{{ _('Definition') }}'
+        },{
+          id: 'minimum', label: '{{ _('Minimum') }}', type: 'int',
+          mode: ['properties', 'create', 'edit'], group: '{{ _('Definition') }}'
+        },{
+          id: 'maximum', label: '{{ _('Maximum') }}', type: 'int',
+          mode: ['properties', 'create', 'edit'], group: '{{ _('Definition') }}'
+        },{
+          id: 'cache', label: '{{ _('Cache') }}', type: 'int',
+          mode: ['properties', 'create', 'edit'], group: '{{ _('Definition') }}'
+        },{
+          id: 'cycled', label: '{{ _('Cycled') }}', type: 'switch',
+          mode: ['properties', 'create', 'edit'], group: '{{ _('Definition') }}'
+        },{
+          id: 'relacl', label: '{{ _('Privileges') }}', model: pgAdmin.Browser.Node.PrivilegeRoleModel.extend(
+            {privileges: ['r', 'w', 'U']}), uniqueCol : ['grantee', 'grantor'],
+          editable: false, type: 'collection', group: '{{ _('Security') }}', mode: ['properties', 'edit', 'create'],
+          canAdd: true, canDelete: true, control: 'unique-col-collection',
+        },{
+          id: 'securities', label: '{{ _('Securitiy Labels') }}', model: SecurityModel,
+          editable: false, type: 'collection', canEdit: false,
+          group: '{{ _('Security') }}', canDelete: true,
+          mode: ['properties', 'edit', 'create'], canAdd: true,
+          control: 'unique-col-collection', uniqueCol : ['provider'],
+          min_version: 90200
+        }],
+        /* 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;
+          // Clear any existing error msg.
+          this.errorModel.unset('name');
+          this.errorModel.unset('seqowner');
+          this.errorModel.unset('schema');
+
+          if (_.isUndefined(this.get('name'))
+              || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
+            msg = '{{ _('Sequence name can not be empty!') }}';
+            this.errorModel.set('name', msg);
+            return msg;
+          }
+
+          if (_.isUndefined(this.get('seqowner'))
+              || String(this.get('seqowner')).replace(/^\s+|\s+$/g, '') == '') {
+            msg = '{{ _('Sequence owner can not be empty!') }}';
+            this.errorModel.set('seqowner', msg);
+            return msg;
+          }
+
+          if (_.isUndefined(this.get('schema'))
+              || String(this.get('schema')).replace(/^\s+|\s+$/g, '') == '') {
+            msg = '{{ _('Sequence schema can not be empty!') }}';
+            this.errorModel.set('schema', msg);
+            return msg;
+          }
+          return null;
+        }
+      })
+    });
+  }
+
+  return pgBrowser.Nodes['sequence'];
+});
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/sql/9.1_plus/acl.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/sql/9.1_plus/acl.sql
new file mode 100644
index 0000000..f27c924
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/sql/9.1_plus/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
+		(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 = {{seid}}::oid ) acl,
+		aclexplode(relacl) 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
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/sql/9.1_plus/backend_support.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/sql/9.1_plus/backend_support.sql
new file mode 100644
index 0000000..f9b9564
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/sql/9.1_plus/backend_support.sql
@@ -0,0 +1,18 @@
+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}}::int
+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/sequences/templates/sequence/sql/9.1_plus/create.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/sql/9.1_plus/create.sql
new file mode 100644
index 0000000..5bea409
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/sql/9.1_plus/create.sql
@@ -0,0 +1,14 @@
+{% if data %}
+CREATE SEQUENCE {{ conn|qtIdent(data.schema) }}.{{ conn|qtIdent(data.name) }}{% if data.cycled and data.cycled == True %} CYCLE{% endif %}
+{% if data.increment %}
+
+INCREMENT {{data.increment}}{% endif %}{% if data.start %}
+
+START {{data.start}}{% endif %}{% if data.minimum %}
+
+MINVALUE {{data.minimum}}{% endif %}{% if data.maximum %}
+
+MAXVALUE {{data.maximum}}{% endif %}{% if data.cache %}
+
+CACHE {{data.cache}}{% endif %};
+{% endif %}
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/sql/9.1_plus/delete.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/sql/9.1_plus/delete.sql
new file mode 100644
index 0000000..efd218e
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/sql/9.1_plus/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/sequences/templates/sequence/sql/9.1_plus/get_def.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/sql/9.1_plus/get_def.sql
new file mode 100644
index 0000000..1c926db
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/sql/9.1_plus/get_def.sql
@@ -0,0 +1,3 @@
+SELECT last_value, min_value, max_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/sequences/templates/sequence/sql/9.1_plus/get_dependencies.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/sql/9.1_plus/get_dependencies.sql
new file mode 100644
index 0000000..31812d2
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/sql/9.1_plus/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={{seid}}::oid
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/sql/9.1_plus/get_oid.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/sql/9.1_plus/get_oid.sql
new file mode 100644
index 0000000..361a6bb
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/sql/9.1_plus/get_oid.sql
@@ -0,0 +1,5 @@
+SELECT cl.oid as oid
+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 relname = {{ name|qtLiteral }}
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/sql/9.1_plus/grant.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/sql/9.1_plus/grant.sql
new file mode 100644
index 0000000..e976066
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/sql/9.1_plus/grant.sql
@@ -0,0 +1,26 @@
+{% import 'macros/schemas/security.macros' as SECLABLE %}
+{% 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 %}
+{{ SECLABLE.SET(conn, 'SEQUENCE', data.name, r.provider, r.security_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 %}
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/sql/9.1_plus/nodes.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/sql/9.1_plus/nodes.sql
new file mode 100644
index 0000000..1312896
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/sql/9.1_plus/nodes.sql
@@ -0,0 +1,4 @@
+SELECT cl.oid as oid, relname as name
+FROM pg_class cl
+WHERE relkind = 'S' AND relnamespace = {{scid}}::oid
+ORDER BY relname
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/sql/9.1_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/sql/9.1_plus/properties.sql
new file mode 100644
index 0000000..caab0ed
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/sql/9.1_plus/properties.sql
@@ -0,0 +1,11 @@
+{% if scid %}
+SELECT cl.oid as oid, relname as name, nsp.nspname as schema, pg_get_userbyid(relowner) AS seqowner, description as comment,
+(SELECT array_agg(provider || '=' || label) FROM pg_shseclabel 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 seid %}AND cl.oid = {{seid}}::oid {% endif %}
+ORDER BY relname
+{% endif %}
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/sql/9.1_plus/update.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/sql/9.1_plus/update.sql
new file mode 100644
index 0000000..a1ecd50
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/templates/sequence/sql/9.1_plus/update.sql
@@ -0,0 +1,89 @@
+{% import 'macros/schemas/security.macros' as SECLABLE %}
+{% 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 %}
+{% set seqname = conn|qtIdent(o_data.schema, data.name) %}
+SELECT setval({{ seqname|qtLiteral }}, {{ data.current_value }}, true);
+{% endif %}
+{% set defquery = '' %}
+{% if data.increment %}
+  {% set defquery = defquery+'\n INCREMENT '+data.increment|string %}
+{% endif %}
+{% if data.minimum %}
+  {% set defquery = defquery+'\n MINVALUE '+data.minimum|string %}
+{% endif %}
+{% if data.maximum %}
+  {% set defquery = defquery+'\n MAXVALUE '+data.maximum|string %}
+{% endif %}
+{% if data.cache %}
+  {% 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 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 %}
+{{ SECLABLE.UNSET(conn, 'SEQUENCE', data.name, r.provider, schema) }}
+{% endfor %}
+{% endif %}
+{% if 'added' in seclabels and seclabels.added|length > 0 %}
+{% for r in seclabels.added %}
+{{ SECLABLE.SET(conn, 'SEQUENCE', data.name, r.provider, r.security_label, schema) }}
+{% endfor %}
+{% endif %}
+{% if 'changed' in seclabels and seclabels.changed|length > 0 %}
+{% for r in seclabels.changed %}
+{{ SECLABLE.SET(conn, 'SEQUENCE', data.name, r.provider, r.security_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 %}
\ No newline at end of file
-- 
Sent via pgadmin-hackers mailing list (pgadmin-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgadmin-hackers

Reply via email to