mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
1) Added browse button to select the binary path in the Preferences. Fixes #1561
2) Added support to set the binary path for the different database server versions. Fixes #5370
This commit is contained in:
parent
ac8e8961ce
commit
4bc4ca1ba9
Binary file not shown.
Before Width: | Height: | Size: 142 KiB After Width: | Height: | Size: 237 KiB |
@ -211,21 +211,23 @@ files.
|
||||
:align: center
|
||||
|
||||
Use the fields on the *Binary paths* panel to specify the path to the directory
|
||||
that contains the utility programs (pg_dump, pg_restore, and pg_dumpall) for
|
||||
that contains the utility programs (pg_dump, pg_dumpall, pg_restore and psql) for
|
||||
monitored databases:
|
||||
|
||||
* Use the *EDB Advanced Server Binary Path* field to specify the location of the
|
||||
EDB Postgres Advanced Server utility programs. If this path is not set,
|
||||
pgAdmin will attempt to find the utilities in standard locations used by
|
||||
EnterpriseDB.
|
||||
* Use the *EDB Advanced Server Binary Path* grid to specify the location of the
|
||||
EDB Postgres Advanced Server utility programs based on the server version.
|
||||
If the respective path is not set, then pgAdmin will pick up the path for which
|
||||
'Set as default' is checked else pgAdmin will attempt to find the utilities in
|
||||
standard locations used by EnterpriseDB.
|
||||
|
||||
* Use the *Greenplum Database Binary Path* field to specify the location of the
|
||||
Greenplum database utility programs. If this path is not set, pgAdmin will
|
||||
attempt to find the utilities in standard locations used by Greenplum.
|
||||
* Use the *PostgreSQL Binary Path* grid to specify the location of the
|
||||
PostgreSQL utility programs based on the server version. If the respective
|
||||
path is not set, then pgAdmin will pick up the path for which 'Set as default'
|
||||
is checked else pgAdmin will attempt to find the utilities in standard
|
||||
locations used by PostgreSQL.
|
||||
|
||||
* Use the *PostgreSQL Binary Path* field to specify the location of the
|
||||
PostgreSQL utility programs. If this path is not set, pgAdmin will attempt
|
||||
to find the utilities in standard locations used by PostgreSQL.
|
||||
**Note:** Use the 'Validate path' button to check the existence of the utility
|
||||
programs (pg_dump, pg_dumpall, pg_restore and psql) and there respective versions.
|
||||
|
||||
.. image:: images/preferences_paths_help.png
|
||||
:alt: Preferences dialog binary path help section
|
||||
|
@ -9,9 +9,11 @@ This release contains a number of bug fixes and new features since the release o
|
||||
New features
|
||||
************
|
||||
|
||||
| `Issue #1561 <https://redmine.postgresql.org/issues/1561>`_ - Added browse button to select the binary path in the Preferences.
|
||||
| `Issue #1591 <https://redmine.postgresql.org/issues/1591>`_ - Added Grant Wizard option under Package node.
|
||||
| `Issue #2341 <https://redmine.postgresql.org/issues/2341>`_ - Added support to launch PSQL for the connected database server.
|
||||
| `Issue #4064 <https://redmine.postgresql.org/issues/4064>`_ - Added window maximize/restore functionality for properties dialog.
|
||||
| `Issue #5370 <https://redmine.postgresql.org/issues/5370>`_ - Added support to set the binary path for the different database server versions.
|
||||
| `Issue #6231 <https://redmine.postgresql.org/issues/6231>`_ - Added OS, Browser, Configuration details in the About dialog.
|
||||
| `Issue #6395 <https://redmine.postgresql.org/issues/6395>`_ - Added support to rotate the pgadmin log file on the basis of Size and Age.
|
||||
|
||||
|
@ -658,7 +658,12 @@ ENABLE_PSQL = True
|
||||
# User will able to execute the system level commands through PSQL terminal
|
||||
# in pgAdmin.
|
||||
ALLOW_PSQL_SHELL_COMMANDS = False
|
||||
|
||||
##########################################################################
|
||||
# ENABLE_BINARY_PATH_BROWSING setting is used to enable the browse button
|
||||
# while selecting binary path for the database server in server mode.
|
||||
# In Desktop mode it is always enabled and setting is of no use.
|
||||
##########################################################################
|
||||
ENABLE_BINARY_PATH_BROWSING = False
|
||||
##########################################################################
|
||||
# Local config settings
|
||||
##########################################################################
|
||||
|
@ -11,10 +11,11 @@ define('pgadmin.node.mview', [
|
||||
'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
|
||||
'sources/pgadmin', 'pgadmin.alertifyjs', 'pgadmin.browser',
|
||||
'pgadmin.backform', 'pgadmin.node.schema.dir/child',
|
||||
'pgadmin.node.schema.dir/schema_child_tree_node', 'pgadmin.browser.server.privilege',
|
||||
'pgadmin.node.schema.dir/schema_child_tree_node', 'sources/utils',
|
||||
'pgadmin.browser.server.privilege',
|
||||
], function(
|
||||
gettext, url_for, $, _, pgAdmin, Alertify, pgBrowser, Backform,
|
||||
schemaChild, schemaChildTreeNode
|
||||
schemaChild, schemaChildTreeNode, commonUtils
|
||||
) {
|
||||
|
||||
/**
|
||||
@ -316,25 +317,7 @@ define('pgadmin.node.mview', [
|
||||
return;
|
||||
}
|
||||
|
||||
var module = 'paths',
|
||||
preference_name = 'pg_bin_dir',
|
||||
msg = gettext('Please configure the PostgreSQL Binary Path in the Preferences dialog.');
|
||||
|
||||
if ((server_data.type && server_data.type == 'ppas') ||
|
||||
server_data.server_type == 'ppas') {
|
||||
preference_name = 'ppas_bin_dir';
|
||||
msg = gettext('Please configure the EDB Advanced Server Binary Path in the Preferences dialog.');
|
||||
}
|
||||
|
||||
var preference = pgBrowser.get_preference(module, preference_name);
|
||||
|
||||
if (preference) {
|
||||
if (!preference.value) {
|
||||
Alertify.alert(gettext('Configuration required'), msg);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
Alertify.alert(gettext('Failed to load preference %s of module %s', preference_name, module));
|
||||
if (!commonUtils.hasBinariesConfiguration(pgBrowser, server_data, this.alertify)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -9,14 +9,13 @@
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
|
||||
from flask import render_template
|
||||
from flask_babelex import gettext as _
|
||||
from pgadmin.utils.preferences import Preferences
|
||||
from werkzeug.exceptions import InternalServerError
|
||||
|
||||
import config
|
||||
|
||||
|
||||
class ServerType(object):
|
||||
"""
|
||||
@ -61,14 +60,18 @@ class ServerType(object):
|
||||
|
||||
for key in cls.registry:
|
||||
st = cls.registry[key]
|
||||
default_path = config.DEFAULT_BINARY_PATHS.get(st.stype, "")
|
||||
|
||||
st.utility_path = paths.register(
|
||||
'bin_paths', st.stype + '_bin_dir',
|
||||
st.UTILITY_PATH_LABEL,
|
||||
'text', default_path, category_label=_('Binary paths'),
|
||||
help_str=st.UTILITY_PATH_HELP
|
||||
)
|
||||
if key == 'pg':
|
||||
st.utility_path = paths.register(
|
||||
'bin_paths', 'pg_bin_dir',
|
||||
_("PostgreSQL Binary Path"), 'selectFile', None,
|
||||
category_label=_('Binary paths')
|
||||
)
|
||||
elif key == 'ppas':
|
||||
st.utility_path = paths.register(
|
||||
'bin_paths', 'ppas_bin_dir',
|
||||
_("EDB Advanced Server Binary Path"), 'selectFile', None,
|
||||
category_label=_('Binary paths')
|
||||
)
|
||||
|
||||
@property
|
||||
def priority(self):
|
||||
@ -120,7 +123,8 @@ class ServerType(object):
|
||||
operation
|
||||
)
|
||||
)
|
||||
bin_path = self.utility_path.get()
|
||||
|
||||
bin_path = self.get_utility_path(sversion)
|
||||
if "$DIR" in bin_path:
|
||||
# When running as an WSGI application, we will not find the
|
||||
# '__file__' attribute for the '__main__' module.
|
||||
@ -138,6 +142,26 @@ class ServerType(object):
|
||||
(res if os.name != 'nt' else (res + '.exe'))
|
||||
))
|
||||
|
||||
def get_utility_path(self, sverison):
|
||||
"""
|
||||
This function is used to get the utility path set by the user in
|
||||
preferences for the specific server version, if not set then check
|
||||
for any default path is set.
|
||||
"""
|
||||
default_path = None
|
||||
bin_path_json = json.loads(self.utility_path.get())
|
||||
# iterate through all the path and return appropriate value
|
||||
for bin_path in bin_path_json:
|
||||
if int(bin_path['version']) <= sverison < \
|
||||
int(bin_path['next_major_version']) and \
|
||||
bin_path['binaryPath'] is not None:
|
||||
return bin_path['binaryPath']
|
||||
|
||||
if bin_path['isDefault']:
|
||||
default_path = bin_path['binaryPath']
|
||||
|
||||
return default_path
|
||||
|
||||
|
||||
# Default Server Type
|
||||
ServerType('pg', _("PostgreSQL"), -1)
|
||||
|
@ -57,6 +57,9 @@ define('pgadmin.browser.utils',
|
||||
pgAdmin['allow_psql_shell_commands'] = '{{ current_app.config.get('ALLOW_PSQL_SHELL_COMMANDS') }}' == 'True';
|
||||
pgAdmin['platform'] = '{{platform}}';
|
||||
|
||||
/* GET Binary Path Browse config */
|
||||
pgAdmin['enable_binary_path_browsing'] = '{{ current_app.config.get('ENABLE_BINARY_PATH_BROWSING') }}' == 'True';
|
||||
|
||||
// Define list of nodes on which Query tool option doesn't appears
|
||||
var unsupported_nodes = pgAdmin.unsupported_nodes = [
|
||||
'server_group', 'server', 'coll-tablespace', 'tablespace',
|
||||
|
@ -17,8 +17,11 @@ from pgadmin.utils.csrf import pgCSRFProtect
|
||||
from pgadmin.utils.session import cleanup_session_files
|
||||
from pgadmin.misc.themes import get_all_themes
|
||||
from pgadmin.utils.constants import MIMETYPE_APP_JS
|
||||
from pgadmin.utils.ajax import precondition_required, make_json_response
|
||||
import config
|
||||
from werkzeug.exceptions import InternalServerError
|
||||
import subprocess
|
||||
import os
|
||||
import json
|
||||
|
||||
MODULE_NAME = 'misc'
|
||||
|
||||
@ -98,7 +101,8 @@ class MiscModule(PgAdminModule):
|
||||
Returns:
|
||||
list: a list of url endpoints exposed to the client.
|
||||
"""
|
||||
return ['misc.ping', 'misc.index', 'misc.cleanup']
|
||||
return ['misc.ping', 'misc.index', 'misc.cleanup',
|
||||
'misc.validate_binary_path']
|
||||
|
||||
|
||||
# Initialise the module
|
||||
@ -165,3 +169,48 @@ def shutdown():
|
||||
return 'SHUTDOWN'
|
||||
else:
|
||||
return ''
|
||||
|
||||
|
||||
##########################################################################
|
||||
# A special URL used to validate the binary path
|
||||
##########################################################################
|
||||
@blueprint.route("/validate_binary_path",
|
||||
endpoint="validate_binary_path",
|
||||
methods=["POST"])
|
||||
def validate_binary_path():
|
||||
"""
|
||||
This function is used to validate the specified utilities path by
|
||||
running the utilities with there versions.
|
||||
"""
|
||||
data = None
|
||||
if hasattr(request.data, 'decode'):
|
||||
data = request.data.decode('utf-8')
|
||||
|
||||
if data != '':
|
||||
data = json.loads(data)
|
||||
|
||||
version_str = ''
|
||||
if 'utility_path' in data and data['utility_path'] is not None:
|
||||
for utility in ['pg_dump', 'pg_dumpall', 'pg_restore', 'psql']:
|
||||
full_path = os.path.abspath(
|
||||
os.path.join(data['utility_path'],
|
||||
(utility if os.name != 'nt' else
|
||||
(utility + '.exe'))))
|
||||
try:
|
||||
result = subprocess.Popen([full_path, '--version'],
|
||||
stdout=subprocess.PIPE)
|
||||
except FileNotFoundError:
|
||||
version_str += "<b>" + utility + ":</b> " + \
|
||||
"not found on the specified binary path.<br/>"
|
||||
continue
|
||||
|
||||
# Replace the name of the utility from the result to avoid
|
||||
# duplicate name.
|
||||
result_str = \
|
||||
result.stdout.read().decode("utf-8").replace(utility, '')
|
||||
|
||||
version_str += "<b>" + utility + ":</b> " + result_str + "<br/>"
|
||||
else:
|
||||
return precondition_required(gettext('Invalid binary path.'))
|
||||
|
||||
return make_json_response(data=gettext(version_str), status=200)
|
||||
|
@ -1573,7 +1573,6 @@ define([
|
||||
);
|
||||
$('.file_manager button.rename').attr('disabled', 'disabled');
|
||||
// set selected folder name in breadcrums
|
||||
$('.file_manager #uploader .input-path').hide();
|
||||
$('.file_manager #uploader .show_selected_file').remove();
|
||||
$('<span class="show_selected_file">' + path + '</span>').appendTo(
|
||||
'.file_manager #uploader .filemanager-path-group'
|
||||
|
@ -307,6 +307,8 @@ define('pgadmin.preferences', [
|
||||
return 'keyboardShortcut';
|
||||
case 'radioModern':
|
||||
return 'radioModern';
|
||||
case 'selectFile':
|
||||
return 'binary-paths-grid';
|
||||
default:
|
||||
if (console && console.warn) {
|
||||
// Warning for developer only.
|
||||
@ -476,7 +478,7 @@ define('pgadmin.preferences', [
|
||||
overflow: !1,
|
||||
title: gettext('Preferences'),
|
||||
closableByDimmer: false,
|
||||
modal: false,
|
||||
modal: true,
|
||||
pinnable: false,
|
||||
},
|
||||
};
|
||||
|
@ -79,66 +79,6 @@ export class Dialog {
|
||||
return serverInformation;
|
||||
}
|
||||
|
||||
retrieveAncestorOfTypeDatabase(item) {
|
||||
let databaseInfo = null;
|
||||
let aciTreeItem = item || this.pgBrowser.treeMenu.selected();
|
||||
let treeNode = this.pgBrowser.treeMenu.findNodeByDomElement(aciTreeItem);
|
||||
|
||||
if (treeNode) {
|
||||
if(treeNode.getData()._type === 'database') {
|
||||
databaseInfo = treeNode.getData();
|
||||
} else {
|
||||
let nodeData = null;
|
||||
treeNode.ancestorNode(
|
||||
(node) => {
|
||||
nodeData = node.getData();
|
||||
if(nodeData._type === 'database') {
|
||||
databaseInfo = nodeData;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (databaseInfo === null) {
|
||||
this.alertify.alert(
|
||||
gettext(this.errorAlertTitle),
|
||||
gettext('Please select a database or its child node from the browser.')
|
||||
);
|
||||
}
|
||||
|
||||
return databaseInfo;
|
||||
}
|
||||
|
||||
hasBinariesConfiguration(serverInformation) {
|
||||
const module = 'paths';
|
||||
let preference_name = 'pg_bin_dir';
|
||||
let msg = gettext('Please configure the PostgreSQL Binary Path in the Preferences dialog.');
|
||||
|
||||
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 = this.pgBrowser.get_preference(module, preference_name);
|
||||
|
||||
if (preference) {
|
||||
if (!preference.value) {
|
||||
this.alertify.alert(gettext('Configuration required'), msg);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
this.alertify.alert(
|
||||
gettext(this.errorAlertTitle),
|
||||
gettext('Failed to load preference %s of module %s', preference_name, module)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
dialogName() {
|
||||
return undefined;
|
||||
}
|
||||
|
@ -1115,6 +1115,120 @@ define([
|
||||
};
|
||||
};
|
||||
|
||||
Backform.BinaryPathsGridControl = Backform.Control.extend({
|
||||
initialize: function() {
|
||||
Backform.Control.prototype.initialize.apply(this, arguments);
|
||||
|
||||
var BinaryPathModel = Backbone.Model.extend({
|
||||
idAttribute: 'serverType',
|
||||
defaults: {
|
||||
serverType: undefined,
|
||||
binaryPath: undefined,
|
||||
isDefault: false
|
||||
},
|
||||
});
|
||||
|
||||
this.gridColumns = [{
|
||||
name: 'isDefault',
|
||||
label: 'Set as default',
|
||||
sortable: false,
|
||||
cell: Backgrid.RadioCell,
|
||||
cellHeaderClasses: 'width_percent_10',
|
||||
headerCell: Backgrid.Extension.CustomHeaderCell,
|
||||
deps: ['binaryPath'],
|
||||
editable: function(m) {
|
||||
if (!_.isUndefined(m.get('binaryPath')) && !_.isNull(m.get('binaryPath')) && m.get('binaryPath') !== '') {
|
||||
return true;
|
||||
} else if (!_.isUndefined(m.get('isDefault')) && !_.isNull(m.get('isDefault'))){
|
||||
setTimeout(function() {
|
||||
m.set('isDefault', false);
|
||||
}, 10);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}, {
|
||||
name: 'serverType',
|
||||
label: 'Database Server',
|
||||
editable: false,
|
||||
cell: 'string',
|
||||
cellHeaderClasses: 'width_percent_20',
|
||||
headerCell: Backgrid.Extension.CustomHeaderCell,
|
||||
}, {
|
||||
name: 'binaryPath',
|
||||
label: 'Binary Path',
|
||||
sortable: false,
|
||||
cell: Backgrid.Extension.SelectFileCell,
|
||||
dialog_type: 'select_folder',
|
||||
dialog_title: gettext('Select Folder'),
|
||||
placeholder: gettext('Select binary path ...'),
|
||||
browse_btn_label: gettext('Select path'),
|
||||
check_btn_label: gettext('Validate utilities'),
|
||||
browse_btn_visible: pgAdmin.server_mode === 'False' ? true : pgAdmin.enable_binary_path_browsing ? true : false
|
||||
}];
|
||||
|
||||
var BinPathCollection = this.BinPathCollection = new (Backbone.Collection.extend({
|
||||
model: BinaryPathModel
|
||||
}))(null);
|
||||
|
||||
let bin_value = JSON.parse(this.model.get(this.field.get('name')));
|
||||
if (this.field.get('label').indexOf('EDB') >= 0) {
|
||||
let as_bin_paths = _.extend([
|
||||
{'version': '90600', 'next_major_version': '100000', 'serverType': gettext('EDB Advanced Server 9.6'), 'binaryPath': null, 'isDefault': false},
|
||||
{'version': '100000', 'next_major_version': '110000', 'serverType': gettext('EDB Advanced Server 10'), 'binaryPath': null, 'isDefault': false},
|
||||
{'version': '110000', 'next_major_version': '120000', 'serverType': gettext('EDB Advanced Server 11'), 'binaryPath': null, 'isDefault': false},
|
||||
{'version': '120000', 'next_major_version': '130000', 'serverType': gettext('EDB Advanced Server 12'), 'binaryPath': null, 'isDefault': false},
|
||||
{'version': '130000', 'next_major_version': '140000', 'serverType': gettext('EDB Advanced Server 13'), 'binaryPath': null, 'isDefault': false},
|
||||
], bin_value);
|
||||
|
||||
this.BinPathCollection.add(as_bin_paths);
|
||||
} else {
|
||||
let pg_bin_paths = _.extend([
|
||||
{'version': '90600', 'next_major_version': '100000', 'serverType': gettext('PostgreSQL 9.6'), 'binaryPath': null, 'isDefault': false},
|
||||
{'version': '100000', 'next_major_version': '110000', 'serverType': gettext('PostgreSQL 10'), 'binaryPath': null, 'isDefault': false},
|
||||
{'version': '110000', 'next_major_version': '120000', 'serverType': gettext('PostgreSQL 11'), 'binaryPath': null, 'isDefault': false},
|
||||
{'version': '120000', 'next_major_version': '130000', 'serverType': gettext('PostgreSQL 12'), 'binaryPath': null, 'isDefault': false},
|
||||
{'version': '130000', 'next_major_version': '140000', 'serverType': gettext('PostgreSQL 13'), 'binaryPath': null, 'isDefault': false}
|
||||
], bin_value);
|
||||
|
||||
this.BinPathCollection.add(pg_bin_paths);
|
||||
}
|
||||
|
||||
this.listenTo(BinPathCollection, 'change', this.binPathCollectionChanged);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var self = this,
|
||||
gridHeader = ['<div class=\'subnode-header\'>',
|
||||
' <span class=\'control-label pg-el-sm-12\'>' + gettext(this.field.get('label')) + '</span>',
|
||||
'</div>',
|
||||
].join('\n'),
|
||||
gridBody = $('<div class=\'pgadmin-control-group backgrid form-group pg-el-12 object subnode\'></div>').append(gridHeader);
|
||||
|
||||
self.grid = new Backgrid.Grid({
|
||||
columns: self.gridColumns,
|
||||
collection: self.BinPathCollection,
|
||||
className: 'backgrid table presentation table-bordered table-noouter-border table-hover',
|
||||
});
|
||||
|
||||
this.$el.empty();
|
||||
this.$el.append(gridBody.append(self.grid.render().$el));
|
||||
this.$el.append(['<span class="pg-el-sm-12 form-text text-muted help-block">' +
|
||||
gettext(' Enter the directory in which the psql, pg_dump, pg_dumpall, and pg_restore' +
|
||||
' utilities can be found for the corresponding database server version.' +
|
||||
' The default path will be used for server versions that do not have a' +
|
||||
'path specified.') + '</span>'].join('\n'));
|
||||
|
||||
return this;
|
||||
},
|
||||
binPathCollectionChanged: function() {
|
||||
let bin_value = JSON.stringify(this.BinPathCollection.toJSON());
|
||||
this.model.set(this.field.get('name'), bin_value, {
|
||||
silent: false
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Backform.UniqueColCollectionControl = Backform.Control.extend({
|
||||
initialize: function() {
|
||||
Backform.Control.prototype.initialize.apply(this, arguments);
|
||||
|
@ -10,10 +10,10 @@
|
||||
define([
|
||||
'sources/gettext', 'underscore', 'jquery', 'backbone', 'backform', 'backgrid', 'alertify',
|
||||
'moment', 'bignumber', 'codemirror', 'sources/utils', 'sources/keyboard_shortcuts', 'sources/select2/configure_show_on_scroll',
|
||||
'sources/window', 'bootstrap.datetimepicker', 'backgrid.filter', 'bootstrap.toggle',
|
||||
'sources/window', 'sources/url_for', 'bootstrap.datetimepicker', 'backgrid.filter', 'bootstrap.toggle',
|
||||
], function(
|
||||
gettext, _, $, Backbone, Backform, Backgrid, Alertify, moment, BigNumber, CodeMirror,
|
||||
commonUtils, keyboardShortcuts, configure_show_on_scroll, pgWindow
|
||||
commonUtils, keyboardShortcuts, configure_show_on_scroll, pgWindow, url_for
|
||||
) {
|
||||
/*
|
||||
* Add mechanism in backgrid to render different types of cells in
|
||||
@ -2154,7 +2154,7 @@ define([
|
||||
var editable = Backgrid.callByNeed(column.editable(), column, model);
|
||||
var align_center = column.get('align_center') || false;
|
||||
let checked = this.formatter.fromRaw(model.get(column.get('name')), model);
|
||||
let id = `column.get('name')_${_.uniqueId()}`;
|
||||
let id = `${column.get('name')}_${_.uniqueId()}`;
|
||||
|
||||
this.$el.empty();
|
||||
this.$el.append(
|
||||
@ -2249,6 +2249,187 @@ define([
|
||||
},
|
||||
});
|
||||
|
||||
return Backgrid;
|
||||
Backgrid.RadioCell = Backgrid.BooleanCell.extend({
|
||||
className: 'radio-cell',
|
||||
|
||||
initialize: function() {
|
||||
Backgrid.BooleanCell.prototype.initialize.apply(this, arguments);
|
||||
Backgrid.Extension.DependentCell.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
|
||||
dependentChanged: function() {
|
||||
return this.render();
|
||||
},
|
||||
|
||||
enterEditMode: function() {
|
||||
this.$el.addClass('editor');
|
||||
$(this.$el.find('input[type=radio]')).trigger('focus');
|
||||
},
|
||||
|
||||
exitEditMode: function() {
|
||||
this.$el.removeClass('editor');
|
||||
},
|
||||
|
||||
events: {
|
||||
'change input': 'onChange',
|
||||
'blur input': 'exitEditMode',
|
||||
},
|
||||
|
||||
onChange: function(e) {
|
||||
var model = this.model,
|
||||
column = this.column,
|
||||
val = this.formatter.toRaw(this.$input.prop('checked'), model);
|
||||
|
||||
this.enterEditMode();
|
||||
|
||||
_.each(this.model.collection.models, function(sub_model) {
|
||||
sub_model.set(column.get('name'), false);
|
||||
sub_model.trigger('backgrid:edited', sub_model, column, new Backgrid.Command(e));
|
||||
});
|
||||
|
||||
// on bootstrap change we also need to change model's value
|
||||
model.set(column.get('name'), val);
|
||||
model.trigger('backgrid:edited', model, column, new Backgrid.Command(e));
|
||||
},
|
||||
|
||||
render: function () {
|
||||
this.$el.empty();
|
||||
var model = this.model, column = this.column;
|
||||
var editable = Backgrid.callByNeed(column.editable(), column, model);
|
||||
let checked = this.formatter.fromRaw(model.get(column.get('name')), model);
|
||||
let id = `${column.get('name')}_${_.uniqueId()}`;
|
||||
|
||||
this.$el.empty();
|
||||
this.$el.append(
|
||||
$(`<div style="text-align: center">
|
||||
<input tabindex="0" type="radio" id="${id}" ${!editable?'disabled':''} ${checked?'checked':''}/>
|
||||
</div>`)
|
||||
);
|
||||
this.$input = this.$el.find('input');
|
||||
this.delegateEvents();
|
||||
return this;
|
||||
},
|
||||
});
|
||||
|
||||
Backgrid.Extension.SelectFileCell = Backgrid.Cell.extend({
|
||||
/** @property */
|
||||
className: 'file-cell',
|
||||
defaults: {
|
||||
supported_types: ['*'],
|
||||
dialog_type: 'select_file',
|
||||
dialog_title: gettext('Select file'),
|
||||
type: 'text',
|
||||
value: '',
|
||||
placeholder: gettext('Select file...'),
|
||||
disabled: false,
|
||||
browse_btn_label: gettext('Select file'),
|
||||
check_btn_label: gettext('Validate file'),
|
||||
browse_btn_visible: true,
|
||||
validate_btn_visible: true,
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
Backgrid.Cell.prototype.initialize.apply(this, arguments);
|
||||
this.data = _.extend(this.defaults, this.column.toJSON());
|
||||
},
|
||||
template: _.template([
|
||||
'<div class="input-group">',
|
||||
'<input type="<%=type%>" id="<%=cId%>" class="form-control" value="<%-value%>" placeholder="<%-placeholder%>" <%=disabled ? "disabled" : ""%> />',
|
||||
'<% if (browse_btn_visible) { %>',
|
||||
'<div class="input-group-append">',
|
||||
'<button class="btn btn-primary-icon fa fa-ellipsis-h select_item" <%=disabled ? "disabled" : ""%> aria-hidden="true" aria-label=<%=browse_btn_label%> title=<%=browse_btn_label%>></button>',
|
||||
'</div>',
|
||||
'<% } %>',
|
||||
'<% if (validate_btn_visible) { %>',
|
||||
'<div class="input-group-append">',
|
||||
'<button class="btn btn-primary-icon fa fa-clipboard-check validate_item" <%=disabled ? "disabled" : ""%> <%=(value=="" || value==null) ? "disabled" : ""%> aria-hidden="true" aria-label=<%=check_btn_label%> title=<%=check_btn_label%>></button>',
|
||||
'</div>',
|
||||
'<% } %>',
|
||||
'</div>',
|
||||
].join('\n')),
|
||||
events: {
|
||||
'change input': 'onChange',
|
||||
'click .select_item': 'onSelect',
|
||||
'click .validate_item': 'onValidate',
|
||||
},
|
||||
|
||||
render: function() {
|
||||
this.$el.empty();
|
||||
this.data = _.extend(this.data, {value: this.model.get(this.column.get('name'))});
|
||||
// Adding unique id
|
||||
this.data['cId'] = _.uniqueId('pgC_');
|
||||
this.$el.append(this.template(this.data));
|
||||
|
||||
this.$input = this.$el.find('input');
|
||||
this.delegateEvents();
|
||||
|
||||
return this;
|
||||
},
|
||||
onChange: function() {
|
||||
var model = this.model,
|
||||
column = this.column,
|
||||
val = this.formatter.toRaw(this.$input.prop('value'), model);
|
||||
|
||||
model.set(column.get('name'), val);
|
||||
},
|
||||
onSelect: function() {
|
||||
let self = this;
|
||||
|
||||
var params = {
|
||||
supported_types: self.data.supported_types,
|
||||
dialog_type: self.data.dialog_type,
|
||||
dialog_title: self.data.dialog_title
|
||||
};
|
||||
|
||||
pgAdmin.FileManager.init();
|
||||
pgAdmin.FileManager.show_dialog(params);
|
||||
// Listen click events of Storage Manager dialog buttons
|
||||
this.listen_file_dlg_events();
|
||||
},
|
||||
storage_dlg_hander: function(value) {
|
||||
var attrArr = this.column.get('name').split('.'),
|
||||
name = attrArr.shift();
|
||||
|
||||
this.remove_file_dlg_event_listeners();
|
||||
|
||||
// Set selected value into the model
|
||||
this.model.set(name, decodeURI(value));
|
||||
},
|
||||
storage_close_dlg_hander: function() {
|
||||
this.remove_file_dlg_event_listeners();
|
||||
},
|
||||
listen_file_dlg_events: function() {
|
||||
pgAdmin.Browser.Events.on('pgadmin-storage:finish_btn:' + this.data.dialog_type, this.storage_dlg_hander, this);
|
||||
pgAdmin.Browser.Events.on('pgadmin-storage:cancel_btn:' + this.data.dialog_type, this.storage_close_dlg_hander, this);
|
||||
},
|
||||
remove_file_dlg_event_listeners: function() {
|
||||
pgAdmin.Browser.Events.off('pgadmin-storage:finish_btn:' + this.data.dialog_type, this.storage_dlg_hander, this);
|
||||
pgAdmin.Browser.Events.off('pgadmin-storage:cancel_btn:' + this.data.dialog_type, this.storage_close_dlg_hander, this);
|
||||
},
|
||||
onValidate: function() {
|
||||
var model = this.model,
|
||||
val = this.formatter.toRaw(this.$input.prop('value'), model);
|
||||
|
||||
if (_.isNull(val) || val.trim() === '') {
|
||||
Alertify.alert(gettext('Validate Path'), gettext('Path should not be empty.'));
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: url_for('misc.validate_binary_path'),
|
||||
method: 'POST',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify({
|
||||
'utility_path': val,
|
||||
}),
|
||||
})
|
||||
.done(function(res) {
|
||||
Alertify.alert(gettext('Validate binary path'), gettext(res.data));
|
||||
})
|
||||
.fail(function(xhr, error) {
|
||||
Alertify.pgNotifier(error, xhr, gettext('Failed to validate binary path.'));
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
return Backgrid;
|
||||
});
|
||||
|
90
web/pgadmin/static/js/tree/tree_utils.js
Normal file
90
web/pgadmin/static/js/tree/tree_utils.js
Normal file
@ -0,0 +1,90 @@
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2021, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
import gettext from 'sources/gettext';
|
||||
|
||||
export function retrieveAncestorOfTypeServer(pgBrowser, item, errorAlertTitle, alertify) {
|
||||
let serverInformation = null;
|
||||
let aciTreeItem = item || pgBrowser.treeMenu.selected();
|
||||
let treeNode = pgBrowser.treeMenu.findNodeByDomElement(aciTreeItem);
|
||||
|
||||
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) {
|
||||
alertify.alert(
|
||||
gettext(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) {
|
||||
alertify.alert(
|
||||
gettext(errorAlertTitle),
|
||||
gettext('Please select server or child node from the browser tree.')
|
||||
);
|
||||
}
|
||||
|
||||
return serverInformation;
|
||||
}
|
||||
|
||||
export function retrieveAncestorOfTypeDatabase(pgBrowser, item, errorAlertTitle, alertify) {
|
||||
let databaseInfo = null;
|
||||
let aciTreeItem = item || pgBrowser.treeMenu.selected();
|
||||
let treeNode = pgBrowser.treeMenu.findNodeByDomElement(aciTreeItem);
|
||||
|
||||
if (treeNode) {
|
||||
if(treeNode.getData()._type === 'database') {
|
||||
databaseInfo = treeNode.getData();
|
||||
} else {
|
||||
let nodeData = null;
|
||||
treeNode.ancestorNode(
|
||||
(node) => {
|
||||
nodeData = node.getData();
|
||||
if(nodeData._type === 'database') {
|
||||
databaseInfo = nodeData;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (databaseInfo === null) {
|
||||
alertify.alert(
|
||||
gettext(errorAlertTitle),
|
||||
gettext('Please select a database or its child node from the browser.')
|
||||
);
|
||||
}
|
||||
|
||||
return databaseInfo;
|
||||
}
|
@ -10,7 +10,7 @@
|
||||
import _ from 'underscore';
|
||||
import { getTreeNodeHierarchyFromIdentifier } from 'sources/tree/pgadmin_tree_node';
|
||||
import $ from 'jquery';
|
||||
|
||||
import gettext from 'sources/gettext';
|
||||
|
||||
export function parseShortcutValue(obj) {
|
||||
var shortcut = '';
|
||||
@ -360,3 +360,51 @@ export function CSVToArray( strData, strDelimiter, quoteChar){
|
||||
// Return the parsed data.
|
||||
return arrData;
|
||||
}
|
||||
|
||||
export function hasBinariesConfiguration(pgBrowser, serverInformation, alertify) {
|
||||
const module = 'paths';
|
||||
let preference_name = 'pg_bin_dir';
|
||||
let msg = gettext('Please configure the PostgreSQL Binary Path in the Preferences dialog.');
|
||||
|
||||
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 (_.isUndefined(preference.value) || !checkBinaryPathExists(preference.value, serverInformation.version)) {
|
||||
alertify.alert(gettext('Configuration required'), msg);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
alertify.alert(
|
||||
gettext('Preferences Error'),
|
||||
gettext('Failed to load preference %s of module %s', preference_name, module)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function checkBinaryPathExists(binaryPathArray, selectedServerVersion) {
|
||||
let foundDefaultPath = false,
|
||||
serverSpecificPathExist = false,
|
||||
binPathArray = JSON.parse(binaryPathArray);
|
||||
|
||||
_.each(binPathArray, function(binPath) {
|
||||
if (selectedServerVersion >= binPath.version && selectedServerVersion < binPath.next_major_version) {
|
||||
if (!_.isUndefined(binPath.binaryPath) && !_.isNull(binPath.binaryPath) && binPath.binaryPath.trim() !== '')
|
||||
serverSpecificPathExist = true;
|
||||
}
|
||||
|
||||
// Check for default path
|
||||
if (binPath.isDefault) {
|
||||
foundDefaultPath = true;
|
||||
}
|
||||
});
|
||||
|
||||
return (serverSpecificPathExist | foundDefaultPath);
|
||||
}
|
||||
|
@ -12,6 +12,8 @@ import Backform from '../../../../static/js/backform.pgadmin';
|
||||
import {Dialog} from '../../../../static/js/alertify/dialog';
|
||||
import url_for from 'sources/url_for';
|
||||
import axios from 'axios/index';
|
||||
import {retrieveAncestorOfTypeServer} from 'sources/tree/tree_utils';
|
||||
import {hasBinariesConfiguration} from 'sources/utils';
|
||||
|
||||
export class BackupDialog extends Dialog {
|
||||
constructor(pgBrowser, $, alertify, BackupModel, backform = Backform) {
|
||||
@ -29,13 +31,13 @@ export class BackupDialog extends Dialog {
|
||||
}
|
||||
|
||||
draw(action, aciTreeItem, params, width=0, height=0) {
|
||||
const serverInformation = this.retrieveAncestorOfTypeServer(aciTreeItem);
|
||||
const serverInformation = retrieveAncestorOfTypeServer(this.pgBrowser, aciTreeItem, gettext('Backup Error'), this.alertify);
|
||||
|
||||
if (!serverInformation) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.hasBinariesConfiguration(serverInformation)) {
|
||||
if (!hasBinariesConfiguration(this.pgBrowser, serverInformation, this.alertify)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -444,25 +444,7 @@ define([
|
||||
return;
|
||||
}
|
||||
|
||||
var module = 'paths',
|
||||
preference_name = 'pg_bin_dir',
|
||||
msg = gettext('Please configure the PostgreSQL Binary Path in the Preferences dialog.');
|
||||
|
||||
if ((server_data.type && server_data.type == 'ppas') ||
|
||||
server_data.server_type == 'ppas') {
|
||||
preference_name = 'ppas_bin_dir';
|
||||
msg = gettext('Please configure the EDB Advanced Server Binary Path in the Preferences dialog.');
|
||||
}
|
||||
|
||||
var preference = pgBrowser.get_preference(module, preference_name);
|
||||
|
||||
if (preference) {
|
||||
if (!preference.value) {
|
||||
Alertify.alert(gettext('Configuration required'), msg);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
Alertify.alert(gettext('Failed to load preference %s of module %s', preference_name, module));
|
||||
if (!commonUtils.hasBinariesConfiguration(pgBrowser, server_data, Alertify)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -221,25 +221,7 @@ define([
|
||||
return;
|
||||
}
|
||||
|
||||
var module = 'paths',
|
||||
preference_name = 'pg_bin_dir',
|
||||
msg = gettext('Please configure the PostgreSQL Binary Path in the Preferences dialog.');
|
||||
|
||||
if ((server_data.type && server_data.type == 'ppas') ||
|
||||
server_data.server_type == 'ppas') {
|
||||
preference_name = 'ppas_bin_dir';
|
||||
msg = gettext('Please configure the EDB Advanced Server Binary Path in the Preferences dialog.');
|
||||
}
|
||||
|
||||
var preference = pgBrowser.get_preference(module, preference_name);
|
||||
|
||||
if (preference) {
|
||||
if (!preference.value) {
|
||||
Alertify.alert(gettext('Configuration required'), msg);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
Alertify.alert(gettext('Failed to load preference %s of module %s', preference_name, module));
|
||||
if (!commonUtils.hasBinariesConfiguration(pgBrowser, server_data, Alertify)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,8 @@ 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 {getRandomInt, hasBinariesConfiguration} from 'sources/utils';
|
||||
import {retrieveAncestorOfTypeServer} from 'sources/tree/tree_utils';
|
||||
import pgWindow from 'sources/window';
|
||||
|
||||
import {getTreeNodeHierarchyFromIdentifier} from 'sources/tree/pgadmin_tree_node';
|
||||
@ -114,74 +115,12 @@ export function initialize(gettext, url_for, $, _, pgAdmin, csrfToken, Browser)
|
||||
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);
|
||||
const serverInformation = retrieveAncestorOfTypeServer(pgBrowser, aciTreeIdentifier, gettext('PSQL Error'), Alertify);
|
||||
if (!hasBinariesConfiguration(pgBrowser, serverInformation, Alertify)) {
|
||||
return;
|
||||
}
|
||||
|
||||
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(
|
||||
|
@ -12,6 +12,8 @@ import Backform from '../../../../static/js/backform.pgadmin';
|
||||
import {Dialog} from '../../../../static/js/alertify/dialog';
|
||||
import url_for from 'sources/url_for';
|
||||
import axios from 'axios/index';
|
||||
import {retrieveAncestorOfTypeServer} from 'sources/tree/tree_utils';
|
||||
import {hasBinariesConfiguration} from 'sources/utils';
|
||||
|
||||
export class RestoreDialog extends Dialog {
|
||||
constructor(pgBrowser, $, alertify, RestoreModel, backform = Backform) {
|
||||
@ -27,14 +29,12 @@ export class RestoreDialog extends Dialog {
|
||||
}
|
||||
|
||||
draw(action, aciTreeItem, width, height) {
|
||||
|
||||
const serverInformation = this.retrieveAncestorOfTypeServer(aciTreeItem);
|
||||
|
||||
const serverInformation = retrieveAncestorOfTypeServer(this.pgBrowser, aciTreeItem, gettext('Restore Error'), this.alertify);
|
||||
if (!serverInformation) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.hasBinariesConfiguration(serverInformation)) {
|
||||
if (!hasBinariesConfiguration(this.pgBrowser, serverInformation, this.alertify)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
import gettext from 'sources/gettext';
|
||||
import {Dialog} from 'sources/alertify/dialog';
|
||||
import {getPanelTitle} from 'tools/datagrid/static/js/datagrid_panel_title';
|
||||
import {retrieveAncestorOfTypeDatabase} from 'sources/tree/tree_utils';
|
||||
|
||||
export default class SearchObjectsDialog extends Dialog {
|
||||
constructor(pgBrowser, $, alertify, BackupModel, backform = null) {
|
||||
@ -24,7 +25,7 @@ export default class SearchObjectsDialog extends Dialog {
|
||||
}
|
||||
|
||||
draw(action, aciTreeItem, params, width=0, height=0) {
|
||||
let dbInfo = this.retrieveAncestorOfTypeDatabase(aciTreeItem);
|
||||
let dbInfo = retrieveAncestorOfTypeDatabase(this.pgBrowser, aciTreeItem, gettext('Search Objects Error'), this.alertify);
|
||||
if (!dbInfo) {
|
||||
return;
|
||||
}
|
||||
|
@ -437,7 +437,7 @@ class Preferences(object):
|
||||
assert _type in (
|
||||
'boolean', 'integer', 'numeric', 'date', 'datetime',
|
||||
'options', 'multiline', 'switch', 'node', 'text', 'radioModern',
|
||||
'keyboardshortcut', 'select2'
|
||||
'keyboardshortcut', 'select2', 'selectFile',
|
||||
), "Type cannot be found in the defined list!"
|
||||
|
||||
(cat['preferences'])[name] = res = _Preference(
|
||||
|
@ -68,6 +68,9 @@ describe('BackupDialog', () => {
|
||||
data: {
|
||||
_id: 10,
|
||||
_type: 'server',
|
||||
label: 'some-tree-label',
|
||||
server_type: 'pg',
|
||||
version: 100000,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
@ -88,14 +91,34 @@ describe('BackupDialog', () => {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'serverTreeNodeWrongPath',
|
||||
data: {
|
||||
_id: 12,
|
||||
_type: 'server',
|
||||
label: 'some-tree-label',
|
||||
server_type: 'pg',
|
||||
version: 90600,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'ppasServer',
|
||||
data: {
|
||||
_id: 13,
|
||||
_type: 'server',
|
||||
label: 'some-tree-label',
|
||||
server_type: 'ppas',
|
||||
children: [
|
||||
{id: 'someNodeUnderneathPPASServer'},
|
||||
],
|
||||
version: 130000,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'ppasServerTreeNodeWrongPath',
|
||||
data: {
|
||||
_id: 14,
|
||||
_type: 'server',
|
||||
label: 'some-tree-label',
|
||||
server_type: 'ppas',
|
||||
version: 90600,
|
||||
},
|
||||
},
|
||||
],
|
||||
@ -148,52 +171,42 @@ describe('BackupDialog', () => {
|
||||
pgBrowser.get_preference.and.returnValue(undefined);
|
||||
});
|
||||
|
||||
context('server is a ppas server', () => {
|
||||
it('display an alert with "Backup Error"', () => {
|
||||
backupDialog.draw(null, [{id: 'some_database'}], null);
|
||||
context('server is a PostgreSQL server', () => {
|
||||
it('display an alert with "Preferences Error"', () => {
|
||||
backupDialog.draw(null, [{id: 'serverTreeNode'}], null);
|
||||
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
||||
'Backup Error',
|
||||
'Preferences Error',
|
||||
'Failed to load preference pg_bin_dir of module paths'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
context('server is not a ppas server', () => {
|
||||
it('display an alert with "Backup Error"', () => {
|
||||
context('server is a EPAS server', () => {
|
||||
it('display an alert with "Preferences Error"', () => {
|
||||
backupDialog.draw(null, [{id: 'ppasServer'}], null);
|
||||
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
||||
'Backup Error',
|
||||
'Preferences Error',
|
||||
'Failed to load preference ppas_bin_dir of module paths'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('preference can be found', () => {
|
||||
context('preference can be found for PostgreSQL Server', () => {
|
||||
context('binary folder is not configured', () => {
|
||||
beforeEach(() => {
|
||||
pgBrowser.get_preference.and.returnValue({});
|
||||
pgBrowser.get_preference.and.returnValue({value: '[{\"serverType\":\"PostgreSQL 9.6\",\"binaryPath\":null,\"isDefault\":false,\"version\":\"90600\",\"next_major_version\":\"100000\"},{\"serverType\":\"PostgreSQL 10\",\"binaryPath\":\"/Library/PostgreSQL/10/bin\",\"isDefault\":false,\"version\":\"100000\",\"next_major_version\":\"110000\"},{\"serverType\":\"PostgreSQL 11\",\"binaryPath\":\"/Library/PostgreSQL/11/bin\",\"isDefault\":false,\"version\":\"110000\",\"next_major_version\":\"120000\"},{\"serverType\":\"PostgreSQL 12\",\"binaryPath\":\"/Library/PostgreSQL/12/bin\",\"isDefault\":false,\"version\":\"120000\",\"next_major_version\":\"130000\"},{\"serverType\":\"PostgreSQL 13\",\"binaryPath\":null,\"isDefault\":false,\"version\":\"130000\",\"next_major_version\":\"140000\"}]'});
|
||||
});
|
||||
|
||||
context('server is a ppas server', () => {
|
||||
context('server is a PostgreSQL server', () => {
|
||||
it('display an alert with "Configuration required"', () => {
|
||||
backupDialog.draw(null, [{id: 'serverTreeNode'}], null);
|
||||
backupDialog.draw(null, [{id: 'serverTreeNodeWrongPath'}], null);
|
||||
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
||||
'Configuration required',
|
||||
'Please configure the PostgreSQL Binary Path in the Preferences dialog.'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
context('server is not a ppas server', () => {
|
||||
it('display an alert with "Configuration required"', () => {
|
||||
backupDialog.draw(null, [{id: 'ppasServer'}], null);
|
||||
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
||||
'Configuration required',
|
||||
'Please configure the EDB Advanced Server Binary Path in the Preferences dialog.'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('binary folder is configured', () => {
|
||||
@ -202,12 +215,12 @@ describe('BackupDialog', () => {
|
||||
backupDialogResizeToSpy = jasmine.createSpyObj('backupDialogResizeToSpy', ['resizeTo']);
|
||||
alertifySpy['backup_objects'].and
|
||||
.returnValue(backupDialogResizeToSpy);
|
||||
pgBrowser.get_preference.and.returnValue({value: '/some/path'});
|
||||
pgBrowser.get_preference.and.returnValue({value: '[{\"serverType\":\"PostgreSQL 9.6\",\"binaryPath\":null,\"isDefault\":false,\"version\":\"90600\",\"next_major_version\":\"100000\"},{\"serverType\":\"PostgreSQL 10\",\"binaryPath\":\"/Library/PostgreSQL/10/bin\",\"isDefault\":true,\"version\":\"100000\",\"next_major_version\":\"110000\"},{\"serverType\":\"PostgreSQL 11\",\"binaryPath\":\"/Library/PostgreSQL/11/bin\",\"isDefault\":false,\"version\":\"110000\",\"next_major_version\":\"120000\"},{\"serverType\":\"PostgreSQL 12\",\"binaryPath\":\"/Library/PostgreSQL/12/bin\",\"isDefault\":false,\"version\":\"120000\",\"next_major_version\":\"130000\"},{\"serverType\":\"PostgreSQL 13\",\"binaryPath\":null,\"isDefault\":false,\"version\":\"130000\",\"next_major_version\":\"140000\"}]'});
|
||||
spyOn(backupDialog, 'url_for_utility_exists').and.returnValue('/backup/utility_exists/10/objects');
|
||||
networkMock.onGet('/backup/utility_exists/10/objects').reply(200, {'success': 1});
|
||||
});
|
||||
|
||||
it('displays the dialog', (done) => {
|
||||
it('displays the dialog when binary path is for correct server version', (done) => {
|
||||
backupDialog.draw(null, [{id: 'serverTreeNode'}], null, pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
setTimeout(() => {
|
||||
expect(alertifySpy['backup_objects']).toHaveBeenCalledWith(true);
|
||||
@ -216,6 +229,15 @@ describe('BackupDialog', () => {
|
||||
}, 0);
|
||||
});
|
||||
|
||||
it('displays the dialog when default binary path is specified', (done) => {
|
||||
backupDialog.draw(null, [{id: 'serverTreeNodeWrongPath'}], null, pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
setTimeout(() => {
|
||||
expect(alertifySpy['backup_objects']).toHaveBeenCalledWith(true);
|
||||
expect(backupDialogResizeToSpy.resizeTo).toHaveBeenCalledWith(pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
|
||||
context('database label contain "="', () => {
|
||||
it('should create alert dialog with backup error', (done) => {
|
||||
backupDialog.draw(null, [{id: 'database_with_equal_in_name'}], null);
|
||||
@ -228,6 +250,54 @@ describe('BackupDialog', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('preference can be found for EPAS server', () => {
|
||||
context('binary folder is not configured', () => {
|
||||
beforeEach(() => {
|
||||
pgBrowser.get_preference.and.returnValue({value: '[{\"serverType\":\"EDB Advanced Server 9.6\",\"binaryPath\":\"\",\"isDefault\":false,\"version\":\"90600\",\"next_major_version\":\"100000\"},{\"serverType\":\"EDB Advanced Server 10\",\"binaryPath\":null,\"isDefault\":false,\"version\":\"100000\",\"next_major_version\":\"110000\"},{\"serverType\":\"EDB Advanced Server 11\",\"binaryPath\":\"/Library/EPAS/11/bin/\",\"isDefault\":false,\"version\":\"110000\",\"next_major_version\":\"120000\"},{\"serverType\":\"EDB Advanced Server 12\",\"binaryPath\":null,\"isDefault\":false,\"version\":\"120000\",\"next_major_version\":\"130000\"},{\"serverType\":\"EDB Advanced Server 13\",\"binaryPath\":\"/Library/EPAS/13/bin/\",\"isDefault\":false,\"version\":\"130000\",\"next_major_version\":\"140000\"}]'});
|
||||
});
|
||||
|
||||
context('server is a EPAS server', () => {
|
||||
it('display an alert with "Configuration required"', () => {
|
||||
backupDialog.draw(null, [{id: 'ppasServerTreeNodeWrongPath'}], null);
|
||||
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
||||
'Configuration required',
|
||||
'Please configure the EDB Advanced Server Binary Path in the Preferences dialog.'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('binary folder is configured', () => {
|
||||
let backupDialogResizeToSpy;
|
||||
beforeEach(() => {
|
||||
backupDialogResizeToSpy = jasmine.createSpyObj('backupDialogResizeToSpy', ['resizeTo']);
|
||||
alertifySpy['backup_objects'].and
|
||||
.returnValue(backupDialogResizeToSpy);
|
||||
pgBrowser.get_preference.and.returnValue({value: '[{\"serverType\":\"EDB Advanced Server 9.6\",\"binaryPath\":\"\",\"isDefault\":false,\"version\":\"90600\",\"next_major_version\":\"100000\"},{\"serverType\":\"EDB Advanced Server 10\",\"binaryPath\":null,\"isDefault\":false,\"version\":\"100000\",\"next_major_version\":\"110000\"},{\"serverType\":\"EDB Advanced Server 11\",\"binaryPath\":\"/Library/EPAS/11/bin/\",\"isDefault\":false,\"version\":\"110000\",\"next_major_version\":\"120000\"},{\"serverType\":\"EDB Advanced Server 12\",\"binaryPath\":null,\"isDefault\":false,\"version\":\"120000\",\"next_major_version\":\"130000\"},{\"serverType\":\"EDB Advanced Server 13\",\"binaryPath\":\"/Library/EPAS/13/bin/\",\"isDefault\":true,\"version\":\"130000\",\"next_major_version\":\"140000\"}]'});
|
||||
spyOn(backupDialog, 'url_for_utility_exists').and.returnValue('/backup/utility_exists/10/objects');
|
||||
networkMock.onGet('/backup/utility_exists/10/objects').reply(200, {'success': 1});
|
||||
});
|
||||
|
||||
it('displays the dialog when binary path is for correct server version', (done) => {
|
||||
backupDialog.draw(null, [{id: 'ppasServer'}], null, pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
setTimeout(() => {
|
||||
expect(alertifySpy['backup_objects']).toHaveBeenCalledWith(true);
|
||||
expect(backupDialogResizeToSpy.resizeTo).toHaveBeenCalledWith(pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
|
||||
it('displays the dialog when default binary path is specified', (done) => {
|
||||
backupDialog.draw(null, [{id: 'ppasServerTreeNodeWrongPath'}], null, pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
setTimeout(() => {
|
||||
expect(alertifySpy['backup_objects']).toHaveBeenCalledWith(true);
|
||||
expect(backupDialogResizeToSpy.resizeTo).toHaveBeenCalledWith(pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -21,8 +21,8 @@ describe('GlobalServerBackupDialog', () => {
|
||||
let backupModelSpy;
|
||||
|
||||
let rootNode;
|
||||
let serverTreeNode;
|
||||
let ppasServerTreeNode;
|
||||
let serverTreeNode, serverTreeNodeWrongPath;
|
||||
let ppasServerTreeNode, ppasServerTreeNodeWrongPath;
|
||||
|
||||
beforeEach(() => {
|
||||
pgBrowser = {
|
||||
@ -51,12 +51,26 @@ describe('GlobalServerBackupDialog', () => {
|
||||
serverTreeNode = pgBrowser.treeMenu.addNewNode('level1.1', {
|
||||
_type: 'server',
|
||||
_id: 10,
|
||||
server_type: 'pg',
|
||||
version: 100000,
|
||||
}, undefined, ['level1']);
|
||||
ppasServerTreeNode = pgBrowser.treeMenu.addNewNode('level1.2', {
|
||||
serverTreeNodeWrongPath = pgBrowser.treeMenu.addNewNode('level1.2', {
|
||||
_type: 'server',
|
||||
_id: 11,
|
||||
server_type: 'pg',
|
||||
version: 90600,
|
||||
}, undefined, ['level1']);
|
||||
ppasServerTreeNode = pgBrowser.treeMenu.addNewNode('level1.3', {
|
||||
_type: 'server',
|
||||
server_type: 'ppas',
|
||||
version: 130000,
|
||||
}, undefined, ['level1']);
|
||||
pgBrowser.treeMenu.addNewNode('level3', {}, undefined, ['level1', 'level1.2']);
|
||||
ppasServerTreeNodeWrongPath = pgBrowser.treeMenu.addNewNode('level1.4', {
|
||||
_type: 'server',
|
||||
server_type: 'ppas',
|
||||
version: 90600,
|
||||
}, undefined, ['level1']);
|
||||
pgBrowser.treeMenu.addNewNode('level3', {}, undefined, ['level1', 'level1.2', 'level1.3', 'level1.4']);
|
||||
pgBrowser.treeMenu.addNewNode('level3.1', undefined, undefined, ['level1', 'level1.2', 'level3']);
|
||||
});
|
||||
|
||||
@ -73,6 +87,7 @@ describe('GlobalServerBackupDialog', () => {
|
||||
alertifySpy,
|
||||
backupModelSpy
|
||||
);
|
||||
|
||||
pgBrowser.get_preference = jasmine.createSpy('get_preferences');
|
||||
});
|
||||
|
||||
@ -103,46 +118,113 @@ describe('GlobalServerBackupDialog', () => {
|
||||
pgBrowser.get_preference.and.returnValue(undefined);
|
||||
});
|
||||
|
||||
context('server is a ppas server', () => {
|
||||
it('display an alert with "Backup Error"', () => {
|
||||
context('server is a PostgreSQL server', () => {
|
||||
it('display an alert with "Preferences Error"', () => {
|
||||
backupDialog.draw(null, [serverTreeNode], null);
|
||||
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
||||
'Backup Error',
|
||||
'Preferences Error',
|
||||
'Failed to load preference pg_bin_dir of module paths'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
context('server is not a ppas server', () => {
|
||||
it('display an alert with "Backup Error"', () => {
|
||||
context('server is a EPAS server', () => {
|
||||
it('display an alert with "Preferences Error"', () => {
|
||||
backupDialog.draw(null, [ppasServerTreeNode], null);
|
||||
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
||||
'Backup Error',
|
||||
'Preferences Error',
|
||||
'Failed to load preference ppas_bin_dir of module paths'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('preference can be found', () => {
|
||||
context('preference can be found for PostgreSQL Server', () => {
|
||||
context('binary folder is not configured', () => {
|
||||
beforeEach(() => {
|
||||
pgBrowser.get_preference.and.returnValue({});
|
||||
pgBrowser.get_preference.and.returnValue({value: '[{\"serverType\":\"PostgreSQL 9.6\",\"binaryPath\":null,\"isDefault\":false,\"version\":\"90600\",\"next_major_version\":\"100000\"},{\"serverType\":\"PostgreSQL 10\",\"binaryPath\":\"/Library/PostgreSQL/10/bin\",\"isDefault\":false,\"version\":\"100000\",\"next_major_version\":\"110000\"},{\"serverType\":\"PostgreSQL 11\",\"binaryPath\":\"/Library/PostgreSQL/11/bin\",\"isDefault\":false,\"version\":\"110000\",\"next_major_version\":\"120000\"},{\"serverType\":\"PostgreSQL 12\",\"binaryPath\":\"/Library/PostgreSQL/12/bin\",\"isDefault\":false,\"version\":\"120000\",\"next_major_version\":\"130000\"},{\"serverType\":\"PostgreSQL 13\",\"binaryPath\":null,\"isDefault\":false,\"version\":\"130000\",\"next_major_version\":\"140000\"}]'});
|
||||
});
|
||||
|
||||
context('server is a ppas server', () => {
|
||||
context('server is a PostgreSQL server', () => {
|
||||
it('display an alert with "Configuration required"', () => {
|
||||
backupDialog.draw(null, [serverTreeNode], null);
|
||||
backupDialog.draw(null, [serverTreeNodeWrongPath], null);
|
||||
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
||||
'Configuration required',
|
||||
'Please configure the PostgreSQL Binary Path in the Preferences dialog.'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('server is not a ppas server', () => {
|
||||
context('binary folder is configured', () => {
|
||||
let globalResizeToSpy;
|
||||
let serverResizeToSpy;
|
||||
beforeEach(() => {
|
||||
globalResizeToSpy = jasmine.createSpyObj('globals', ['resizeTo']);
|
||||
alertifySpy['BackupDialog_globals'].and
|
||||
.returnValue(globalResizeToSpy);
|
||||
serverResizeToSpy = jasmine.createSpyObj('server', ['resizeTo']);
|
||||
alertifySpy['BackupDialog_server'].and
|
||||
.returnValue(serverResizeToSpy);
|
||||
pgBrowser.get_preference.and.returnValue({value: '[{\"serverType\":\"PostgreSQL 9.6\",\"binaryPath\":null,\"isDefault\":false,\"version\":\"90600\",\"next_major_version\":\"100000\"},{\"serverType\":\"PostgreSQL 10\",\"binaryPath\":\"/Library/PostgreSQL/10/bin\",\"isDefault\":true,\"version\":\"100000\",\"next_major_version\":\"110000\"},{\"serverType\":\"PostgreSQL 11\",\"binaryPath\":\"/Library/PostgreSQL/11/bin\",\"isDefault\":false,\"version\":\"110000\",\"next_major_version\":\"120000\"},{\"serverType\":\"PostgreSQL 12\",\"binaryPath\":\"/Library/PostgreSQL/12/bin\",\"isDefault\":false,\"version\":\"120000\",\"next_major_version\":\"130000\"},{\"serverType\":\"PostgreSQL 13\",\"binaryPath\":null,\"isDefault\":false,\"version\":\"130000\",\"next_major_version\":\"140000\"}]'});
|
||||
spyOn(backupDialog, 'url_for_utility_exists').and.returnValue('/backup/utility_exists/10/servers');
|
||||
networkMock.onGet('/backup/utility_exists/10/servers').reply(200, {'success': 1});
|
||||
});
|
||||
|
||||
context('dialog for global backup ', () => {
|
||||
it('displays the dialog when binary path is for correct server version', (done) => {
|
||||
backupDialog.draw(null, [serverTreeNode], {globals: true}, pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
setTimeout(() => {
|
||||
expect(alertifySpy['BackupDialog_globals']).toHaveBeenCalledWith(true);
|
||||
expect(globalResizeToSpy.resizeTo).toHaveBeenCalledWith(pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
|
||||
context('dialog for server backup', () => {
|
||||
it('displays the dialog when binary path is for correct server version', (done) => {
|
||||
backupDialog.draw(null, [serverTreeNode], {server: true}, pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
setTimeout(() => {
|
||||
expect(alertifySpy['BackupDialog_server']).toHaveBeenCalledWith(true);
|
||||
expect(serverResizeToSpy.resizeTo).toHaveBeenCalledWith(pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
|
||||
context('dialog for global backup ', () => {
|
||||
it('displays the dialog when default binary path is specified', (done) => {
|
||||
backupDialog.draw(null, [serverTreeNodeWrongPath], {globals: true}, pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
setTimeout(() => {
|
||||
expect(alertifySpy['BackupDialog_globals']).toHaveBeenCalledWith(true);
|
||||
expect(globalResizeToSpy.resizeTo).toHaveBeenCalledWith(pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
|
||||
context('dialog for server backup', () => {
|
||||
it('displays the dialog when default binary path is specified', (done) => {
|
||||
backupDialog.draw(null, [serverTreeNodeWrongPath], {server: true}, pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
setTimeout(() => {
|
||||
expect(alertifySpy['BackupDialog_server']).toHaveBeenCalledWith(true);
|
||||
expect(serverResizeToSpy.resizeTo).toHaveBeenCalledWith(pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
context('preference can be found for EPAS Server', () => {
|
||||
context('binary folder is not configured', () => {
|
||||
beforeEach(() => {
|
||||
pgBrowser.get_preference.and.returnValue({value: '[{\"serverType\":\"EDB Advanced Server 9.6\",\"binaryPath\":\"\",\"isDefault\":false,\"version\":\"90600\",\"next_major_version\":\"100000\"},{\"serverType\":\"EDB Advanced Server 10\",\"binaryPath\":null,\"isDefault\":false,\"version\":\"100000\",\"next_major_version\":\"110000\"},{\"serverType\":\"EDB Advanced Server 11\",\"binaryPath\":\"/Library/EPAS/11/bin/\",\"isDefault\":false,\"version\":\"110000\",\"next_major_version\":\"120000\"},{\"serverType\":\"EDB Advanced Server 12\",\"binaryPath\":null,\"isDefault\":false,\"version\":\"120000\",\"next_major_version\":\"130000\"},{\"serverType\":\"EDB Advanced Server 13\",\"binaryPath\":\"/Library/EPAS/13/bin/\",\"isDefault\":false,\"version\":\"130000\",\"next_major_version\":\"140000\"}]'});
|
||||
});
|
||||
|
||||
context('server is a EPAS server', () => {
|
||||
it('display an alert with "Configuration required"', () => {
|
||||
backupDialog.draw(null, [ppasServerTreeNode], null);
|
||||
backupDialog.draw(null, [ppasServerTreeNodeWrongPath], null);
|
||||
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
||||
'Configuration required',
|
||||
'Please configure the EDB Advanced Server Binary Path in the Preferences dialog.'
|
||||
@ -161,14 +243,14 @@ describe('GlobalServerBackupDialog', () => {
|
||||
serverResizeToSpy = jasmine.createSpyObj('server', ['resizeTo']);
|
||||
alertifySpy['BackupDialog_server'].and
|
||||
.returnValue(serverResizeToSpy);
|
||||
pgBrowser.get_preference.and.returnValue({value: '/some/path'});
|
||||
pgBrowser.get_preference.and.returnValue({value: '[{\"serverType\":\"EDB Advanced Server 9.6\",\"binaryPath\":\"\",\"isDefault\":false,\"version\":\"90600\",\"next_major_version\":\"100000\"},{\"serverType\":\"EDB Advanced Server 10\",\"binaryPath\":null,\"isDefault\":false,\"version\":\"100000\",\"next_major_version\":\"110000\"},{\"serverType\":\"EDB Advanced Server 11\",\"binaryPath\":\"/Library/EPAS/11/bin/\",\"isDefault\":false,\"version\":\"110000\",\"next_major_version\":\"120000\"},{\"serverType\":\"EDB Advanced Server 12\",\"binaryPath\":null,\"isDefault\":false,\"version\":\"120000\",\"next_major_version\":\"130000\"},{\"serverType\":\"EDB Advanced Server 13\",\"binaryPath\":\"/Library/EPAS/13/bin/\",\"isDefault\":true,\"version\":\"130000\",\"next_major_version\":\"140000\"}]'});
|
||||
spyOn(backupDialog, 'url_for_utility_exists').and.returnValue('/backup/utility_exists/10/servers');
|
||||
networkMock.onGet('/backup/utility_exists/10/servers').reply(200, {'success': 1});
|
||||
});
|
||||
|
||||
context('dialog for global backup', () => {
|
||||
it('displays the dialog', (done) => {
|
||||
backupDialog.draw(null, [serverTreeNode], {globals: true}, pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
context('dialog for global backup ', () => {
|
||||
it('displays the dialog when binary path is for correct server version', (done) => {
|
||||
backupDialog.draw(null, [ppasServerTreeNode], {globals: true}, pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
setTimeout(() => {
|
||||
expect(alertifySpy['BackupDialog_globals']).toHaveBeenCalledWith(true);
|
||||
expect(globalResizeToSpy.resizeTo).toHaveBeenCalledWith(pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
@ -178,8 +260,30 @@ describe('GlobalServerBackupDialog', () => {
|
||||
});
|
||||
|
||||
context('dialog for server backup', () => {
|
||||
it('displays the dialog', (done) => {
|
||||
backupDialog.draw(null, [serverTreeNode], {server: true}, pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
it('displays the dialog when binary path is for correct server version', (done) => {
|
||||
backupDialog.draw(null, [ppasServerTreeNode], {server: true}, pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
setTimeout(() => {
|
||||
expect(alertifySpy['BackupDialog_server']).toHaveBeenCalledWith(true);
|
||||
expect(serverResizeToSpy.resizeTo).toHaveBeenCalledWith(pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
|
||||
context('dialog for global backup ', () => {
|
||||
it('displays the dialog when default binary path is specified', (done) => {
|
||||
backupDialog.draw(null, [ppasServerTreeNodeWrongPath], {globals: true}, pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
setTimeout(() => {
|
||||
expect(alertifySpy['BackupDialog_globals']).toHaveBeenCalledWith(true);
|
||||
expect(globalResizeToSpy.resizeTo).toHaveBeenCalledWith(pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
|
||||
context('dialog for server backup', () => {
|
||||
it('displays the dialog when default binary path is specified', (done) => {
|
||||
backupDialog.draw(null, [ppasServerTreeNodeWrongPath], {server: true}, pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
setTimeout(() => {
|
||||
expect(alertifySpy['BackupDialog_server']).toHaveBeenCalledWith(true);
|
||||
expect(serverResizeToSpy.resizeTo).toHaveBeenCalledWith(pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
|
@ -56,6 +56,8 @@ describe('RestoreDialog', () => {
|
||||
_id: 10,
|
||||
_type: 'server',
|
||||
label: 'some-tree-label',
|
||||
server_type: 'pg',
|
||||
version: 100000,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
@ -76,14 +78,34 @@ describe('RestoreDialog', () => {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'serverTreeNodeWrongPath',
|
||||
data: {
|
||||
_id: 12,
|
||||
_type: 'server',
|
||||
label: 'some-tree-label',
|
||||
server_type: 'pg',
|
||||
version: 90600,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'ppasServer',
|
||||
data: {
|
||||
_id: 13,
|
||||
_type: 'server',
|
||||
label: 'some-tree-label',
|
||||
server_type: 'ppas',
|
||||
children: [
|
||||
{id: 'someNodeUnderneathPPASServer'},
|
||||
],
|
||||
version: 130000,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'ppasServerTreeNodeWrongPath',
|
||||
data: {
|
||||
_id: 14,
|
||||
_type: 'server',
|
||||
label: 'some-tree-label',
|
||||
server_type: 'ppas',
|
||||
version: 90600,
|
||||
},
|
||||
},
|
||||
],
|
||||
@ -136,52 +158,42 @@ describe('RestoreDialog', () => {
|
||||
pgBrowser.get_preference.and.returnValue(undefined);
|
||||
});
|
||||
|
||||
context('server is a ppas server', () => {
|
||||
it('display an alert with "Restore Error"', () => {
|
||||
context('server is a PostgreSQL server', () => {
|
||||
it('display an alert with "Preferences Error"', () => {
|
||||
restoreDialog.draw(null, [{id: 'serverTreeNode'}], null);
|
||||
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
||||
'Restore Error',
|
||||
'Preferences Error',
|
||||
'Failed to load preference pg_bin_dir of module paths'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
context('server is not a ppas server', () => {
|
||||
it('display an alert with "Restore Error"', () => {
|
||||
context('server is a EPAS server', () => {
|
||||
it('display an alert with "Preferences Error"', () => {
|
||||
restoreDialog.draw(null, [{id: 'ppasServer'}], null);
|
||||
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
||||
'Restore Error',
|
||||
'Preferences Error',
|
||||
'Failed to load preference ppas_bin_dir of module paths'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('preference can be found', () => {
|
||||
context('preference can be found for PostgreSQL Server', () => {
|
||||
context('binary folder is not configured', () => {
|
||||
beforeEach(() => {
|
||||
pgBrowser.get_preference.and.returnValue({});
|
||||
pgBrowser.get_preference.and.returnValue({value: '[{\"serverType\":\"PostgreSQL 9.6\",\"binaryPath\":null,\"isDefault\":false,\"version\":\"90600\",\"next_major_version\":\"100000\"},{\"serverType\":\"PostgreSQL 10\",\"binaryPath\":\"/Library/PostgreSQL/10/bin\",\"isDefault\":false,\"version\":\"100000\",\"next_major_version\":\"110000\"},{\"serverType\":\"PostgreSQL 11\",\"binaryPath\":\"/Library/PostgreSQL/11/bin\",\"isDefault\":false,\"version\":\"110000\",\"next_major_version\":\"120000\"},{\"serverType\":\"PostgreSQL 12\",\"binaryPath\":\"/Library/PostgreSQL/12/bin\",\"isDefault\":false,\"version\":\"120000\",\"next_major_version\":\"130000\"},{\"serverType\":\"PostgreSQL 13\",\"binaryPath\":null,\"isDefault\":false,\"version\":\"130000\",\"next_major_version\":\"140000\"}]'});
|
||||
});
|
||||
|
||||
context('server is a ppas server', () => {
|
||||
context('server is a PostgreSQL server', () => {
|
||||
it('display an alert with "Configuration required"', () => {
|
||||
restoreDialog.draw(null, [{id: 'serverTreeNode'}], null);
|
||||
restoreDialog.draw(null, [{id: 'serverTreeNodeWrongPath'}], null);
|
||||
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
||||
'Configuration required',
|
||||
'Please configure the PostgreSQL Binary Path in the Preferences dialog.'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
context('server is not a ppas server', () => {
|
||||
it('display an alert with "Configuration required"', () => {
|
||||
restoreDialog.draw(null, [{id: 'ppasServer'}], null);
|
||||
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
||||
'Configuration required',
|
||||
'Please configure the EDB Advanced Server Binary Path in the Preferences dialog.'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('binary folder is configured', () => {
|
||||
@ -190,13 +202,13 @@ describe('RestoreDialog', () => {
|
||||
spy = jasmine.createSpyObj('globals', ['resizeTo']);
|
||||
alertifySpy['pg_restore'].and
|
||||
.returnValue(spy);
|
||||
pgBrowser.get_preference.and.returnValue({value: '/some/path'});
|
||||
pgBrowser.Nodes.server.label = 'some-server-label';
|
||||
pgBrowser.get_preference.and.returnValue({value: '[{\"serverType\":\"PostgreSQL 9.6\",\"binaryPath\":null,\"isDefault\":false,\"version\":\"90600\",\"next_major_version\":\"100000\"},{\"serverType\":\"PostgreSQL 10\",\"binaryPath\":\"/Library/PostgreSQL/10/bin\",\"isDefault\":true,\"version\":\"100000\",\"next_major_version\":\"110000\"},{\"serverType\":\"PostgreSQL 11\",\"binaryPath\":\"/Library/PostgreSQL/11/bin\",\"isDefault\":false,\"version\":\"110000\",\"next_major_version\":\"120000\"},{\"serverType\":\"PostgreSQL 12\",\"binaryPath\":\"/Library/PostgreSQL/12/bin\",\"isDefault\":false,\"version\":\"120000\",\"next_major_version\":\"130000\"},{\"serverType\":\"PostgreSQL 13\",\"binaryPath\":null,\"isDefault\":false,\"version\":\"130000\",\"next_major_version\":\"140000\"}]'});
|
||||
spyOn(restoreDialog, 'url_for_utility_exists').and.returnValue('/restore/utility_exists/10/objects');
|
||||
networkMock.onGet('/restore/utility_exists/10/objects').reply(200, {'success': 1});
|
||||
});
|
||||
|
||||
it('displays the dialog', (done) => {
|
||||
it('displays the dialog when binary path is for correct server version', (done) => {
|
||||
restoreDialog.draw(null, [{id: 'serverTreeNode'}], pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
setTimeout(() => {
|
||||
expect(alertifySpy['pg_restore']).toHaveBeenCalledWith(
|
||||
@ -206,6 +218,28 @@ describe('RestoreDialog', () => {
|
||||
_id: 10,
|
||||
_type: 'server',
|
||||
label: 'some-tree-label',
|
||||
server_type: 'pg',
|
||||
version: 100000,
|
||||
},
|
||||
pgBrowser.Nodes.server
|
||||
);
|
||||
expect(spy.resizeTo).toHaveBeenCalledWith(pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
|
||||
it('displays the dialog when default binary path is specified', (done) => {
|
||||
restoreDialog.draw(null, [{id: 'serverTreeNodeWrongPath'}], pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
setTimeout(() => {
|
||||
expect(alertifySpy['pg_restore']).toHaveBeenCalledWith(
|
||||
'Restore (some-server-label: some-tree-label)',
|
||||
[{id: 'serverTreeNodeWrongPath'}],
|
||||
{
|
||||
_id: 12,
|
||||
_type: 'server',
|
||||
label: 'some-tree-label',
|
||||
server_type: 'pg',
|
||||
version: 90600,
|
||||
},
|
||||
pgBrowser.Nodes.server
|
||||
);
|
||||
@ -226,6 +260,77 @@ describe('RestoreDialog', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('preference can be found for EPAS server', () => {
|
||||
context('binary folder is not configured', () => {
|
||||
beforeEach(() => {
|
||||
pgBrowser.get_preference.and.returnValue({value: '[{\"serverType\":\"EDB Advanced Server 9.6\",\"binaryPath\":\"\",\"isDefault\":false,\"version\":\"90600\",\"next_major_version\":\"100000\"},{\"serverType\":\"EDB Advanced Server 10\",\"binaryPath\":null,\"isDefault\":false,\"version\":\"100000\",\"next_major_version\":\"110000\"},{\"serverType\":\"EDB Advanced Server 11\",\"binaryPath\":\"/Library/EPAS/11/bin/\",\"isDefault\":false,\"version\":\"110000\",\"next_major_version\":\"120000\"},{\"serverType\":\"EDB Advanced Server 12\",\"binaryPath\":null,\"isDefault\":false,\"version\":\"120000\",\"next_major_version\":\"130000\"},{\"serverType\":\"EDB Advanced Server 13\",\"binaryPath\":\"/Library/EPAS/13/bin/\",\"isDefault\":false,\"version\":\"130000\",\"next_major_version\":\"140000\"}]'});
|
||||
});
|
||||
|
||||
context('server is a EPAS server', () => {
|
||||
it('display an alert with "Configuration required"', () => {
|
||||
restoreDialog.draw(null, [{id: 'ppasServerTreeNodeWrongPath'}], null);
|
||||
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
||||
'Configuration required',
|
||||
'Please configure the EDB Advanced Server Binary Path in the Preferences dialog.'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('binary folder is configured', () => {
|
||||
let spy;
|
||||
beforeEach(() => {
|
||||
spy = jasmine.createSpyObj('globals', ['resizeTo']);
|
||||
alertifySpy['pg_restore'].and
|
||||
.returnValue(spy);
|
||||
pgBrowser.Nodes.server.label = 'some-server-label';
|
||||
pgBrowser.get_preference.and.returnValue({value: '[{\"serverType\":\"EDB Advanced Server 9.6\",\"binaryPath\":\"\",\"isDefault\":false,\"version\":\"90600\",\"next_major_version\":\"100000\"},{\"serverType\":\"EDB Advanced Server 10\",\"binaryPath\":null,\"isDefault\":false,\"version\":\"100000\",\"next_major_version\":\"110000\"},{\"serverType\":\"EDB Advanced Server 11\",\"binaryPath\":\"/Library/EPAS/11/bin/\",\"isDefault\":false,\"version\":\"110000\",\"next_major_version\":\"120000\"},{\"serverType\":\"EDB Advanced Server 12\",\"binaryPath\":null,\"isDefault\":false,\"version\":\"120000\",\"next_major_version\":\"130000\"},{\"serverType\":\"EDB Advanced Server 13\",\"binaryPath\":\"/Library/EPAS/13/bin/\",\"isDefault\":true,\"version\":\"130000\",\"next_major_version\":\"140000\"}]'});
|
||||
spyOn(restoreDialog, 'url_for_utility_exists').and.returnValue('/restore/utility_exists/10/objects');
|
||||
networkMock.onGet('/restore/utility_exists/10/objects').reply(200, {'success': 1});
|
||||
});
|
||||
|
||||
it('displays the dialog when binary path is for correct server version', (done) => {
|
||||
restoreDialog.draw(null, [{id: 'ppasServer'}], pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
setTimeout(() => {
|
||||
expect(alertifySpy['pg_restore']).toHaveBeenCalledWith(
|
||||
'Restore (some-server-label: some-tree-label)',
|
||||
[{id: 'ppasServer'}],
|
||||
{
|
||||
_id: 13,
|
||||
_type: 'server',
|
||||
label: 'some-tree-label',
|
||||
server_type: 'ppas',
|
||||
version: 130000,
|
||||
},
|
||||
pgBrowser.Nodes.server
|
||||
);
|
||||
expect(spy.resizeTo).toHaveBeenCalledWith(pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
|
||||
it('displays the dialog when default binary path is specified', (done) => {
|
||||
restoreDialog.draw(null, [{id: 'ppasServerTreeNodeWrongPath'}], pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
setTimeout(() => {
|
||||
expect(alertifySpy['pg_restore']).toHaveBeenCalledWith(
|
||||
'Restore (some-server-label: some-tree-label)',
|
||||
[{id: 'ppasServerTreeNodeWrongPath'}],
|
||||
{
|
||||
_id: 14,
|
||||
_type: 'server',
|
||||
label: 'some-tree-label',
|
||||
server_type: 'ppas',
|
||||
version: 90600,
|
||||
},
|
||||
pgBrowser.Nodes.server
|
||||
);
|
||||
expect(spy.resizeTo).toHaveBeenCalledWith(pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -10,6 +10,7 @@ import SearchObjectsDialog from 'tools/search_objects/static/js/search_objects_d
|
||||
import {TreeFake} from '../tree/tree_fake';
|
||||
import MockAdapter from 'axios-mock-adapter';
|
||||
import axios from 'axios/index';
|
||||
import gettext from 'sources/gettext';
|
||||
|
||||
const context = describe;
|
||||
|
||||
@ -141,11 +142,11 @@ describe('SearchObjectsDialog', () => {
|
||||
expect(alertifySpy['search_objects']).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('display an alert with a Backup Error', () => {
|
||||
it('display an alert with a Search object Error', () => {
|
||||
soDialog.draw(null, [{id: 'serverTreeNode'}], null);
|
||||
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
||||
'Search Objects Error',
|
||||
'Please select a database or its child node from the browser.'
|
||||
gettext('Search Objects Error'),
|
||||
gettext('Please select a database or its child node from the browser.')
|
||||
);
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user