codekingpro/portable-devtools
114k
1##########################################################################2#3# pgAdmin 4 - PostgreSQL Tools4#5# Copyright (C) 2013 - 2024, The pgAdmin Development Team6# This software is released under the PostgreSQL Licence7#8##########################################################################9 10from abc import ABCMeta, abstractmethod11 12from flask import render_template13from flask_babel import gettext14from pgadmin.browser import BrowserPluginModule15from pgadmin.browser.utils import PGChildModule16from pgadmin.utils import PgAdminModule17from pgadmin.utils.preferences import Preferences18from pgadmin.utils.constants import PGADMIN_NODE19from pgadmin.utils.driver import get_driver20from config import PG_DEFAULT_DRIVER21from pgadmin.browser.utils import PGChildNodeView22 23 24class CollectionNodeModule(PgAdminModule, PGChildModule, metaclass=ABCMeta):25 """26 Base class for collection node submodules.27 """28 browser_url_prefix = BrowserPluginModule.browser_url_prefix29 SHOW_ON_BROWSER = True30 31 _BROWSER_CSS_PATH = 'browser/css'32 33 _NODE_CSS = "/".join([_BROWSER_CSS_PATH, 'node.css'])34 _COLLECTION_CSS = "/".join([_BROWSER_CSS_PATH, 'collection.css'])35 36 def __init__(self, import_name, **kwargs):37 kwargs.setdefault("url_prefix", self.node_path)38 kwargs.setdefault("static_url_path", '/static')39 40 PgAdminModule.__init__(41 self,42 "NODE-%s" % self.node_type,43 import_name,44 **kwargs45 )46 PGChildModule.__init__(self)47 48 @property49 def jssnippets(self):50 """51 Returns a snippet of javascript to include in the page52 """53 return []54 55 @property56 def module_use_template_javascript(self):57 """58 Returns whether Jinja2 template is used for generating the javascript59 module.60 """61 return True62 63 def generate_browser_node(64 self, node_id, parent_id, label, icon, **kwargs65 ):66 obj = {67 "id": "%s_%s" % (self.node_type, node_id),68 "label": label,69 "icon": self.node_icon if not icon else icon,70 "inode": self.node_inode71 if 'inode' not in kwargs72 else kwargs['inode'],73 "_type": self.node_type,74 "_id": node_id,75 "_pid": parent_id,76 "module": PGADMIN_NODE % self.node_type77 }78 for key in kwargs:79 obj.setdefault(key, kwargs[key])80 return obj81 82 def generate_browser_collection_node(self, parent_id, **kwargs):83 obj = {84 "id": "coll-%s_%d" % (self.node_type, parent_id),85 "label": self.collection_label,86 "icon": self.collection_icon,87 "inode": True,88 "_type": 'coll-%s' % (self.node_type),89 "_id": parent_id,90 "_pid": parent_id,91 "module": PGADMIN_NODE % self.node_type,92 "nodes": [self.node_type]93 }94 95 for key in kwargs:96 obj.setdefault(key, kwargs[key])97 98 return obj99 100 def has_nodes(self, sid, did, scid=None, tid=None, vid=None,101 base_template_path=''):102 if self.pref_show_empty_coll_nodes.get():103 return True104 105 try:106 driver = get_driver(PG_DEFAULT_DRIVER)107 manager = driver.connection_manager(sid)108 conn = manager.connection(did=did)109 if '{1}' in base_template_path:110 template_base_path = base_template_path.format(111 manager.server_type, manager.version)112 else:113 template_base_path = base_template_path.format(manager.version)114 115 last_system_oid = 0 if self.show_system_objects else \116 PGChildNodeView._DATABASE_LAST_SYSTEM_OID117 118 sql = render_template(119 "/".join([template_base_path, PGChildNodeView._COUNT_SQL]),120 did=did,121 scid=scid,122 tid=tid,123 vid=vid,124 datlastsysoid=last_system_oid,125 showsysobj=self.show_system_objects,126 conn=conn127 )128 129 status, res = conn.execute_dict(sql)130 131 return int(res['rows'][0]['count']) > 0 if status \132 else True133 except Exception as _:134 return True135 136 @property137 def node_type(self):138 return '%s' % (self._NODE_TYPE)139 140 @property141 def csssnippets(self):142 """143 Returns a snippet of css to include in the page144 """145 snippets = [146 render_template(147 self._COLLECTION_CSS,148 node_type=self.node_type149 ),150 render_template(151 self._NODE_CSS,152 node_type=self.node_type,153 _=gettext154 )155 ]156 157 for submodule in self.submodules:158 snippets.extend(submodule.csssnippets)159 160 return snippets161 162 @property163 def collection_label(self):164 """165 Label to be shown for the collection node, do not forget to set the166 class level variable _COLLECTION_LABEL.167 """168 return gettext(self._COLLECTION_LABEL)169 170 @property171 def label(self):172 return gettext(self._COLLECTION_LABEL)173 174 @property175 def collection_icon(self):176 """177 icon to be displayed for the browser collection node178 """179 return 'icon-coll-%s' % (self.node_type)180 181 @property182 def node_icon(self):183 """184 icon to be displayed for the browser nodes185 """186 return 'icon-%s' % (self.node_type)187 188 @property189 def node_inode(self):190 """191 Override this property to make the node as leaf node.192 """193 return True194 195 @abstractmethod196 def get_nodes(self, sid, *args, **kwargs):197 """198 Generate the collection node199 You need to override this method because every node will have different200 url pattern for the parent.201 """202 pass203 204 @property205 def script_load(self):206 """207 This property defines, when to load this script.208 In order to allow creation of an object, we need to load script for any209 node at the parent level.210 211 i.e.212 - In order to allow creating a server object, it should be loaded at213 server-group node.214 """215 pass216 217 @property218 def node_path(self):219 return self.browser_url_prefix + self.node_type220 221 @property222 def show_node(self):223 """224 Property to check whether to show the node for this module on the225 browser tree or not.226 227 Relies on show_node preference object, otherwise on the SHOW_ON_BROWSER228 default value.229 """230 if self.pref_show_node:231 return self.pref_show_node.get()232 else:233 return self.SHOW_ON_BROWSER234 235 @property236 def show_system_objects(self):237 """238 Show/Hide the system objects in the database server.239 """240 if self.pref_show_system_objects:241 return self.pref_show_system_objects.get()242 else:243 return False244 245 @property246 def show_database_template(self):247 """248 Show/Hide the user defined template in the database server.249 """250 if self.pref_show_user_defined_templates:251 return self.pref_show_user_defined_templates.get()252 else:253 return False254 255 def register_preferences(self):256 """257 register_preferences258 Register preferences for this module.259 260 Keep the browser preference object to be used by overriden submodule,261 along with that get two browser level preferences show_system_objects,262 and show_node will be registered to used by the submodules.263 """264 # Add the node informaton for browser, not in respective node265 # preferences266 self.browser_preference = Preferences.module('browser')267 self.pref_show_system_objects = self.browser_preference.preference(268 'show_system_objects'269 )270 self.pref_show_user_defined_templates = \271 self.browser_preference.preference('show_user_defined_templates')272 self.pref_show_node = self.browser_preference.register(273 'node', 'show_node_' + self.node_type,274 self.collection_label, 'node', self.SHOW_ON_BROWSER,275 category_label=gettext('Nodes')276 )277 self.pref_show_empty_coll_nodes = self.browser_preference.preference(278 'show_empty_coll_nodes'279 )280 