246 lines
7.8 KiB
JavaScript
246 lines
7.8 KiB
JavaScript
/////////////////////////////////////////////////////////////
|
|
//
|
|
// pgAdmin 4 - PostgreSQL Tools
|
|
//
|
|
// Copyright (C) 2013 - 2025, The pgAdmin Development Team
|
|
// This software is released under the PostgreSQL Licence
|
|
//
|
|
//////////////////////////////////////////////////////////////
|
|
|
|
import { getRandomInt, hasBinariesConfiguration } from 'sources/utils';
|
|
import { retrieveAncestorOfTypeServer } from 'sources/tree/tree_utils';
|
|
import { generateTitle } from 'tools/sqleditor/static/js/sqleditor_title';
|
|
import { AllPermissionTypes, BROWSER_PANELS, WORKSPACES } from '../../../../browser/static/js/constants';
|
|
import usePreferences,{ listenPreferenceBroadcast } from '../../../../preferences/static/js/store';
|
|
import 'pgadmin.browser.keyboard';
|
|
import pgWindow from 'sources/window';
|
|
import pgAdmin from 'sources/pgadmin';
|
|
import pgBrowser from 'pgadmin.browser';
|
|
import PsqlComponent from './components/PsqlComponent';
|
|
import { PgAdminProvider } from '../../../../static/js/PgAdminProvider';
|
|
import getApiInstance from '../../../../static/js/api_instance';
|
|
import gettext from 'sources/gettext';
|
|
import url_for from 'sources/url_for';
|
|
import Theme from '../../../../static/js/Theme';
|
|
import { NotifierProvider } from '../../../../static/js/helpers/Notifier';
|
|
import ModalProvider from '../../../../static/js/helpers/ModalProvider';
|
|
import * as csrfToken from 'sources/csrf';
|
|
import { ApplicationStateProvider } from '../../../../settings/static/ApplicationStateProvider';
|
|
import ToolErrorView from '../../../../static/js/ToolErrorView';
|
|
import React from 'react';
|
|
import ReactDOM from 'react-dom/client';
|
|
|
|
|
|
export default class Psql {
|
|
static instance;
|
|
|
|
static getInstance(...args) {
|
|
if (!Psql.instance) {
|
|
Psql.instance = new Psql(...args);
|
|
}
|
|
return Psql.instance;
|
|
}
|
|
|
|
constructor(pgAdmin, pgBrowser) {
|
|
this.pgAdmin = pgAdmin;
|
|
this.pgBrowser = pgBrowser;
|
|
this.api = getApiInstance();
|
|
}
|
|
|
|
/* 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(obj) {
|
|
|
|
let 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;
|
|
}
|
|
})();
|
|
|
|
return isEnabled;
|
|
}
|
|
|
|
init() {
|
|
if (this.initialized)
|
|
return;
|
|
this.initialized = true;
|
|
csrfToken.setPGCSRFToken(pgAdmin.csrf_token_header, pgAdmin.csrf_token);
|
|
// Define the nodes on which the menus to be appear
|
|
|
|
let menus = [{
|
|
name: 'psql',
|
|
module: this,
|
|
applies: ['tools'],
|
|
callback: 'openPsqlTool',
|
|
enable: this.psqlToolEnabled,
|
|
priority: 1,
|
|
label: gettext('PSQL Tool'),
|
|
data:{
|
|
applies: 'tools',
|
|
data_disabled: gettext('Please select a database from the object explorer to access Pql Tool.'),
|
|
},
|
|
permission: AllPermissionTypes.TOOLS_PSQL_TOOL,
|
|
}];
|
|
|
|
|
|
this.enable_psql_tool = pgAdmin['enable_psql'];
|
|
if(pgAdmin['enable_psql']) {
|
|
pgBrowser.add_menus(menus);
|
|
}
|
|
}
|
|
|
|
openPsqlTool(_data, treeIdentifier, connectionInfo=null) {
|
|
let parentData = null;
|
|
let panelTitle = '';
|
|
if (connectionInfo){
|
|
parentData = {
|
|
server_group: {
|
|
_id: connectionInfo.sgid || 0
|
|
},
|
|
server: {
|
|
_id: connectionInfo.sid,
|
|
server_type: connectionInfo.server_type,
|
|
label: connectionInfo.server_name,
|
|
user: {
|
|
name: connectionInfo.user
|
|
}
|
|
},
|
|
database: {
|
|
_id: connectionInfo.did,
|
|
_label: connectionInfo.db
|
|
},
|
|
schema: {
|
|
_id: connectionInfo.scid || null,
|
|
},
|
|
table: {
|
|
_id: connectionInfo.tid || null,
|
|
}
|
|
};
|
|
|
|
}else{
|
|
const serverInformation = retrieveAncestorOfTypeServer(pgBrowser, treeIdentifier, gettext('PSQL Error'));
|
|
if (!hasBinariesConfiguration(pgBrowser, serverInformation)) {
|
|
return;
|
|
}
|
|
|
|
const node = pgBrowser.tree.findNodeByDomElement(treeIdentifier);
|
|
if (node === undefined || !node.getData()) {
|
|
pgAdmin.Browser.notifier.alert(
|
|
gettext('PSQL Error'),
|
|
gettext('No object selected.')
|
|
);
|
|
return;
|
|
}
|
|
|
|
parentData = pgBrowser.tree.getTreeNodeHierarchy(treeIdentifier);
|
|
if(_.isUndefined(parentData.server)) {
|
|
pgAdmin.Browser.notifier.alert(
|
|
gettext('PSQL Error'),
|
|
gettext('Please select a server/database object.')
|
|
);
|
|
return;
|
|
}
|
|
|
|
}
|
|
|
|
const transId = getRandomInt(1, 9999999);
|
|
// Set psql tab title as per prefrences setting.
|
|
let title_data = {
|
|
'database': parentData.database ? _.unescape(parentData.database._label) : 'postgres' ,
|
|
'username': parentData.server.user.name,
|
|
'server': parentData.server.label,
|
|
'type': 'psql_tool',
|
|
};
|
|
|
|
let tab_title_placeholder = usePreferences.getState().getPreferencesForModule('browser').psql_tab_title_placeholder;
|
|
panelTitle = generateTitle(tab_title_placeholder, title_data);
|
|
|
|
const [panelUrl, db_label] = this.getPanelUrls(transId, parentData);
|
|
|
|
const open_new_tab = usePreferences.getState().getPreferencesForModule('browser').new_browser_tab_open;
|
|
|
|
pgAdmin.Browser.Events.trigger(
|
|
'pgadmin:tool:show',
|
|
`${BROWSER_PANELS.PSQL_TOOL}_${transId}`,
|
|
panelUrl,
|
|
{title: panelTitle, db: db_label, server_name: parentData.server.label, 'user': parentData.server.user.name },
|
|
{title: panelTitle, icon: 'pg-font-icon icon-terminal', manualClose: false, renamable: true},
|
|
Boolean(open_new_tab?.includes('psql_tool'))
|
|
);
|
|
|
|
return true;
|
|
}
|
|
|
|
getPanelUrls(transId, pData) {
|
|
let openUrl = url_for('psql.panel', {
|
|
trans_id: transId,
|
|
});
|
|
const misc_preferences = usePreferences.getState().getPreferencesForModule('misc');
|
|
let theme = misc_preferences.theme;
|
|
|
|
openUrl += `?sgid=${pData.server_group._id}`
|
|
+`&sid=${pData.server._id}`
|
|
+`&did=${pData.database._id}`
|
|
+`&server_type=${pData.server.server_type}`
|
|
+ `&theme=${theme}`;
|
|
|
|
if(pData.database?._id) {
|
|
openUrl += `&db=${encodeURIComponent(pData.database._label)}`;
|
|
} else {
|
|
openUrl += `&db=${''}`;
|
|
}
|
|
|
|
return [openUrl, pData.database._label];
|
|
}
|
|
|
|
async loadComponent(container, params) {
|
|
let panelDocker = pgWindow.pgAdmin.Browser.docker.psql_workspace;
|
|
if (pgWindow.pgAdmin.Browser.docker.currentWorkspace == WORKSPACES.DEFAULT) {
|
|
panelDocker = pgWindow.pgAdmin.Browser.docker.default_workspace;
|
|
}
|
|
|
|
pgAdmin.Browser.keyboardNavigation.init();
|
|
await listenPreferenceBroadcast();
|
|
const root = ReactDOM.createRoot(container);
|
|
root.render(
|
|
<Theme>
|
|
<PgAdminProvider value={pgAdmin}>
|
|
<ApplicationStateProvider>
|
|
<ModalProvider>
|
|
<NotifierProvider pgAdmin={pgAdmin} pgWindow={pgWindow} />
|
|
{ params.error ?
|
|
<ToolErrorView
|
|
error={params.error}
|
|
panelId={`${BROWSER_PANELS.PSQL_TOOL}_${params.trans_id}`}
|
|
panelDocker={panelDocker}
|
|
/> :
|
|
<PsqlComponent
|
|
params={params}
|
|
pgAdmin={pgAdmin}
|
|
panelId={`${BROWSER_PANELS.PSQL_TOOL}_${params.trans_id}`}
|
|
panelDocker={panelDocker}
|
|
/>
|
|
}
|
|
</ModalProvider>
|
|
</ApplicationStateProvider>
|
|
</PgAdminProvider>
|
|
</Theme>
|
|
);
|
|
}
|
|
}
|