mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2024-11-30 12:33:52 -06:00
35d01bea3e
PostgreSQL node(s). Browser Tree Node (PostgreSQL object) requires more than just CRUD. i.e. - CRUD (Create, Read, Update & Delete) - Reversed Engineered SQL for the object - Modified Query in edit mode i.e. ALTER TABLE ... - Statistics - List of dependents - List of dependencies - Children node list This class can be inherited to achieve the different 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 SQL (Reversed | /sql/[Parent URL]/id | GET Engineering) | SQL (Modified | /sql/[Parent URL]/id | POST Properties) | Statistics | /stats/[Parent URL]/id | GET Dependencies | /deps/[Parent URL]/id | GET Dependents | /deps/[Parent URL]/id | POST Children Nodes | /nodes/[Parent URL]/id | GET NOTE: Parent URL can be seen as the path to identify the particular node. i.e. In order to identify the TABLE object, we requires information about the server -> database -> schema objects. Hence, the Parent URL for the TABLE object will be something like this as below: <int:sid>/<str:database>/<str:schema> Inherited a new classes ServerGroupView and ServerView, which are inherited from the NodeView for the implementation of above operations.
165 lines
5.4 KiB
Python
165 lines
5.4 KiB
Python
##########################################################################
|
|
#
|
|
# pgAdmin 4 - PostgreSQL Tools
|
|
#
|
|
# Copyright (C) 2013 - 2015, The pgAdmin Development Team
|
|
# This software is released under the PostgreSQL Licence
|
|
#
|
|
##########################################################################
|
|
from abc import ABCMeta, abstractmethod, abstractproperty
|
|
from pgadmin import current_blueprint
|
|
from pgadmin.utils import PgAdminModule
|
|
from pgadmin.utils.ajax import make_json_response
|
|
from pgadmin.settings import get_setting
|
|
from flask import current_app, render_template, url_for, make_response
|
|
from flask.ext.security import login_required
|
|
from flask.ext.login import current_user
|
|
from flaskext.gravatar import Gravatar
|
|
|
|
MODULE_NAME = 'browser'
|
|
|
|
class BrowserModule(PgAdminModule):
|
|
|
|
|
|
def get_own_stylesheets(self):
|
|
stylesheets = []
|
|
# Add browser stylesheets
|
|
for (endpoint, filename) in [
|
|
('static', 'css/codemirror/codemirror.css'),
|
|
('static', 'css/jQuery-contextMenu/jquery.contextMenu.css'),
|
|
('static', 'css/wcDocker/wcDockerSkeleton.css' if \
|
|
current_app.debug else \
|
|
'css/wcDocker/wcDockerSkeleton.min.css'),
|
|
('static', 'css/wcDocker/theme.css'),
|
|
('browser.static', 'css/aciTree/css/aciTree.css'),
|
|
]:
|
|
stylesheets.append(url_for(endpoint, filename=filename))
|
|
stylesheets.append(url_for('browser.browser_css'))
|
|
return stylesheets
|
|
|
|
|
|
def get_own_javascripts(self):
|
|
scripts = []
|
|
for (endpoint, filename) in [
|
|
('static', 'js/codemirror/codemirror.js'),
|
|
('static', 'js/codemirror/mode/sql.js'),
|
|
('static', 'js/jQuery-contextMenu/jquery.ui.position.js'),
|
|
('static', 'js/jQuery-contextMenu/jquery.contextMenu.js'),
|
|
('browser.static', 'js/aciTree/jquery.aciPlugin.min.js'),
|
|
('browser.static', 'js/aciTree/jquery.aciTree.dom.js'),
|
|
('browser.static', 'js/aciTree/jquery.aciTree.min.js')]:
|
|
scripts.append(url_for(endpoint, filename=filename))
|
|
scripts.append(url_for('browser.browser_js'))
|
|
if current_app.debug:
|
|
scripts.append(url_for(
|
|
'static',
|
|
filename='js/wcDocker/wcDocker.js'))
|
|
else:
|
|
scripts.append(url_for(
|
|
'static',
|
|
filename='js/wcDocker/wcDocker.min.js'))
|
|
return scripts
|
|
|
|
|
|
blueprint = BrowserModule(MODULE_NAME, __name__)
|
|
|
|
class BrowserPluginModule(PgAdminModule):
|
|
"""
|
|
Base class for browser submodules.
|
|
"""
|
|
|
|
__metaclass__ = ABCMeta
|
|
|
|
def __init__(self, import_name, **kwargs):
|
|
kwargs.setdefault("url_prefix", self.node_path)
|
|
kwargs.setdefault("static_url_path", 'static')
|
|
super(BrowserPluginModule, self).__init__("NODE-%s" % self.node_type,
|
|
import_name,
|
|
**kwargs)
|
|
|
|
|
|
@property
|
|
@abstractmethod
|
|
def jssnippets(self):
|
|
"""
|
|
Returns a snippet of javascript to include in the page
|
|
"""
|
|
# TODO: move those methods to BrowserModule subclass ?
|
|
return []
|
|
|
|
@property
|
|
def csssnippets(self):
|
|
"""
|
|
Returns a snippet of css to include in the page
|
|
"""
|
|
# TODO: move those methods to BrowserModule subclass ?
|
|
return [render_template("browser/css/node.css",
|
|
node_type=self.node_type)]
|
|
|
|
@abstractmethod
|
|
def get_nodes(self):
|
|
"""
|
|
Each browser module is responsible for fetching
|
|
its own tree subnodes.
|
|
"""
|
|
return []
|
|
|
|
@abstractproperty
|
|
def node_type(self):
|
|
pass
|
|
|
|
@property
|
|
def node_path(self):
|
|
return '/browser/nodes/' + self.node_type
|
|
|
|
|
|
@blueprint.route("/")
|
|
@login_required
|
|
def index():
|
|
"""Render and process the main browser window."""
|
|
# Get the Gravatar
|
|
gravatar = Gravatar(current_app,
|
|
size=100,
|
|
rating='g',
|
|
default='retro',
|
|
force_default=False,
|
|
use_ssl=False,
|
|
base_url=None)
|
|
return render_template(MODULE_NAME + "/index.html",
|
|
username=current_user.email)
|
|
|
|
@blueprint.route("/browser.js")
|
|
@login_required
|
|
def browser_js():
|
|
layout = get_setting('Browser/Layout', default='')
|
|
snippets = []
|
|
for submodule in current_blueprint.submodules:
|
|
snippets.extend(submodule.jssnippets)
|
|
return make_response(
|
|
render_template(
|
|
'browser/js/browser.js',
|
|
layout=layout,
|
|
jssnippets=snippets),
|
|
200, {'Content-Type': 'application/x-javascript'})
|
|
|
|
@blueprint.route("/browser.css")
|
|
@login_required
|
|
def browser_css():
|
|
"""Render and return CSS snippets from the nodes and modules."""
|
|
snippets = []
|
|
for submodule in current_blueprint.submodules:
|
|
snippets.extend(submodule.csssnippets)
|
|
return make_response(
|
|
render_template('browser/css/browser.css', snippets=snippets),
|
|
200, {'Content-Type': 'text/css'})
|
|
|
|
|
|
@blueprint.route("/nodes/")
|
|
@login_required
|
|
def get_nodes():
|
|
"""Build a list of treeview nodes from the child nodes."""
|
|
nodes = []
|
|
for submodule in current_blueprint.submodules:
|
|
nodes.extend(submodule.get_nodes())
|
|
return make_json_response(data=nodes)
|