public inbox for [email protected]  
help / color / mirror / Atom feed
pgAdmin4 - help adding new node to Browser Tree
6+ messages / 2 participants
[nested] [flat]

* pgAdmin4 - help adding new node to Browser Tree
@ 2020-09-02 04:20 Warren Chan <[email protected]>
  2020-09-02 08:18 ` Re: pgAdmin4 - help adding new node to Browser Tree Aditya Toshniwal <[email protected]>
  0 siblings, 1 reply; 6+ messages in thread

From: Warren Chan @ 2020-09-02 04:20 UTC (permalink / raw)
  To: [email protected] <[email protected]>

Hi, 

I'm trying to learn about the pgAdmin4 project and am hoping to make some contributions sometime in the future.
I'm new to Flask and python but am keen to learn.
While trying to familiarize myself with the application and the way it works, I've tried to create a 'test' node under the schema node, I want to list test items under this node - not listing anything particular at the moment but wanted to get an understanding of how the application ties together). In order to just get a new node added under schema, I've copied the sequence folder under \web\pgadmin\browser\server_groups\servers\databases\schemas and renamed the applicable folders to tests (I want a test node to appear under schema).
I've updated the \tests\_init_.py file so that the SequenceModule has been changed to TestModule (updated the NODE_TYPE etc). I've also updated the SequenceView to become TestView and other parts of the view like the template path etc. 

In addition to this I've changed the name in the \tests\static\js\sequence.js file to \tests\static\js\test.js and have also updated the test.js file so that any references to sequence has been changed to test and have added 'pgadmin.node.tests' to the webpack.config.js and 'pgadmin.node.test': path.join(__dirname, './pgadmin/browser/server_groups/servers/databases/schemas/tests/static/js/test') to the webpack.shim.js file
Doing this I was hoping that a new 'Test' node would appear under the schema directory and opening this node, would render all the sequences (as I haven't changed any of the sql). However I only get the new 'Test' node being rendered, and when I open this, I get a Server Node with the server I'm connected to being added, not the list of sequences I was hoping for. 

Is there an additional setting / steps I need to add somewhere in order to get the TestView to render under the TestModule node?

I'd appreciate any pointers to get this working as the next thing I'd like, would be to start modifying the sql and getting different database objects being listed.
Best regards,Warren Chan




^ permalink  raw  reply  [nested|flat] 6+ messages in thread

* Re: pgAdmin4 - help adding new node to Browser Tree
  2020-09-02 04:20 pgAdmin4 - help adding new node to Browser Tree Warren Chan <[email protected]>
@ 2020-09-02 08:18 ` Aditya Toshniwal <[email protected]>
  2020-09-03 02:59   ` Re: pgAdmin4 - help adding new node to Browser Tree Warren Chan <[email protected]>
  0 siblings, 1 reply; 6+ messages in thread

From: Aditya Toshniwal @ 2020-09-02 08:18 UTC (permalink / raw)
  To: Warren Chan <[email protected]>; +Cc: [email protected] <[email protected]>

Hi Warren,

Can you check the browser console if any errors ? Can you also share the
patch so that I can help you further by debugging at my end ?

On Wed, Sep 2, 2020 at 9:51 AM Warren Chan <[email protected]> wrote:

> Hi,
>
> I'm trying to learn about the pgAdmin4 project and am hoping to make some
> contributions sometime in the future.
>
> I'm new to Flask and python but am keen to learn.
>
> While trying to familiarize myself with the application and the way it
> works, I've tried to create a 'test' node under the schema node, I want to
> list test items under this node - not listing anything particular at the
> moment but wanted to get an understanding of how the application ties
> together). In order to just get a new node added under schema, I've
> copied the sequence folder under
> \web\pgadmin\browser\server_groups\servers\databases\schemas and renamed
> the applicable folders to tests (I want a test node to appear under schema).
>
> I've updated the \tests\_init_.py file so that the SequenceModule has been
> changed to TestModule (updated the NODE_TYPE etc). I've also updated the
> SequenceView to become TestView and other parts of the view like the
> template path etc.
>
> In addition to this I've changed the name in the
> \tests\static\js\sequence.js file to \tests\static\js\test.js and have
> also updated the test.js file so that any references to sequence has been
> changed to test and have added 'pgadmin.node.tests' to the
> webpack.config.js and 'pgadmin.node.test': path.join(__dirname,
> './pgadmin/browser/server_groups/servers/databases/schemas/tests/static/js/test')
> to the webpack.shim.js file
>
> Doing this I was hoping that a new 'Test' node would appear under the
> schema directory and opening this node, would render all the sequences (as
> I haven't changed any of the sql). However I only get the new 'Test' node
> being rendered, and when I open this, I get a Server Node with the server
> I'm connected to being added, not the list of sequences I was hoping for.
>
> Is there an additional setting / steps I need to add somewhere in order to
> get the TestView to render under the TestModule node?
>
> I'd appreciate any pointers to get this working as the next thing I'd
> like, would be to start modifying the sql and getting different database
> objects being listed.
>
> Best regards,
> Warren Chan
>
>
>

-- 
Thanks,
Aditya Toshniwal
pgAdmin hacker | Sr. Software Engineer | *edbpostgres.com*
<http://edbpostgres.com;
"Don't Complain about Heat, Plant a TREE"


^ permalink  raw  reply  [nested|flat] 6+ messages in thread

* Re: pgAdmin4 - help adding new node to Browser Tree
  2020-09-02 04:20 pgAdmin4 - help adding new node to Browser Tree Warren Chan <[email protected]>
  2020-09-02 08:18 ` Re: pgAdmin4 - help adding new node to Browser Tree Aditya Toshniwal <[email protected]>
@ 2020-09-03 02:59   ` Warren Chan <[email protected]>
  2020-09-03 04:43     ` Re: pgAdmin4 - help adding new node to Browser Tree Aditya Toshniwal <[email protected]>
  0 siblings, 1 reply; 6+ messages in thread

From: Warren Chan @ 2020-09-03 02:59 UTC (permalink / raw)
  To: Aditya Toshniwal <[email protected]>; +Cc: [email protected] <[email protected]>

 Hi Aditya,
thanks for helping, really appreciate you taking the time.
I've attached a patch as requested and yes, when i expand the new Foo node I've created, I get the following errors in the console:

2020-09-03 12:50:37,291: ERROR  flask.app:      404 Not Found: The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
Traceback (most recent call last):
  File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\app.py", line 1791, in dispatch_request
    self.raise_routing_exception(req)
  File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\app.py", line 1774, in raise_routing_exception
    raise request.routing_exception
  File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\ctx.py", line 336, in match_request
    self.url_adapter.match(return_rule=True)
  File "C:\git\pgadmin4\pgadmin4\lib\site-packages\werkzeug\routing.py", line 1945, in match
    raise NotFound()
werkzeug.exceptions.NotFound: 404 Not Found: The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
2020-09-03 12:50:37,372: ERROR  flask.app:      404 Not Found: The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
Traceback (most recent call last):
  File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\app.py", line 1791, in dispatch_request
    self.raise_routing_exception(req)
  File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\app.py", line 1774, in raise_routing_exception
    raise request.routing_exception
  File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\ctx.py", line 336, in match_request
    self.url_adapter.match(return_rule=True)
  File "C:\git\pgadmin4\pgadmin4\lib\site-packages\werkzeug\routing.py", line 1945, in match
    raise NotFound()
werkzeug.exceptions.NotFound: 404 Not Found: The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
Please let me know if you need anything else.
Best Regards,Warren Chan
   On Wednesday, 2 September 2020, 6:19:59 pm AEST, Aditya Toshniwal <[email protected]> wrote:  
 
 Hi Warren,
Can you check the browser console if any errors ? Can you also share the patch so that I can help you further by debugging at my end ?
On Wed, Sep 2, 2020 at 9:51 AM Warren Chan <[email protected]> wrote:

Hi, 

I'm trying to learn about the pgAdmin4 project and am hoping to make some contributions sometime in the future.
I'm new to Flask and python but am keen to learn.
While trying to familiarize myself with the application and the way it works, I've tried to create a 'test' node under the schema node, I want to list test items under this node - not listing anything particular at the moment but wanted to get an understanding of how the application ties together). In order to just get a new node added under schema, I've copied the sequence folder under \web\pgadmin\browser\server_groups\servers\databases\schemas and renamed the applicable folders to tests (I want a test node to appear under schema).
I've updated the \tests\_init_.py file so that the SequenceModule has been changed to TestModule (updated the NODE_TYPE etc). I've also updated the SequenceView to become TestView and other parts of the view like the template path etc. 

In addition to this I've changed the name in the \tests\static\js\sequence.js file to \tests\static\js\test.js and have also updated the test.js file so that any references to sequence has been changed to test and have added 'pgadmin.node.tests' to the webpack.config.js and 'pgadmin.node.test': path.join(__dirname, './pgadmin/browser/server_groups/servers/databases/schemas/tests/static/js/test') to the webpack.shim.js file
Doing this I was hoping that a new 'Test' node would appear under the schema directory and opening this node, would render all the sequences (as I haven't changed any of the sql). However I only get the new 'Test' node being rendered, and when I open this, I get a Server Node with the server I'm connected to being added, not the list of sequences I was hoping for. 

Is there an additional setting / steps I need to add somewhere in order to get the TestView to render under the TestModule node?

I'd appreciate any pointers to get this working as the next thing I'd like, would be to start modifying the sql and getting different database objects being listed.
Best regards,Warren Chan





-- 
Thanks,Aditya Toshniwal
pgAdmin hacker | Sr. Software Engineer | edbpostgres.com"Don't Complain about Heat, Plant a TREE"  

Attachments:

  [application/octet-stream] newFooNode.patch (131.7K, 3-newFooNode.patch)
  download | inline diff:
From 782ac5288fdbab1fd1f7cdc3e8b93d4c0211a6d8 Mon Sep 17 00:00:00 2001
From: Warren Chan <[email protected]>
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 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{font-size:8px;fill:#7749bd;font-family:Helvetica-Bold, Helvetica;font-weight:700;}</style></defs><title>coll-sequence</title><g id="_2" data-name="2"><text class="cls-1" transform="translate(1.4 10.79)">1</text><text class="cls-1" transform="translate(9.87 10.79)">3</text><text class="cls-1" transform="translate(5.23 10.79)">..</text></g></svg>
\ 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 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{font-size:8px;fill:#7749bd;font-family:Helvetica-Bold, Helvetica;font-weight:700;}</style></defs><title>sequence</title><g id="_2" data-name="2"><text class="cls-1" transform="translate(1.4 10.83)">1</text><text class="cls-1" transform="translate(9.87 10.83)">3</text><text class="cls-1" transform="translate(5.23 10.83)">..</text></g></svg>
\ 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



^ permalink  raw  reply  [nested|flat] 6+ messages in thread

* Re: pgAdmin4 - help adding new node to Browser Tree
  2020-09-02 04:20 pgAdmin4 - help adding new node to Browser Tree Warren Chan <[email protected]>
  2020-09-02 08:18 ` Re: pgAdmin4 - help adding new node to Browser Tree Aditya Toshniwal <[email protected]>
  2020-09-03 02:59   ` Re: pgAdmin4 - help adding new node to Browser Tree Warren Chan <[email protected]>
@ 2020-09-03 04:43     ` Aditya Toshniwal <[email protected]>
  2020-09-03 05:44       ` Re: pgAdmin4 - help adding new node to Browser Tree Warren Chan <[email protected]>
  0 siblings, 1 reply; 6+ messages in thread

From: Aditya Toshniwal @ 2020-09-03 04:43 UTC (permalink / raw)
  To: Warren Chan <[email protected]>; +Cc: [email protected] <[email protected]>

Hi Warren,

The patch works fine, just that replacing sequences with foos was missing
at 1-2 places. I guess you've not restarted the dev server after the
changes. :)
- Always restart the backend dev server if there is any change in Python or
any template files.
- You can run webpack in continuous watch mode with yarn run bundle:dev
--watch. Always empty cache reload if there is any change in JS files. You
can enable chrome dev tools and right click on the refresh button to get
the option.

Here's what I've changed in your patch:

*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*

*index 3bc310d6f..52de71f0b 100644*

*---
a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/__init__.py*

*+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/__init__.py*

@@ -141,7 +141,7 @@ class FooView(PGChildNodeView, SchemaDiffObjectCompare):

                     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.template_path = 'foos/sql/#{0}#'.format(

                     self.manager.version

                 )

                 self.acl = ['r', 'w', 'U']

*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*

*index cd9b0154a..91a2f9259 100644*

*---
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*

@@ -4,4 +4,4 @@ SELECT

 FROM

     pg_statio_all_sequences

 WHERE

-    relid = {{ seid }}::OID

\ No newline at end of file

+    relid = {{ fooid }}::OID


On Thu, Sep 3, 2020 at 8:29 AM Warren Chan <[email protected]> wrote:

> Hi Aditya,
>
> thanks for helping, really appreciate you taking the time.
>
> I've attached a patch as requested and yes, when i expand the new Foo node
> I've created, I get the following errors in the console:
>
> 2020-09-03 12:50:37,291: ERROR  flask.app:      404 Not Found: The
> requested URL was not found on the server. If you entered the URL manually
> please check your spelling and try again.
> Traceback (most recent call last):
>   File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\app.py", line
> 1813, in full_dispatch_request
>     rv = self.dispatch_request()
>   File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\app.py", line
> 1791, in dispatch_request
>     self.raise_routing_exception(req)
>   File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\app.py", line
> 1774, in raise_routing_exception
>     raise request.routing_exception
>   File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\ctx.py", line
> 336, in match_request
>     self.url_adapter.match(return_rule=True)
>   File "C:\git\pgadmin4\pgadmin4\lib\site-packages\werkzeug\routing.py",
> line 1945, in match
>     raise NotFound()
> werkzeug.exceptions.NotFound: 404 Not Found: The requested URL was not
> found on the server. If you entered the URL manually please check your
> spelling and try again.
> 2020-09-03 12:50:37,372: ERROR  flask.app:      404 Not Found: The
> requested URL was not found on the server. If you entered the URL manually
> please check your spelling and try again.
> Traceback (most recent call last):
>   File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\app.py", line
> 1813, in full_dispatch_request
>     rv = self.dispatch_request()
>   File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\app.py", line
> 1791, in dispatch_request
>     self.raise_routing_exception(req)
>   File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\app.py", line
> 1774, in raise_routing_exception
>     raise request.routing_exception
>   File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\ctx.py", line
> 336, in match_request
>     self.url_adapter.match(return_rule=True)
>   File "C:\git\pgadmin4\pgadmin4\lib\site-packages\werkzeug\routing.py",
> line 1945, in match
>     raise NotFound()
> werkzeug.exceptions.NotFound: 404 Not Found: The requested URL was not
> found on the server. If you entered the URL manually please check your
> spelling and try again.
>
> Please let me know if you need anything else.
>
> Best Regards,
> Warren Chan
> On Wednesday, 2 September 2020, 6:19:59 pm AEST, Aditya Toshniwal <
> [email protected]> wrote:
>
>
> Hi Warren,
>
> Can you check the browser console if any errors ? Can you also share the
> patch so that I can help you further by debugging at my end ?
>
> On Wed, Sep 2, 2020 at 9:51 AM Warren Chan <[email protected]> wrote:
>
> Hi,
>
> I'm trying to learn about the pgAdmin4 project and am hoping to make some
> contributions sometime in the future.
>
> I'm new to Flask and python but am keen to learn.
>
> While trying to familiarize myself with the application and the way it
> works, I've tried to create a 'test' node under the schema node, I want to
> list test items under this node - not listing anything particular at the
> moment but wanted to get an understanding of how the application ties
> together). In order to just get a new node added under schema, I've
> copied the sequence folder under
> \web\pgadmin\browser\server_groups\servers\databases\schemas and renamed
> the applicable folders to tests (I want a test node to appear under schema).
>
> I've updated the \tests\_init_.py file so that the SequenceModule has been
> changed to TestModule (updated the NODE_TYPE etc). I've also updated the
> SequenceView to become TestView and other parts of the view like the
> template path etc.
>
> In addition to this I've changed the name in the
> \tests\static\js\sequence.js file to \tests\static\js\test.js and have
> also updated the test.js file so that any references to sequence has been
> changed to test and have added 'pgadmin.node.tests' to the
> webpack.config.js and 'pgadmin.node.test': path.join(__dirname,
> './pgadmin/browser/server_groups/servers/databases/schemas/tests/static/js/test')
> to the webpack.shim.js file
>
> Doing this I was hoping that a new 'Test' node would appear under the
> schema directory and opening this node, would render all the sequences (as
> I haven't changed any of the sql). However I only get the new 'Test' node
> being rendered, and when I open this, I get a Server Node with the server
> I'm connected to being added, not the list of sequences I was hoping for.
>
> Is there an additional setting / steps I need to add somewhere in order to
> get the TestView to render under the TestModule node?
>
> I'd appreciate any pointers to get this working as the next thing I'd
> like, would be to start modifying the sql and getting different database
> objects being listed.
>
> Best regards,
> Warren Chan
>
>
>
>
> --
> Thanks,
> Aditya Toshniwal
> pgAdmin hacker | Sr. Software Engineer | *edbpostgres.com*
> <http://edbpostgres.com;
> "Don't Complain about Heat, Plant a TREE"
>


-- 
Thanks,
Aditya Toshniwal
pgAdmin hacker | Sr. Software Engineer | *edbpostgres.com*
<http://edbpostgres.com;
"Don't Complain about Heat, Plant a TREE"


^ permalink  raw  reply  [nested|flat] 6+ messages in thread

* Re: pgAdmin4 - help adding new node to Browser Tree
  2020-09-02 04:20 pgAdmin4 - help adding new node to Browser Tree Warren Chan <[email protected]>
  2020-09-02 08:18 ` Re: pgAdmin4 - help adding new node to Browser Tree Aditya Toshniwal <[email protected]>
  2020-09-03 02:59   ` Re: pgAdmin4 - help adding new node to Browser Tree Warren Chan <[email protected]>
  2020-09-03 04:43     ` Re: pgAdmin4 - help adding new node to Browser Tree Aditya Toshniwal <[email protected]>
@ 2020-09-03 05:44       ` Warren Chan <[email protected]>
  2020-09-03 06:02         ` Re: pgAdmin4 - help adding new node to Browser Tree Aditya Toshniwal <[email protected]>
  0 siblings, 1 reply; 6+ messages in thread

From: Warren Chan @ 2020-09-03 05:44 UTC (permalink / raw)
  To: Aditya Toshniwal <[email protected]>; +Cc: [email protected] <[email protected]>

 Hi Aditya,
thats it, I wasn't running yarn bundle after my modifications to the templates. Thanks for tip to run webpack in continuous mode, that's great.

Really appreciate the help in getting past this. 

Best Regards,Warren Chan

    On Thursday, 3 September 2020, 2:43:56 pm AEST, Aditya Toshniwal <[email protected]> wrote:  
 
 Hi Warren,
The patch works fine, just that replacing sequences with foos was missing at 1-2 places. I guess you've not restarted the dev server after the changes. :)- Always restart the backend dev server if there is any change in Python or any template files.- You can run webpack in continuous watch mode with yarn run bundle:dev --watch. Always empty cache reload if there is any change in JS files. You can enable chrome dev tools and right click on the refresh button to get the option.
Here's what I've changed in your patch:
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

index 3bc310d6f..52de71f0b 100644

--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/__init__.py

+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/__init__.py

@@ -141,7 +141,7 @@ class FooView(PGChildNodeView, SchemaDiffObjectCompare):

                     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.template_path = 'foos/sql/#{0}#'.format(

                     self.manager.version

                 )

                 self.acl = ['r', 'w', 'U']

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

index cd9b0154a..91a2f9259 100644

--- 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

@@ -4,4 +4,4 @@ SELECT

 FROM

     pg_statio_all_sequences

 WHERE

-    relid = {{ seid }}::OID

\ No newline at end of file

+    relid = {{ fooid }}::OID


On Thu, Sep 3, 2020 at 8:29 AM Warren Chan <[email protected]> wrote:

 Hi Aditya,
thanks for helping, really appreciate you taking the time.
I've attached a patch as requested and yes, when i expand the new Foo node I've created, I get the following errors in the console:

2020-09-03 12:50:37,291: ERROR  flask.app:      404 Not Found: The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
Traceback (most recent call last):
  File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\app.py", line 1791, in dispatch_request
    self.raise_routing_exception(req)
  File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\app.py", line 1774, in raise_routing_exception
    raise request.routing_exception
  File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\ctx.py", line 336, in match_request
    self.url_adapter.match(return_rule=True)
  File "C:\git\pgadmin4\pgadmin4\lib\site-packages\werkzeug\routing.py", line 1945, in match
    raise NotFound()
werkzeug.exceptions.NotFound: 404 Not Found: The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
2020-09-03 12:50:37,372: ERROR  flask.app:      404 Not Found: The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
Traceback (most recent call last):
  File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\app.py", line 1791, in dispatch_request
    self.raise_routing_exception(req)
  File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\app.py", line 1774, in raise_routing_exception
    raise request.routing_exception
  File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\ctx.py", line 336, in match_request
    self.url_adapter.match(return_rule=True)
  File "C:\git\pgadmin4\pgadmin4\lib\site-packages\werkzeug\routing.py", line 1945, in match
    raise NotFound()
werkzeug.exceptions.NotFound: 404 Not Found: The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
Please let me know if you need anything else.
Best Regards,Warren Chan
   On Wednesday, 2 September 2020, 6:19:59 pm AEST, Aditya Toshniwal <[email protected]> wrote:  
 
 Hi Warren,
Can you check the browser console if any errors ? Can you also share the patch so that I can help you further by debugging at my end ?
On Wed, Sep 2, 2020 at 9:51 AM Warren Chan <[email protected]> wrote:

Hi, 

I'm trying to learn about the pgAdmin4 project and am hoping to make some contributions sometime in the future.
I'm new to Flask and python but am keen to learn.
While trying to familiarize myself with the application and the way it works, I've tried to create a 'test' node under the schema node, I want to list test items under this node - not listing anything particular at the moment but wanted to get an understanding of how the application ties together). In order to just get a new node added under schema, I've copied the sequence folder under \web\pgadmin\browser\server_groups\servers\databases\schemas and renamed the applicable folders to tests (I want a test node to appear under schema).
I've updated the \tests\_init_.py file so that the SequenceModule has been changed to TestModule (updated the NODE_TYPE etc). I've also updated the SequenceView to become TestView and other parts of the view like the template path etc. 

In addition to this I've changed the name in the \tests\static\js\sequence.js file to \tests\static\js\test.js and have also updated the test.js file so that any references to sequence has been changed to test and have added 'pgadmin.node.tests' to the webpack.config.js and 'pgadmin.node.test': path.join(__dirname, './pgadmin/browser/server_groups/servers/databases/schemas/tests/static/js/test') to the webpack.shim.js file
Doing this I was hoping that a new 'Test' node would appear under the schema directory and opening this node, would render all the sequences (as I haven't changed any of the sql). However I only get the new 'Test' node being rendered, and when I open this, I get a Server Node with the server I'm connected to being added, not the list of sequences I was hoping for. 

Is there an additional setting / steps I need to add somewhere in order to get the TestView to render under the TestModule node?

I'd appreciate any pointers to get this working as the next thing I'd like, would be to start modifying the sql and getting different database objects being listed.
Best regards,Warren Chan





-- 
Thanks,Aditya Toshniwal
pgAdmin hacker | Sr. Software Engineer | edbpostgres.com"Don't Complain about Heat, Plant a TREE"  


-- 
Thanks,Aditya Toshniwal
pgAdmin hacker | Sr. Software Engineer | edbpostgres.com"Don't Complain about Heat, Plant a TREE"  

^ permalink  raw  reply  [nested|flat] 6+ messages in thread

* Re: pgAdmin4 - help adding new node to Browser Tree
  2020-09-02 04:20 pgAdmin4 - help adding new node to Browser Tree Warren Chan <[email protected]>
  2020-09-02 08:18 ` Re: pgAdmin4 - help adding new node to Browser Tree Aditya Toshniwal <[email protected]>
  2020-09-03 02:59   ` Re: pgAdmin4 - help adding new node to Browser Tree Warren Chan <[email protected]>
  2020-09-03 04:43     ` Re: pgAdmin4 - help adding new node to Browser Tree Aditya Toshniwal <[email protected]>
  2020-09-03 05:44       ` Re: pgAdmin4 - help adding new node to Browser Tree Warren Chan <[email protected]>
@ 2020-09-03 06:02         ` Aditya Toshniwal <[email protected]>
  0 siblings, 0 replies; 6+ messages in thread

From: Aditya Toshniwal @ 2020-09-03 06:02 UTC (permalink / raw)
  To: Warren Chan <[email protected]>; +Cc: [email protected] <[email protected]>

Hi Warren,

On Thu, Sep 3, 2020 at 11:14 AM Warren Chan <[email protected]> wrote:

> Hi Aditya,
>
> thats it, I wasn't running yarn bundle after my modifications to the
> templates. Thanks for tip to run webpack in continuous mode, that's great.
>
You need to restart the backend server if you change the templates. yarn
bundle is needed when JS files are changed.
Glad it worked :)

>
> Really appreciate the help in getting past this.
>
> Best Regards,
> Warren Chan
>
> On Thursday, 3 September 2020, 2:43:56 pm AEST, Aditya Toshniwal <
> [email protected]> wrote:
>
>
> Hi Warren,
>
> The patch works fine, just that replacing sequences with foos was missing
> at 1-2 places. I guess you've not restarted the dev server after the
> changes. :)
> - Always restart the backend dev server if there is any change in Python
> or any template files.
> - You can run webpack in continuous watch mode with yarn run bundle:dev
> --watch. Always empty cache reload if there is any change in JS files. You
> can enable chrome dev tools and right click on the refresh button to get
> the option.
>
> Here's what I've changed in your patch:
>
> *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*
>
> *index 3bc310d6f..52de71f0b 100644*
>
> *---
> a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/__init__.py*
>
> *+++
> b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/__init__.py*
>
> @@ -141,7 +141,7 @@ class FooView(PGChildNodeView,
> SchemaDiffObjectCompare):
>
>                      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.template_path = 'foos/sql/#{0}#'.format(
>
>                      self.manager.version
>
>                  )
>
>                  self.acl = ['r', 'w', 'U']
>
> *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*
>
> *index cd9b0154a..91a2f9259 100644*
>
> *---
> 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*
>
> @@ -4,4 +4,4 @@ SELECT
>
>  FROM
>
>      pg_statio_all_sequences
>
>  WHERE
>
> -    relid = {{ seid }}::OID
>
> \ No newline at end of file
>
> +    relid = {{ fooid }}::OID
>
>
> On Thu, Sep 3, 2020 at 8:29 AM Warren Chan <[email protected]> wrote:
>
> Hi Aditya,
>
> thanks for helping, really appreciate you taking the time.
>
> I've attached a patch as requested and yes, when i expand the new Foo node
> I've created, I get the following errors in the console:
>
> 2020-09-03 12:50:37,291: ERROR  flask.app:      404 Not Found: The
> requested URL was not found on the server. If you entered the URL manually
> please check your spelling and try again.
> Traceback (most recent call last):
>   File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\app.py", line
> 1813, in full_dispatch_request
>     rv = self.dispatch_request()
>   File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\app.py", line
> 1791, in dispatch_request
>     self.raise_routing_exception(req)
>   File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\app.py", line
> 1774, in raise_routing_exception
>     raise request.routing_exception
>   File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\ctx.py", line
> 336, in match_request
>     self.url_adapter.match(return_rule=True)
>   File "C:\git\pgadmin4\pgadmin4\lib\site-packages\werkzeug\routing.py",
> line 1945, in match
>     raise NotFound()
> werkzeug.exceptions.NotFound: 404 Not Found: The requested URL was not
> found on the server. If you entered the URL manually please check your
> spelling and try again.
> 2020-09-03 12:50:37,372: ERROR  flask.app:      404 Not Found: The
> requested URL was not found on the server. If you entered the URL manually
> please check your spelling and try again.
> Traceback (most recent call last):
>   File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\app.py", line
> 1813, in full_dispatch_request
>     rv = self.dispatch_request()
>   File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\app.py", line
> 1791, in dispatch_request
>     self.raise_routing_exception(req)
>   File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\app.py", line
> 1774, in raise_routing_exception
>     raise request.routing_exception
>   File "C:\git\pgadmin4\pgadmin4\lib\site-packages\flask\ctx.py", line
> 336, in match_request
>     self.url_adapter.match(return_rule=True)
>   File "C:\git\pgadmin4\pgadmin4\lib\site-packages\werkzeug\routing.py",
> line 1945, in match
>     raise NotFound()
> werkzeug.exceptions.NotFound: 404 Not Found: The requested URL was not
> found on the server. If you entered the URL manually please check your
> spelling and try again.
>
> Please let me know if you need anything else.
>
> Best Regards,
> Warren Chan
> On Wednesday, 2 September 2020, 6:19:59 pm AEST, Aditya Toshniwal <
> [email protected]> wrote:
>
>
> Hi Warren,
>
> Can you check the browser console if any errors ? Can you also share the
> patch so that I can help you further by debugging at my end ?
>
> On Wed, Sep 2, 2020 at 9:51 AM Warren Chan <[email protected]> wrote:
>
> Hi,
>
> I'm trying to learn about the pgAdmin4 project and am hoping to make some
> contributions sometime in the future.
>
> I'm new to Flask and python but am keen to learn.
>
> While trying to familiarize myself with the application and the way it
> works, I've tried to create a 'test' node under the schema node, I want to
> list test items under this node - not listing anything particular at the
> moment but wanted to get an understanding of how the application ties
> together). In order to just get a new node added under schema, I've
> copied the sequence folder under
> \web\pgadmin\browser\server_groups\servers\databases\schemas and renamed
> the applicable folders to tests (I want a test node to appear under schema).
>
> I've updated the \tests\_init_.py file so that the SequenceModule has been
> changed to TestModule (updated the NODE_TYPE etc). I've also updated the
> SequenceView to become TestView and other parts of the view like the
> template path etc.
>
> In addition to this I've changed the name in the
> \tests\static\js\sequence.js file to \tests\static\js\test.js and have
> also updated the test.js file so that any references to sequence has been
> changed to test and have added 'pgadmin.node.tests' to the
> webpack.config.js and 'pgadmin.node.test': path.join(__dirname,
> './pgadmin/browser/server_groups/servers/databases/schemas/tests/static/js/test')
> to the webpack.shim.js file
>
> Doing this I was hoping that a new 'Test' node would appear under the
> schema directory and opening this node, would render all the sequences (as
> I haven't changed any of the sql). However I only get the new 'Test' node
> being rendered, and when I open this, I get a Server Node with the server
> I'm connected to being added, not the list of sequences I was hoping for.
>
> Is there an additional setting / steps I need to add somewhere in order to
> get the TestView to render under the TestModule node?
>
> I'd appreciate any pointers to get this working as the next thing I'd
> like, would be to start modifying the sql and getting different database
> objects being listed.
>
> Best regards,
> Warren Chan
>
>
>
>
> --
> Thanks,
> Aditya Toshniwal
> pgAdmin hacker | Sr. Software Engineer | *edbpostgres.com*
> <http://edbpostgres.com;
> "Don't Complain about Heat, Plant a TREE"
>
>
>
> --
> Thanks,
> Aditya Toshniwal
> pgAdmin hacker | Sr. Software Engineer | *edbpostgres.com*
> <http://edbpostgres.com;
> "Don't Complain about Heat, Plant a TREE"
>


-- 
Thanks,
Aditya Toshniwal
pgAdmin hacker | Sr. Software Engineer | *edbpostgres.com*
<http://edbpostgres.com;
"Don't Complain about Heat, Plant a TREE"


^ permalink  raw  reply  [nested|flat] 6+ messages in thread


end of thread, other threads:[~2020-09-03 06:02 UTC | newest]

Thread overview: 6+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2020-09-02 04:20 pgAdmin4 - help adding new node to Browser Tree Warren Chan <[email protected]>
2020-09-02 08:18 ` Aditya Toshniwal <[email protected]>
2020-09-03 02:59   ` Warren Chan <[email protected]>
2020-09-03 04:43     ` Aditya Toshniwal <[email protected]>
2020-09-03 05:44       ` Warren Chan <[email protected]>
2020-09-03 06:02         ` Aditya Toshniwal <[email protected]>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox