///////////////////////////////////////////////////////////// // // pgAdmin 4 - PostgreSQL Tools // // Copyright (C) 2013 - 2021, The pgAdmin Development Team // This software is released under the PostgreSQL Licence // ////////////////////////////////////////////////////////////// import { Terminal } from 'xterm'; import { FitAddon } from 'xterm-addon-fit'; import { WebLinksAddon } from 'xterm-addon-web-links'; import { SearchAddon } from 'xterm-addon-search'; import { io } from 'socketio'; import Alertify from 'pgadmin.alertifyjs'; import {enable} from 'pgadmin.browser.toolbar'; import clipboard from 'sources/selection/clipboard'; import 'wcdocker'; import {getRandomInt} from 'sources/utils'; import {getTreeNodeHierarchyFromIdentifier} from 'sources/tree/pgadmin_tree_node'; import {generateTitle} from 'tools/datagrid/static/js/datagrid_panel_title'; export function setPanelTitle(psqlToolPanel, panelTitle) { psqlToolPanel.title(''+panelTitle+''); } var wcDocker = window.wcDocker; export function initialize(gettext, url_for, $, _, pgAdmin, csrfToken, Browser) { var pgBrowser = Browser; var terminal = Terminal; var parentData = null; /* Return back, this has been called more than once */ if (pgBrowser.psql) return pgBrowser.psql; // Create an Object Restore of pgBrowser class pgBrowser.psql = { init: function() { this.initialized = true; csrfToken.setPGCSRFToken(pgAdmin.csrf_token_header, pgAdmin.csrf_token); // Define the nodes on which the menus to be appear var menus = [{ name: 'psql', module: this, applies: ['tools'], callback: 'psql_tool', priority: 1, label: gettext('PSQL Tool (Beta)'), enable: this.psqlToolEnabled, }]; this.enable_psql_tool = pgAdmin['enable_psql']; if(pgAdmin['enable_psql']) { pgBrowser.add_menus(menus); } // Creating a new pgBrowser frame to show the data. var psqlFrameType = new pgBrowser.Frame({ name: 'frm_psqltool', showTitle: true, isCloseable: true, isPrivate: true, url: 'about:blank', }); var self = this; /* Cache may take time to load for the first time * Keep trying till available */ let cacheIntervalId = setInterval(function() { if(pgBrowser.preference_version() > 0) { self.preferences = pgBrowser.get_preferences_for_module('psql'); clearInterval(cacheIntervalId); } },0); pgBrowser.onPreferencesChange('psql', function() { self.preferences = pgBrowser.get_preferences_for_module('psql'); }); // Load the newly created frame psqlFrameType.load(pgBrowser.docker); return this; }, /* Enable/disable PSQL tool menu in tools based * on node selected. if selected node is present * in unsupported_nodes, menu will be disabled * otherwise enabled. */ psqlToolEnabled: function(obj) { var isEnabled = (() => { if (!_.isUndefined(obj) && !_.isNull(obj) && pgAdmin['enable_psql']) { if (_.indexOf(pgAdmin.unsupported_nodes, obj._type) == -1) { if (obj._type == 'database' && obj.allowConn) { return true; } else if (obj._type != 'database') { return true; } else { return false; } } else { return false; } } else { return false; } })(); enable(gettext('PSQL Tool'), isEnabled); return isEnabled; }, retrieveAncestorOfTypeServer: function(item) { let serverInformation = null; // let aciTreeItem = item || pgBrowser.treeMenu.selected(); let treeNode = pgBrowser.treeMenu.findNodeByDomElement(item); if (treeNode) { let nodeData; let databaseNode = treeNode.ancestorNode( (node) => { nodeData = node.getData(); return (nodeData._type === 'database'); } ); let isServerNode = (node) => { nodeData = node.getData(); return nodeData._type === 'server'; }; if (databaseNode !== null) { if (nodeData._label.indexOf('=') >= 0) { this.alertify.alert( gettext(this.errorAlertTitle), gettext( 'Databases with = symbols in the name cannot be backed up or restored using this utility.' ) ); } else { if (databaseNode.anyParent(isServerNode)) serverInformation = nodeData; } } else { if (treeNode.anyFamilyMember(isServerNode)) serverInformation = nodeData; } } if (serverInformation === null) { this.alertify.alert( gettext(this.errorAlertTitle), gettext('Please select server or child node from the browser tree.') ); } return serverInformation; }, psql_tool: function(data, aciTreeIdentifier, gen=false) { const module = 'paths'; let preference_name = 'pg_bin_dir'; let msg = gettext('Please configure the PostgreSQL Binary Path in the Preferences dialog.'); const serverInformation = this.retrieveAncestorOfTypeServer(aciTreeIdentifier); if ((serverInformation.type && serverInformation.type === 'ppas') || serverInformation.server_type === 'ppas') { preference_name = 'ppas_bin_dir'; msg = gettext('Please configure the EDB Advanced Server Binary Path in the Preferences dialog.'); } const preference = pgBrowser.get_preference(module, preference_name); if (preference) { if (!preference.value) { Alertify.alert(gettext('Configuration required'), msg); return false; } } else { Alertify.alert( gettext(this.errorAlertTitle), gettext('Failed to load preference %s of module %s', preference_name, module) ); return false; } const node = pgBrowser.treeMenu.findNodeByDomElement(aciTreeIdentifier); if (node === undefined || !node.getData()) { Alertify.alert( gettext('PSQL Error'), gettext('No object selected.') ); return; } parentData = getTreeNodeHierarchyFromIdentifier.call( pgBrowser, aciTreeIdentifier ); if(_.isUndefined(parentData.server)) { Alertify.alert( gettext('PSQL Error'), gettext('Please select a server/database object.') ); return; } const transId = getRandomInt(1, 9999999); var panelTitle = ''; // Set psql tab title as per prefrences setting. var title_data = { 'database': parentData.database ? parentData.database.label : 'postgres' , 'username': parentData.server.user_name, 'server': parentData.server.label, 'type': 'psql_tool', }; var tab_title_placeholder = pgBrowser.get_preferences_for_module('browser').psql_tab_title_placeholder; panelTitle = generateTitle(tab_title_placeholder, title_data); const [panelUrl, panelCloseUrl] = this.getPanelUrls(transId, panelTitle, parentData, gen); let psqlToolForm = `
`; var open_new_tab = pgBrowser.get_preferences_for_module('browser').new_browser_tab_open; if (open_new_tab && open_new_tab.includes('psql_tool')) { var newWin = window.open('', '_blank'); newWin.document.write(psqlToolForm); newWin.document.title = panelTitle; } else { /* On successfully initialization find the properties panel, * create new panel and add it to the dashboard panel. */ var propertiesPanel = pgBrowser.docker.findPanels('properties'); var psqlToolPanel = pgBrowser.docker.addPanel('frm_psqltool', wcDocker.DOCK.STACKED, propertiesPanel[0]); // Set panel title and icon setPanelTitle(psqlToolPanel, panelTitle); psqlToolPanel.icon('fas fa-terminal psql-tab-style'); psqlToolPanel.focus(); var openPSQLToolURL = function(j) { // add spinner element let $spinner_el = $(`