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:
Binary file not shown.
|
Before Width: | Height: | Size: 142 KiB After Width: | Height: | Size: 237 KiB |
@@ -211,21 +211,23 @@ files.
|
|||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
Use the fields on the *Binary paths* panel to specify the path to the directory
|
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:
|
monitored databases:
|
||||||
|
|
||||||
* Use the *EDB Advanced Server Binary Path* field to specify the location of the
|
* Use the *EDB Advanced Server Binary Path* grid to specify the location of the
|
||||||
EDB Postgres Advanced Server utility programs. If this path is not set,
|
EDB Postgres Advanced Server utility programs based on the server version.
|
||||||
pgAdmin will attempt to find the utilities in standard locations used by
|
If the respective path is not set, then pgAdmin will pick up the path for which
|
||||||
EnterpriseDB.
|
'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
|
* Use the *PostgreSQL Binary Path* grid to specify the location of the
|
||||||
Greenplum database utility programs. If this path is not set, pgAdmin will
|
PostgreSQL utility programs based on the server version. If the respective
|
||||||
attempt to find the utilities in standard locations used by Greenplum.
|
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
|
**Note:** Use the 'Validate path' button to check the existence of the utility
|
||||||
PostgreSQL utility programs. If this path is not set, pgAdmin will attempt
|
programs (pg_dump, pg_dumpall, pg_restore and psql) and there respective versions.
|
||||||
to find the utilities in standard locations used by PostgreSQL.
|
|
||||||
|
|
||||||
.. image:: images/preferences_paths_help.png
|
.. image:: images/preferences_paths_help.png
|
||||||
:alt: Preferences dialog binary path help section
|
: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
|
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 #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 #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 #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 #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.
|
| `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
|
# User will able to execute the system level commands through PSQL terminal
|
||||||
# in pgAdmin.
|
# in pgAdmin.
|
||||||
ALLOW_PSQL_SHELL_COMMANDS = False
|
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
|
# Local config settings
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|||||||
@@ -11,10 +11,11 @@ define('pgadmin.node.mview', [
|
|||||||
'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
|
'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
|
||||||
'sources/pgadmin', 'pgadmin.alertifyjs', 'pgadmin.browser',
|
'sources/pgadmin', 'pgadmin.alertifyjs', 'pgadmin.browser',
|
||||||
'pgadmin.backform', 'pgadmin.node.schema.dir/child',
|
'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(
|
], function(
|
||||||
gettext, url_for, $, _, pgAdmin, Alertify, pgBrowser, Backform,
|
gettext, url_for, $, _, pgAdmin, Alertify, pgBrowser, Backform,
|
||||||
schemaChild, schemaChildTreeNode
|
schemaChild, schemaChildTreeNode, commonUtils
|
||||||
) {
|
) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -316,25 +317,7 @@ define('pgadmin.node.mview', [
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var module = 'paths',
|
if (!commonUtils.hasBinariesConfiguration(pgBrowser, server_data, this.alertify)) {
|
||||||
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));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,14 +9,13 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import json
|
||||||
|
|
||||||
from flask import render_template
|
from flask import render_template
|
||||||
from flask_babelex import gettext as _
|
from flask_babelex import gettext as _
|
||||||
from pgadmin.utils.preferences import Preferences
|
from pgadmin.utils.preferences import Preferences
|
||||||
from werkzeug.exceptions import InternalServerError
|
from werkzeug.exceptions import InternalServerError
|
||||||
|
|
||||||
import config
|
|
||||||
|
|
||||||
|
|
||||||
class ServerType(object):
|
class ServerType(object):
|
||||||
"""
|
"""
|
||||||
@@ -61,14 +60,18 @@ class ServerType(object):
|
|||||||
|
|
||||||
for key in cls.registry:
|
for key in cls.registry:
|
||||||
st = cls.registry[key]
|
st = cls.registry[key]
|
||||||
default_path = config.DEFAULT_BINARY_PATHS.get(st.stype, "")
|
if key == 'pg':
|
||||||
|
st.utility_path = paths.register(
|
||||||
st.utility_path = paths.register(
|
'bin_paths', 'pg_bin_dir',
|
||||||
'bin_paths', st.stype + '_bin_dir',
|
_("PostgreSQL Binary Path"), 'selectFile', None,
|
||||||
st.UTILITY_PATH_LABEL,
|
category_label=_('Binary paths')
|
||||||
'text', default_path, category_label=_('Binary paths'),
|
)
|
||||||
help_str=st.UTILITY_PATH_HELP
|
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
|
@property
|
||||||
def priority(self):
|
def priority(self):
|
||||||
@@ -120,7 +123,8 @@ class ServerType(object):
|
|||||||
operation
|
operation
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
bin_path = self.utility_path.get()
|
|
||||||
|
bin_path = self.get_utility_path(sversion)
|
||||||
if "$DIR" in bin_path:
|
if "$DIR" in bin_path:
|
||||||
# When running as an WSGI application, we will not find the
|
# When running as an WSGI application, we will not find the
|
||||||
# '__file__' attribute for the '__main__' module.
|
# '__file__' attribute for the '__main__' module.
|
||||||
@@ -138,6 +142,26 @@ class ServerType(object):
|
|||||||
(res if os.name != 'nt' else (res + '.exe'))
|
(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
|
# Default Server Type
|
||||||
ServerType('pg', _("PostgreSQL"), -1)
|
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['allow_psql_shell_commands'] = '{{ current_app.config.get('ALLOW_PSQL_SHELL_COMMANDS') }}' == 'True';
|
||||||
pgAdmin['platform'] = '{{platform}}';
|
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
|
// Define list of nodes on which Query tool option doesn't appears
|
||||||
var unsupported_nodes = pgAdmin.unsupported_nodes = [
|
var unsupported_nodes = pgAdmin.unsupported_nodes = [
|
||||||
'server_group', 'server', 'coll-tablespace', 'tablespace',
|
'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.utils.session import cleanup_session_files
|
||||||
from pgadmin.misc.themes import get_all_themes
|
from pgadmin.misc.themes import get_all_themes
|
||||||
from pgadmin.utils.constants import MIMETYPE_APP_JS
|
from pgadmin.utils.constants import MIMETYPE_APP_JS
|
||||||
|
from pgadmin.utils.ajax import precondition_required, make_json_response
|
||||||
import config
|
import config
|
||||||
from werkzeug.exceptions import InternalServerError
|
import subprocess
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
|
||||||
MODULE_NAME = 'misc'
|
MODULE_NAME = 'misc'
|
||||||
|
|
||||||
@@ -98,7 +101,8 @@ class MiscModule(PgAdminModule):
|
|||||||
Returns:
|
Returns:
|
||||||
list: a list of url endpoints exposed to the client.
|
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
|
# Initialise the module
|
||||||
@@ -165,3 +169,48 @@ def shutdown():
|
|||||||
return 'SHUTDOWN'
|
return 'SHUTDOWN'
|
||||||
else:
|
else:
|
||||||
return ''
|
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');
|
$('.file_manager button.rename').attr('disabled', 'disabled');
|
||||||
// set selected folder name in breadcrums
|
// set selected folder name in breadcrums
|
||||||
$('.file_manager #uploader .input-path').hide();
|
|
||||||
$('.file_manager #uploader .show_selected_file').remove();
|
$('.file_manager #uploader .show_selected_file').remove();
|
||||||
$('<span class="show_selected_file">' + path + '</span>').appendTo(
|
$('<span class="show_selected_file">' + path + '</span>').appendTo(
|
||||||
'.file_manager #uploader .filemanager-path-group'
|
'.file_manager #uploader .filemanager-path-group'
|
||||||
|
|||||||
@@ -307,6 +307,8 @@ define('pgadmin.preferences', [
|
|||||||
return 'keyboardShortcut';
|
return 'keyboardShortcut';
|
||||||
case 'radioModern':
|
case 'radioModern':
|
||||||
return 'radioModern';
|
return 'radioModern';
|
||||||
|
case 'selectFile':
|
||||||
|
return 'binary-paths-grid';
|
||||||
default:
|
default:
|
||||||
if (console && console.warn) {
|
if (console && console.warn) {
|
||||||
// Warning for developer only.
|
// Warning for developer only.
|
||||||
@@ -476,7 +478,7 @@ define('pgadmin.preferences', [
|
|||||||
overflow: !1,
|
overflow: !1,
|
||||||
title: gettext('Preferences'),
|
title: gettext('Preferences'),
|
||||||
closableByDimmer: false,
|
closableByDimmer: false,
|
||||||
modal: false,
|
modal: true,
|
||||||
pinnable: false,
|
pinnable: false,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -79,66 +79,6 @@ export class Dialog {
|
|||||||
return serverInformation;
|
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() {
|
dialogName() {
|
||||||
return undefined;
|
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({
|
Backform.UniqueColCollectionControl = Backform.Control.extend({
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
Backform.Control.prototype.initialize.apply(this, arguments);
|
Backform.Control.prototype.initialize.apply(this, arguments);
|
||||||
|
|||||||
@@ -10,10 +10,10 @@
|
|||||||
define([
|
define([
|
||||||
'sources/gettext', 'underscore', 'jquery', 'backbone', 'backform', 'backgrid', 'alertify',
|
'sources/gettext', 'underscore', 'jquery', 'backbone', 'backform', 'backgrid', 'alertify',
|
||||||
'moment', 'bignumber', 'codemirror', 'sources/utils', 'sources/keyboard_shortcuts', 'sources/select2/configure_show_on_scroll',
|
'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(
|
], function(
|
||||||
gettext, _, $, Backbone, Backform, Backgrid, Alertify, moment, BigNumber, CodeMirror,
|
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
|
* 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 editable = Backgrid.callByNeed(column.editable(), column, model);
|
||||||
var align_center = column.get('align_center') || false;
|
var align_center = column.get('align_center') || false;
|
||||||
let checked = this.formatter.fromRaw(model.get(column.get('name')), model);
|
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.empty();
|
||||||
this.$el.append(
|
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 _ from 'underscore';
|
||||||
import { getTreeNodeHierarchyFromIdentifier } from 'sources/tree/pgadmin_tree_node';
|
import { getTreeNodeHierarchyFromIdentifier } from 'sources/tree/pgadmin_tree_node';
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
|
import gettext from 'sources/gettext';
|
||||||
|
|
||||||
export function parseShortcutValue(obj) {
|
export function parseShortcutValue(obj) {
|
||||||
var shortcut = '';
|
var shortcut = '';
|
||||||
@@ -360,3 +360,51 @@ export function CSVToArray( strData, strDelimiter, quoteChar){
|
|||||||
// Return the parsed data.
|
// Return the parsed data.
|
||||||
return arrData;
|
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 {Dialog} from '../../../../static/js/alertify/dialog';
|
||||||
import url_for from 'sources/url_for';
|
import url_for from 'sources/url_for';
|
||||||
import axios from 'axios/index';
|
import axios from 'axios/index';
|
||||||
|
import {retrieveAncestorOfTypeServer} from 'sources/tree/tree_utils';
|
||||||
|
import {hasBinariesConfiguration} from 'sources/utils';
|
||||||
|
|
||||||
export class BackupDialog extends Dialog {
|
export class BackupDialog extends Dialog {
|
||||||
constructor(pgBrowser, $, alertify, BackupModel, backform = Backform) {
|
constructor(pgBrowser, $, alertify, BackupModel, backform = Backform) {
|
||||||
@@ -29,13 +31,13 @@ export class BackupDialog extends Dialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
draw(action, aciTreeItem, params, width=0, height=0) {
|
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) {
|
if (!serverInformation) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.hasBinariesConfiguration(serverInformation)) {
|
if (!hasBinariesConfiguration(this.pgBrowser, serverInformation, this.alertify)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -444,25 +444,7 @@ define([
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var module = 'paths',
|
if (!commonUtils.hasBinariesConfiguration(pgBrowser, server_data, Alertify)) {
|
||||||
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));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -221,25 +221,7 @@ define([
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var module = 'paths',
|
if (!commonUtils.hasBinariesConfiguration(pgBrowser, server_data, Alertify)) {
|
||||||
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));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ import Alertify from 'pgadmin.alertifyjs';
|
|||||||
import {enable} from 'pgadmin.browser.toolbar';
|
import {enable} from 'pgadmin.browser.toolbar';
|
||||||
import clipboard from 'sources/selection/clipboard';
|
import clipboard from 'sources/selection/clipboard';
|
||||||
import 'wcdocker';
|
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 pgWindow from 'sources/window';
|
||||||
|
|
||||||
import {getTreeNodeHierarchyFromIdentifier} from 'sources/tree/pgadmin_tree_node';
|
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);
|
enable(gettext('PSQL Tool'), isEnabled);
|
||||||
return 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) {
|
psql_tool: function(data, aciTreeIdentifier, gen=false) {
|
||||||
const module = 'paths';
|
const serverInformation = retrieveAncestorOfTypeServer(pgBrowser, aciTreeIdentifier, gettext('PSQL Error'), Alertify);
|
||||||
let preference_name = 'pg_bin_dir';
|
if (!hasBinariesConfiguration(pgBrowser, serverInformation, Alertify)) {
|
||||||
let msg = gettext('Please configure the PostgreSQL Binary Path in the Preferences dialog.');
|
return;
|
||||||
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);
|
const node = pgBrowser.treeMenu.findNodeByDomElement(aciTreeIdentifier);
|
||||||
if (node === undefined || !node.getData()) {
|
if (node === undefined || !node.getData()) {
|
||||||
Alertify.alert(
|
Alertify.alert(
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ import Backform from '../../../../static/js/backform.pgadmin';
|
|||||||
import {Dialog} from '../../../../static/js/alertify/dialog';
|
import {Dialog} from '../../../../static/js/alertify/dialog';
|
||||||
import url_for from 'sources/url_for';
|
import url_for from 'sources/url_for';
|
||||||
import axios from 'axios/index';
|
import axios from 'axios/index';
|
||||||
|
import {retrieveAncestorOfTypeServer} from 'sources/tree/tree_utils';
|
||||||
|
import {hasBinariesConfiguration} from 'sources/utils';
|
||||||
|
|
||||||
export class RestoreDialog extends Dialog {
|
export class RestoreDialog extends Dialog {
|
||||||
constructor(pgBrowser, $, alertify, RestoreModel, backform = Backform) {
|
constructor(pgBrowser, $, alertify, RestoreModel, backform = Backform) {
|
||||||
@@ -27,14 +29,12 @@ export class RestoreDialog extends Dialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
draw(action, aciTreeItem, width, height) {
|
draw(action, aciTreeItem, width, height) {
|
||||||
|
const serverInformation = retrieveAncestorOfTypeServer(this.pgBrowser, aciTreeItem, gettext('Restore Error'), this.alertify);
|
||||||
const serverInformation = this.retrieveAncestorOfTypeServer(aciTreeItem);
|
|
||||||
|
|
||||||
if (!serverInformation) {
|
if (!serverInformation) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.hasBinariesConfiguration(serverInformation)) {
|
if (!hasBinariesConfiguration(this.pgBrowser, serverInformation, this.alertify)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
import gettext from 'sources/gettext';
|
import gettext from 'sources/gettext';
|
||||||
import {Dialog} from 'sources/alertify/dialog';
|
import {Dialog} from 'sources/alertify/dialog';
|
||||||
import {getPanelTitle} from 'tools/datagrid/static/js/datagrid_panel_title';
|
import {getPanelTitle} from 'tools/datagrid/static/js/datagrid_panel_title';
|
||||||
|
import {retrieveAncestorOfTypeDatabase} from 'sources/tree/tree_utils';
|
||||||
|
|
||||||
export default class SearchObjectsDialog extends Dialog {
|
export default class SearchObjectsDialog extends Dialog {
|
||||||
constructor(pgBrowser, $, alertify, BackupModel, backform = null) {
|
constructor(pgBrowser, $, alertify, BackupModel, backform = null) {
|
||||||
@@ -24,7 +25,7 @@ export default class SearchObjectsDialog extends Dialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
draw(action, aciTreeItem, params, width=0, height=0) {
|
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) {
|
if (!dbInfo) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -437,7 +437,7 @@ class Preferences(object):
|
|||||||
assert _type in (
|
assert _type in (
|
||||||
'boolean', 'integer', 'numeric', 'date', 'datetime',
|
'boolean', 'integer', 'numeric', 'date', 'datetime',
|
||||||
'options', 'multiline', 'switch', 'node', 'text', 'radioModern',
|
'options', 'multiline', 'switch', 'node', 'text', 'radioModern',
|
||||||
'keyboardshortcut', 'select2'
|
'keyboardshortcut', 'select2', 'selectFile',
|
||||||
), "Type cannot be found in the defined list!"
|
), "Type cannot be found in the defined list!"
|
||||||
|
|
||||||
(cat['preferences'])[name] = res = _Preference(
|
(cat['preferences'])[name] = res = _Preference(
|
||||||
|
|||||||
@@ -68,6 +68,9 @@ describe('BackupDialog', () => {
|
|||||||
data: {
|
data: {
|
||||||
_id: 10,
|
_id: 10,
|
||||||
_type: 'server',
|
_type: 'server',
|
||||||
|
label: 'some-tree-label',
|
||||||
|
server_type: 'pg',
|
||||||
|
version: 100000,
|
||||||
},
|
},
|
||||||
children: [
|
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',
|
id: 'ppasServer',
|
||||||
data: {
|
data: {
|
||||||
|
_id: 13,
|
||||||
_type: 'server',
|
_type: 'server',
|
||||||
|
label: 'some-tree-label',
|
||||||
server_type: 'ppas',
|
server_type: 'ppas',
|
||||||
children: [
|
version: 130000,
|
||||||
{id: 'someNodeUnderneathPPASServer'},
|
},
|
||||||
],
|
},
|
||||||
|
{
|
||||||
|
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);
|
pgBrowser.get_preference.and.returnValue(undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
context('server is a ppas server', () => {
|
context('server is a PostgreSQL server', () => {
|
||||||
it('display an alert with "Backup Error"', () => {
|
it('display an alert with "Preferences Error"', () => {
|
||||||
backupDialog.draw(null, [{id: 'some_database'}], null);
|
backupDialog.draw(null, [{id: 'serverTreeNode'}], null);
|
||||||
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
||||||
'Backup Error',
|
'Preferences Error',
|
||||||
'Failed to load preference pg_bin_dir of module paths'
|
'Failed to load preference pg_bin_dir of module paths'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
context('server is not a ppas server', () => {
|
context('server is a EPAS server', () => {
|
||||||
it('display an alert with "Backup Error"', () => {
|
it('display an alert with "Preferences Error"', () => {
|
||||||
backupDialog.draw(null, [{id: 'ppasServer'}], null);
|
backupDialog.draw(null, [{id: 'ppasServer'}], null);
|
||||||
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
||||||
'Backup Error',
|
'Preferences Error',
|
||||||
'Failed to load preference ppas_bin_dir of module paths'
|
'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', () => {
|
context('binary folder is not configured', () => {
|
||||||
beforeEach(() => {
|
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"', () => {
|
it('display an alert with "Configuration required"', () => {
|
||||||
backupDialog.draw(null, [{id: 'serverTreeNode'}], null);
|
backupDialog.draw(null, [{id: 'serverTreeNodeWrongPath'}], null);
|
||||||
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
||||||
'Configuration required',
|
'Configuration required',
|
||||||
'Please configure the PostgreSQL Binary Path in the Preferences dialog.'
|
'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', () => {
|
context('binary folder is configured', () => {
|
||||||
@@ -202,12 +215,12 @@ describe('BackupDialog', () => {
|
|||||||
backupDialogResizeToSpy = jasmine.createSpyObj('backupDialogResizeToSpy', ['resizeTo']);
|
backupDialogResizeToSpy = jasmine.createSpyObj('backupDialogResizeToSpy', ['resizeTo']);
|
||||||
alertifySpy['backup_objects'].and
|
alertifySpy['backup_objects'].and
|
||||||
.returnValue(backupDialogResizeToSpy);
|
.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');
|
spyOn(backupDialog, 'url_for_utility_exists').and.returnValue('/backup/utility_exists/10/objects');
|
||||||
networkMock.onGet('/backup/utility_exists/10/objects').reply(200, {'success': 1});
|
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);
|
backupDialog.draw(null, [{id: 'serverTreeNode'}], null, pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
expect(alertifySpy['backup_objects']).toHaveBeenCalledWith(true);
|
expect(alertifySpy['backup_objects']).toHaveBeenCalledWith(true);
|
||||||
@@ -216,6 +229,15 @@ describe('BackupDialog', () => {
|
|||||||
}, 0);
|
}, 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 "="', () => {
|
context('database label contain "="', () => {
|
||||||
it('should create alert dialog with backup error', (done) => {
|
it('should create alert dialog with backup error', (done) => {
|
||||||
backupDialog.draw(null, [{id: 'database_with_equal_in_name'}], null);
|
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 backupModelSpy;
|
||||||
|
|
||||||
let rootNode;
|
let rootNode;
|
||||||
let serverTreeNode;
|
let serverTreeNode, serverTreeNodeWrongPath;
|
||||||
let ppasServerTreeNode;
|
let ppasServerTreeNode, ppasServerTreeNodeWrongPath;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
pgBrowser = {
|
pgBrowser = {
|
||||||
@@ -51,12 +51,26 @@ describe('GlobalServerBackupDialog', () => {
|
|||||||
serverTreeNode = pgBrowser.treeMenu.addNewNode('level1.1', {
|
serverTreeNode = pgBrowser.treeMenu.addNewNode('level1.1', {
|
||||||
_type: 'server',
|
_type: 'server',
|
||||||
_id: 10,
|
_id: 10,
|
||||||
|
server_type: 'pg',
|
||||||
|
version: 100000,
|
||||||
}, undefined, ['level1']);
|
}, 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',
|
_type: 'server',
|
||||||
server_type: 'ppas',
|
server_type: 'ppas',
|
||||||
|
version: 130000,
|
||||||
}, undefined, ['level1']);
|
}, 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']);
|
pgBrowser.treeMenu.addNewNode('level3.1', undefined, undefined, ['level1', 'level1.2', 'level3']);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -73,6 +87,7 @@ describe('GlobalServerBackupDialog', () => {
|
|||||||
alertifySpy,
|
alertifySpy,
|
||||||
backupModelSpy
|
backupModelSpy
|
||||||
);
|
);
|
||||||
|
|
||||||
pgBrowser.get_preference = jasmine.createSpy('get_preferences');
|
pgBrowser.get_preference = jasmine.createSpy('get_preferences');
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -103,46 +118,113 @@ describe('GlobalServerBackupDialog', () => {
|
|||||||
pgBrowser.get_preference.and.returnValue(undefined);
|
pgBrowser.get_preference.and.returnValue(undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
context('server is a ppas server', () => {
|
context('server is a PostgreSQL server', () => {
|
||||||
it('display an alert with "Backup Error"', () => {
|
it('display an alert with "Preferences Error"', () => {
|
||||||
backupDialog.draw(null, [serverTreeNode], null);
|
backupDialog.draw(null, [serverTreeNode], null);
|
||||||
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
||||||
'Backup Error',
|
'Preferences Error',
|
||||||
'Failed to load preference pg_bin_dir of module paths'
|
'Failed to load preference pg_bin_dir of module paths'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
context('server is not a ppas server', () => {
|
context('server is a EPAS server', () => {
|
||||||
it('display an alert with "Backup Error"', () => {
|
it('display an alert with "Preferences Error"', () => {
|
||||||
backupDialog.draw(null, [ppasServerTreeNode], null);
|
backupDialog.draw(null, [ppasServerTreeNode], null);
|
||||||
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
||||||
'Backup Error',
|
'Preferences Error',
|
||||||
'Failed to load preference ppas_bin_dir of module paths'
|
'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', () => {
|
context('binary folder is not configured', () => {
|
||||||
beforeEach(() => {
|
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"', () => {
|
it('display an alert with "Configuration required"', () => {
|
||||||
backupDialog.draw(null, [serverTreeNode], null);
|
backupDialog.draw(null, [serverTreeNodeWrongPath], null);
|
||||||
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
||||||
'Configuration required',
|
'Configuration required',
|
||||||
'Please configure the PostgreSQL Binary Path in the Preferences dialog.'
|
'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"', () => {
|
it('display an alert with "Configuration required"', () => {
|
||||||
backupDialog.draw(null, [ppasServerTreeNode], null);
|
backupDialog.draw(null, [ppasServerTreeNodeWrongPath], null);
|
||||||
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
||||||
'Configuration required',
|
'Configuration required',
|
||||||
'Please configure the EDB Advanced Server Binary Path in the Preferences dialog.'
|
'Please configure the EDB Advanced Server Binary Path in the Preferences dialog.'
|
||||||
@@ -161,14 +243,14 @@ describe('GlobalServerBackupDialog', () => {
|
|||||||
serverResizeToSpy = jasmine.createSpyObj('server', ['resizeTo']);
|
serverResizeToSpy = jasmine.createSpyObj('server', ['resizeTo']);
|
||||||
alertifySpy['BackupDialog_server'].and
|
alertifySpy['BackupDialog_server'].and
|
||||||
.returnValue(serverResizeToSpy);
|
.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');
|
spyOn(backupDialog, 'url_for_utility_exists').and.returnValue('/backup/utility_exists/10/servers');
|
||||||
networkMock.onGet('/backup/utility_exists/10/servers').reply(200, {'success': 1});
|
networkMock.onGet('/backup/utility_exists/10/servers').reply(200, {'success': 1});
|
||||||
});
|
});
|
||||||
|
|
||||||
context('dialog for global backup', () => {
|
context('dialog for global backup ', () => {
|
||||||
it('displays the dialog', (done) => {
|
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);
|
backupDialog.draw(null, [ppasServerTreeNode], {globals: true}, pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
expect(alertifySpy['BackupDialog_globals']).toHaveBeenCalledWith(true);
|
expect(alertifySpy['BackupDialog_globals']).toHaveBeenCalledWith(true);
|
||||||
expect(globalResizeToSpy.resizeTo).toHaveBeenCalledWith(pgBrowser.stdW.md, pgBrowser.stdH.md);
|
expect(globalResizeToSpy.resizeTo).toHaveBeenCalledWith(pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||||
@@ -178,8 +260,30 @@ describe('GlobalServerBackupDialog', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
context('dialog for server backup', () => {
|
context('dialog for server backup', () => {
|
||||||
it('displays the dialog', (done) => {
|
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);
|
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(() => {
|
setTimeout(() => {
|
||||||
expect(alertifySpy['BackupDialog_server']).toHaveBeenCalledWith(true);
|
expect(alertifySpy['BackupDialog_server']).toHaveBeenCalledWith(true);
|
||||||
expect(serverResizeToSpy.resizeTo).toHaveBeenCalledWith(pgBrowser.stdW.md, pgBrowser.stdH.md);
|
expect(serverResizeToSpy.resizeTo).toHaveBeenCalledWith(pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ describe('RestoreDialog', () => {
|
|||||||
_id: 10,
|
_id: 10,
|
||||||
_type: 'server',
|
_type: 'server',
|
||||||
label: 'some-tree-label',
|
label: 'some-tree-label',
|
||||||
|
server_type: 'pg',
|
||||||
|
version: 100000,
|
||||||
},
|
},
|
||||||
children: [
|
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',
|
id: 'ppasServer',
|
||||||
data: {
|
data: {
|
||||||
|
_id: 13,
|
||||||
_type: 'server',
|
_type: 'server',
|
||||||
|
label: 'some-tree-label',
|
||||||
server_type: 'ppas',
|
server_type: 'ppas',
|
||||||
children: [
|
version: 130000,
|
||||||
{id: 'someNodeUnderneathPPASServer'},
|
},
|
||||||
],
|
},
|
||||||
|
{
|
||||||
|
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);
|
pgBrowser.get_preference.and.returnValue(undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
context('server is a ppas server', () => {
|
context('server is a PostgreSQL server', () => {
|
||||||
it('display an alert with "Restore Error"', () => {
|
it('display an alert with "Preferences Error"', () => {
|
||||||
restoreDialog.draw(null, [{id: 'serverTreeNode'}], null);
|
restoreDialog.draw(null, [{id: 'serverTreeNode'}], null);
|
||||||
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
||||||
'Restore Error',
|
'Preferences Error',
|
||||||
'Failed to load preference pg_bin_dir of module paths'
|
'Failed to load preference pg_bin_dir of module paths'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
context('server is not a ppas server', () => {
|
context('server is a EPAS server', () => {
|
||||||
it('display an alert with "Restore Error"', () => {
|
it('display an alert with "Preferences Error"', () => {
|
||||||
restoreDialog.draw(null, [{id: 'ppasServer'}], null);
|
restoreDialog.draw(null, [{id: 'ppasServer'}], null);
|
||||||
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
||||||
'Restore Error',
|
'Preferences Error',
|
||||||
'Failed to load preference ppas_bin_dir of module paths'
|
'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', () => {
|
context('binary folder is not configured', () => {
|
||||||
beforeEach(() => {
|
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"', () => {
|
it('display an alert with "Configuration required"', () => {
|
||||||
restoreDialog.draw(null, [{id: 'serverTreeNode'}], null);
|
restoreDialog.draw(null, [{id: 'serverTreeNodeWrongPath'}], null);
|
||||||
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
||||||
'Configuration required',
|
'Configuration required',
|
||||||
'Please configure the PostgreSQL Binary Path in the Preferences dialog.'
|
'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', () => {
|
context('binary folder is configured', () => {
|
||||||
@@ -190,13 +202,13 @@ describe('RestoreDialog', () => {
|
|||||||
spy = jasmine.createSpyObj('globals', ['resizeTo']);
|
spy = jasmine.createSpyObj('globals', ['resizeTo']);
|
||||||
alertifySpy['pg_restore'].and
|
alertifySpy['pg_restore'].and
|
||||||
.returnValue(spy);
|
.returnValue(spy);
|
||||||
pgBrowser.get_preference.and.returnValue({value: '/some/path'});
|
|
||||||
pgBrowser.Nodes.server.label = 'some-server-label';
|
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');
|
spyOn(restoreDialog, 'url_for_utility_exists').and.returnValue('/restore/utility_exists/10/objects');
|
||||||
networkMock.onGet('/restore/utility_exists/10/objects').reply(200, {'success': 1});
|
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);
|
restoreDialog.draw(null, [{id: 'serverTreeNode'}], pgBrowser.stdW.md, pgBrowser.stdH.md);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
expect(alertifySpy['pg_restore']).toHaveBeenCalledWith(
|
expect(alertifySpy['pg_restore']).toHaveBeenCalledWith(
|
||||||
@@ -206,6 +218,28 @@ describe('RestoreDialog', () => {
|
|||||||
_id: 10,
|
_id: 10,
|
||||||
_type: 'server',
|
_type: 'server',
|
||||||
label: 'some-tree-label',
|
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
|
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 {TreeFake} from '../tree/tree_fake';
|
||||||
import MockAdapter from 'axios-mock-adapter';
|
import MockAdapter from 'axios-mock-adapter';
|
||||||
import axios from 'axios/index';
|
import axios from 'axios/index';
|
||||||
|
import gettext from 'sources/gettext';
|
||||||
|
|
||||||
const context = describe;
|
const context = describe;
|
||||||
|
|
||||||
@@ -141,11 +142,11 @@ describe('SearchObjectsDialog', () => {
|
|||||||
expect(alertifySpy['search_objects']).not.toHaveBeenCalled();
|
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);
|
soDialog.draw(null, [{id: 'serverTreeNode'}], null);
|
||||||
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
expect(alertifySpy.alert).toHaveBeenCalledWith(
|
||||||
'Search Objects Error',
|
gettext('Search Objects Error'),
|
||||||
'Please select a database or its child node from the browser.'
|
gettext('Please select a database or its child node from the browser.')
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user