From 6d46dfbfba21c0e15a2f81d3f349db56dff9b2c8 Mon Sep 17 00:00:00 2001 From: Ashesh Vashi Date: Mon, 23 Nov 2015 13:25:37 +0530 Subject: [PATCH] Added new url rules for each node by change NodeView class: - Renamed the URL 'nodes' to 'children', because - we'll return the children for the current node. - Using the URL 'nodes' to fetch all nodes of its type, when not specified the node-id, otherwise regenerate that node info using the node-id (it will be used by the refresh function). - Added the URL 'msql' for fetching modified SQL for the modified objects. - Separated the URL 'deps' (GET/POST methods) to 'dependency' and 'dependent', because - it will be used to fetch the properties of the object, not manipulate it. (as suggested by Dave). This commit includes the changes related to it in the specific nodes. (i.e. server-group, and server). Also, includes a javascript change to ask the user (if they really want to leave the page, and it is not an accidental navigation by keyboard shortcuts). --- web/pgadmin/browser/collection.py | 34 ------ web/pgadmin/browser/server_groups/__init__.py | 39 ++++++- .../browser/server_groups/servers/__init__.py | 100 ++++++++++++++++-- .../browser/templates/browser/js/browser.js | 16 ++- .../templates/browser/js/collection.js | 2 +- .../browser/templates/browser/js/node.js | 5 +- web/pgadmin/browser/utils.py | 48 +++++---- 7 files changed, 173 insertions(+), 71 deletions(-) diff --git a/web/pgadmin/browser/collection.py b/web/pgadmin/browser/collection.py index 26ce45d93..44570caa3 100644 --- a/web/pgadmin/browser/collection.py +++ b/web/pgadmin/browser/collection.py @@ -169,37 +169,3 @@ class CollectionNodeModule(PgAdminModule, PGChildModule): @property def javascripts(self): return [] - - -class CollectionNodeView(PGChildNodeView): - """ - A PostgreSQL Collection node has specific functions needs to address - i.e. - - List the nodes - - Get the list of nodes objects (model) - - This class can be inherited to achieve the diffrent routes for each of the - object types/collections. - - OPERATION | URL | Method - ---------------+------------------------+-------- - List | /coll/[Parent URL]/ | GET - Children Nodes | /node/[Parent URL]/ | GET - - NOTE: - Parent URL can be seen as the path to identify the particular node. - """ - operations = dict({ - }) - operations = dict({ - 'obj': [ - {'get': 'properties', 'delete': 'delete', 'put': 'update'}, - {'get': 'list', 'post': 'create'} - ], - 'nodes': [{'get': 'nodes'}], - 'sql': [{'get': 'sql', 'post': 'modified_sql'}], - 'stats': [{'get': 'statistics'}], - 'deps': [{'get': 'dependencies', 'post': 'dependents'}], - 'module.js': [{}, {}, {'get': 'module_js'}], - 'coll': [{}, {'get': 'collections'}] - }) diff --git a/web/pgadmin/browser/server_groups/__init__.py b/web/pgadmin/browser/server_groups/__init__.py index 7fee85df3..c95416dd0 100644 --- a/web/pgadmin/browser/server_groups/__init__.py +++ b/web/pgadmin/browser/server_groups/__init__.py @@ -77,9 +77,16 @@ class ServerGroupView(NodeView): def list(self): res = [] - for g in blueprint.get_nodes(): - res.append(g) - return make_json_response(result=res) + + for sg in ServerGroup.query.filter_by( + user_id=current_user.id + ): + res.append({ + 'id': sg.id, + 'name': sg.name + }) + + return ajax_response(response=res, status=200) def delete(self, gid): """Delete a server group node in the settings database""" @@ -221,5 +228,31 @@ class ServerGroupView(NodeView): 200, {'Content-Type': 'application/x-javascript'} ) + def nodes(self, gid=None): + """Return a JSON document listing the server groups for the user""" + nodes = [] + + if gid is None: + groups = ServerGroup.query.filter_by(user_id=current_user.id) + else: + groups = ServerGroup.query.filter_by(user_id=current_user.id, + id=gid).first() + + for group in groups: + nodes.append( + self.generate_browser_node( + "%d" % (group.id), + group.name, + "icon-%s" % self.node_type, + True, + self.node_type + ) + ) + + return make_json_response(data=nodes) + + def node(self, gid): + return self.nodes(gid) + ServerGroupView.register_node_view(blueprint) diff --git a/web/pgadmin/browser/server_groups/servers/__init__.py b/web/pgadmin/browser/server_groups/servers/__init__.py index 0abd83a58..56b9c3c20 100644 --- a/web/pgadmin/browser/server_groups/servers/__init__.py +++ b/web/pgadmin/browser/server_groups/servers/__init__.py @@ -103,19 +103,25 @@ class ServerNode(PGChildNodeView): {'get': 'properties', 'delete': 'delete', 'put': 'update'}, {'get': 'list', 'post': 'create'} ], - 'nodes': [{'get': 'nodes'}], - 'sql': [{'get': 'sql', 'post': 'modified_sql'}], + 'nodes': [{'get': 'node'}, {'get': 'nodes'}], + 'sql': [{'get': 'sql'}], + 'msql': [{'get': 'modified_sql'}], 'stats': [{'get': 'statistics'}], - 'deps': [{'get': 'dependencies', 'post': 'dependents'}], + 'dependency': [{'get': 'dependencies'}], + 'dependent': [{'get': 'dependents'}], + 'children': [{'get': 'children'}], 'module.js': [{}, {}, {'get': 'module_js'}], 'connect': [{ 'get': 'connect_status', 'post': 'connect', 'delete': 'disconnect' }] }) - def list(self, gid): + def nodes(self, gid): res = [] - """Return a JSON document listing the server groups for the user""" + """ + Return a JSON document listing the servers under this server group + for the user. + """ servers = Server.query.filter_by(user_id=current_user.id, servergroup_id=gid) @@ -136,12 +142,49 @@ class ServerNode(PGChildNodeView): True, self.node_type, connected=connected, - server_type=manager.server_type if connected else 'PG', + server_type=manager.server_type if connected else 'pg', version=manager.version ) ) return make_json_response(result=res) + def node(self, gid, sid): + """Return a JSON document listing the server groups for the user""" + server = Server.query.filter_by(user_id=current_user.id, + servergroup_id=gid, + id=sid).first() + + if server is None: + return make_json_response( + status=410, + success=0, + errormsg=gettext( + gettext( + "Couldn't find the server with id# %s!" + ).format(sid) + ) + ) + + from pgadmin.utils.driver import get_driver + driver = get_driver(PG_DEFAULT_DRIVER).connection_manager(server.id) + + conn = manager.connection() + connected = conn.connected() + + return make_json_response( + result=self.blueprint.generate_browser_node( + "%d" % (server.id), + server.name, + "icon-server-not-connected" if not connected else + "icon-{0}".format(manager.server_type), + True, + self.node_type, + connected=connected, + server_type=manager.server_type if connected else 'pg', + version=manager.version + ) + ) + def delete(self, gid, sid): """Delete a server node in the settings database.""" servers = Server.query.filter_by(user_id=current_user.id, id=sid) @@ -258,6 +301,47 @@ class ServerNode(PGChildNodeView): } ) + def list(self, gid): + """ + Return list of attributes of all servers. + """ + servers = Server.query.filter_by( + user_id=current_user.id, + servergroup_id=gid) + sg = ServerGroup.query.filter_by( + user_id=current_user.id, + id=gid + ).first() + res = [] + + from pgadmin.utils.driver import get_driver + driver = get_driver(PG_DEFAULT_DRIVER) + + for server in servers: + manager = driver.connection_manager(server.id) + conn = manager.connection() + connected = conn.connected() + + res.append({ + 'id': server.id, + 'name': server.name, + 'host': server.host, + 'port': server.port, + 'db': server.maintenance_db, + 'username': server.username, + 'gid': server.servergroup_id, + 'group-name': sg.name, + 'comment': server.comment, + 'role': server.role, + 'connected': connected, + 'version': manager.ver, + 'server_type': manager.server_type if connected else 'pg' + }) + + return ajax_response( + response=res + ) + def properties(self, gid, sid): """Return list of attributes of a server""" server = Server.query.filter_by( @@ -296,7 +380,7 @@ class ServerNode(PGChildNodeView): 'role': server.role, 'connected': connected, 'version': manager.ver, - 'server_type': manager.server_type if connected else 'PG' + 'server_type': manager.server_type if connected else 'pg' } ) @@ -348,7 +432,7 @@ class ServerNode(PGChildNodeView): True, self.node_type, connected=False, - server_type='PG' # Default server type + server_type='pg' # Default server type ) ) diff --git a/web/pgadmin/browser/templates/browser/js/browser.js b/web/pgadmin/browser/templates/browser/js/browser.js index dbd728096..d8e78a5f5 100644 --- a/web/pgadmin/browser/templates/browser/js/browser.js +++ b/web/pgadmin/browser/templates/browser/js/browser.js @@ -358,7 +358,7 @@ OWNER TO helpdesk;\n'; var d = this.itemData(item); n = obj.Nodes[d._type]; if (n) - settings.url = n.generate_url(item, 'nodes', d, true); + settings.url = n.generate_url(item, 'children', d, true); } } }); @@ -622,5 +622,19 @@ OWNER TO helpdesk;\n'; } }); + window.onbeforeunload = function(ev) { + var e = ev || window.event; + + var msg = '{{ _('Do you really want to leave the page?') }}'; + + // For IE and Firefox prior to version 4 + if (e) { + e.returnValue = msg; + } + + // For Safari + return msg; + }; + return pgAdmin.Browser; }); diff --git a/web/pgadmin/browser/templates/browser/js/collection.js b/web/pgadmin/browser/templates/browser/js/collection.js index 0830eba4d..e22f31619 100644 --- a/web/pgadmin/browser/templates/browser/js/collection.js +++ b/web/pgadmin/browser/templates/browser/js/collection.js @@ -103,7 +103,7 @@ function($, _, S, pgAdmin, Backbone, Alertify, Backform) { * under the collection, and properties of the collection respectively. */ opURL = { - 'nodes': 'obj', 'properties': 'coll' + 'properties': 'obj', 'children': 'nodes' }, ref = '', self = this; diff --git a/web/pgadmin/browser/templates/browser/js/node.js b/web/pgadmin/browser/templates/browser/js/node.js index 173718bfd..214635ef5 100644 --- a/web/pgadmin/browser/templates/browser/js/node.js +++ b/web/pgadmin/browser/templates/browser/js/node.js @@ -803,8 +803,7 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, Backform) { var url = pgAdmin.Browser.URL + '{TYPE}/{REDIRECT}{REF}', opURL = { 'create': 'obj', 'drop': 'obj', 'edit': 'obj', - 'properties': 'obj', 'depends': 'deps', - 'statistics': 'stats', 'nodes': 'nodes' + 'properties': 'obj', 'statistics': 'stats' }, ref = '', self = this; @@ -1357,7 +1356,7 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, Backform) { 'id': d._id, 'priority': idx }; - idx += 1; + idx -= 1; } i = t.hasParent(i) ? t.parent(i) : null; } while (i); diff --git a/web/pgadmin/browser/utils.py b/web/pgadmin/browser/utils.py index addacc141..bd7314d35 100644 --- a/web/pgadmin/browser/utils.py +++ b/web/pgadmin/browser/utils.py @@ -128,24 +128,27 @@ class NodeView(with_metaclass(MethodViewType, View)): This class can be inherited to achieve the diffrent routes for each of the object types/collections. - OPERATION | URL | Method - ---------------+------------------------+-------- - List | /obj/[Parent URL]/ | GET - Properties | /obj/[Parent URL]/id | GET - Create | /obj/[Parent URL]/ | POST - Delete | /obj/[Parent URL]/id | DELETE - Update | /obj/[Parent URL]/id | PUT + OPERATION | URL | HTTP Method | Method + ---------------+-----------------------------+-------------+-------------- + List | /obj/[Parent URL]/ | GET | list + Properties | /obj/[Parent URL]/id | GET | properties + Create | /obj/[Parent URL]/ | POST | create + Delete | /obj/[Parent URL]/id | DELETE | delete + Update | /obj/[Parent URL]/id | PUT | update - SQL (Reversed | /sql/[Parent URL]/id | GET + SQL (Reversed | /sql/[Parent URL]/id | GET | sql Engineering) | - SQL (Modified | /sql/[Parent URL]/id | POST + SQL (Modified | /msql/[Parent URL]/id | GET | modified_sql Properties) | - Statistics | /stats/[Parent URL]/id | GET - Dependencies | /deps/[Parent URL]/id | GET - Dependents | /deps/[Parent URL]/id | POST + Statistics | /stats/[Parent URL]/id | GET | statistics + Dependencies | /dependency/[Parent URL]/id | GET | dependencies + Dependents | /dependent/[Parent URL]/id | GET | dependents - Children Nodes | /nodes/[Parent URL]/id | GET + Nodes | /nodes/[Parent URL]/ | GET | nodes + Current Node | /nodes/[Parent URL]/id | GET | node + + Children | /children/[Parent URL]/id | GET | children NOTE: Parent URL can be seen as the path to identify the particular node. @@ -159,10 +162,13 @@ class NodeView(with_metaclass(MethodViewType, View)): {'get': 'properties', 'delete': 'delete', 'put': 'update'}, {'get': 'list', 'post': 'create'} ], - 'nodes': [{'get': 'nodes'}], - 'sql': [{'get': 'sql', 'post': 'modified_sql'}], + 'nodes': [{'get': 'node'}, {'get': 'nodes'}], + 'sql': [{'get': 'sql'}], + 'msql': [{'get': 'modified_sql'}], 'stats': [{'get': 'statistics'}], - 'deps': [{'get': 'dependencies', 'post': 'dependents'}], + 'dependency': [{'get': 'dependencies'}], + 'dependent': [{'get': 'dependents'}], + 'children': [{'get': 'children'}], 'module.js': [{}, {}, {'get': 'module_js'}] }) @@ -311,19 +317,19 @@ class NodeView(with_metaclass(MethodViewType, View)): 200, {'Content-Type': 'application/x-javascript'} ) - def nodes(self, *args, **kwargs): + def children(self, *args, **kwargs): """Build a list of treeview nodes from the child nodes.""" - nodes = [] + children = [] for module in self.blueprint.submodules: - nodes.extend(module.get_nodes(*args, **kwargs)) + children.extend(module.get_nodes(*args, **kwargs)) - return make_json_response(data=nodes) + return make_json_response(data=children) class PGChildNode(object): - def nodes(self, sid, **kwargs): + def children(self, sid, **kwargs): """Build a list of treeview nodes from the child nodes.""" from pgadmin.utils.driver import get_driver