mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2024-11-26 02:30:21 -06:00
Don't wait for the database connection before rendering the Query Tool UI, for improved UX. Fixes #4453
In addition, unescape HTML entities in database names in the Query Tool title bar. Fixes #4584
This commit is contained in:
parent
25f85fe123
commit
234efc3be7
@ -9,6 +9,7 @@ This release contains a number of bug fixes and new features since the release o
|
|||||||
New features
|
New features
|
||||||
************
|
************
|
||||||
|
|
||||||
|
| `Issue #4453 <https://redmine.postgresql.org/issues/4453>`_ - Don't wait for the database connection before rendering the Query Tool UI, for improved UX.
|
||||||
| `Issue #4651 <https://redmine.postgresql.org/issues/4651>`_ - Allow configuration options to be set from the environment in the container distribution.
|
| `Issue #4651 <https://redmine.postgresql.org/issues/4651>`_ - Allow configuration options to be set from the environment in the container distribution.
|
||||||
|
|
||||||
Housekeeping
|
Housekeeping
|
||||||
@ -22,6 +23,7 @@ Bug fixes
|
|||||||
| `Issue #2706 <https://redmine.postgresql.org/issues/2706>`_ - Added ProjectSet icon for explain module.
|
| `Issue #2706 <https://redmine.postgresql.org/issues/2706>`_ - Added ProjectSet icon for explain module.
|
||||||
| `Issue #2828 <https://redmine.postgresql.org/issues/2828>`_ - Added Gather Merge, Named Tuple Store Scan and Table Function Scan icon for explain module.
|
| `Issue #2828 <https://redmine.postgresql.org/issues/2828>`_ - Added Gather Merge, Named Tuple Store Scan and Table Function Scan icon for explain module.
|
||||||
| `Issue #4419 <https://redmine.postgresql.org/issues/4419>`_ - Fix a debugger error when using Python 2.7.
|
| `Issue #4419 <https://redmine.postgresql.org/issues/4419>`_ - Fix a debugger error when using Python 2.7.
|
||||||
|
| `Issue #4584 <https://redmine.postgresql.org/issues/4584>`_ - Unescape HTML entities in database names in the Query Tool title bar.
|
||||||
| `Issue #4643 <https://redmine.postgresql.org/issues/4643>`_ - Fix Truncate option deselect issue for compound triggers.
|
| `Issue #4643 <https://redmine.postgresql.org/issues/4643>`_ - Fix Truncate option deselect issue for compound triggers.
|
||||||
| `Issue #4644 <https://redmine.postgresql.org/issues/4644>`_ - Fix length and precision enable/disable issue when changing the data type for Domain node.
|
| `Issue #4644 <https://redmine.postgresql.org/issues/4644>`_ - Fix length and precision enable/disable issue when changing the data type for Domain node.
|
||||||
| `Issue #4650 <https://redmine.postgresql.org/issues/4650>`_ - Fix SQL tab issue for Views. It's a regression of compound triggers.
|
| `Issue #4650 <https://redmine.postgresql.org/issues/4650>`_ - Fix SQL tab issue for Views. It's a regression of compound triggers.
|
||||||
|
@ -47,6 +47,30 @@ def underscore_escape(text):
|
|||||||
return text
|
return text
|
||||||
|
|
||||||
|
|
||||||
|
def underscore_unescape(text):
|
||||||
|
"""
|
||||||
|
This function mimics the behaviour of underscore js unescape function
|
||||||
|
The html unescape by jinja is not compatible for underscore escape
|
||||||
|
function
|
||||||
|
:param text: input html text
|
||||||
|
:return: unescaped text
|
||||||
|
"""
|
||||||
|
html_map = {
|
||||||
|
"&": '&',
|
||||||
|
"<": '<',
|
||||||
|
">": '>',
|
||||||
|
""": '"',
|
||||||
|
"`": '`',
|
||||||
|
"'": "'"
|
||||||
|
}
|
||||||
|
|
||||||
|
# always replace & first
|
||||||
|
for c, r in html_map.items():
|
||||||
|
text = text.replace(c, r)
|
||||||
|
|
||||||
|
return text
|
||||||
|
|
||||||
|
|
||||||
def is_version_in_range(sversion, min_ver, max_ver):
|
def is_version_in_range(sversion, min_ver, max_ver):
|
||||||
assert (max_ver is None or isinstance(max_ver, int))
|
assert (max_ver is None or isinstance(max_ver, int))
|
||||||
assert (min_ver is None or isinstance(min_ver, int))
|
assert (min_ver is None or isinstance(min_ver, int))
|
||||||
|
@ -73,6 +73,9 @@ define(['jquery', 'sources/gettext', 'sources/url_for'],
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($status_el.hasClass('obtaining-conn')){
|
||||||
|
return;
|
||||||
|
}
|
||||||
let sqleditor_obj = target;
|
let sqleditor_obj = target;
|
||||||
|
|
||||||
// Start polling..
|
// Start polling..
|
||||||
@ -195,22 +198,6 @@ define(['jquery', 'sources/gettext', 'sources/url_for'],
|
|||||||
}
|
}
|
||||||
return '1em';
|
return '1em';
|
||||||
},
|
},
|
||||||
|
|
||||||
removeSlashInTheString: (value) => {
|
|
||||||
let locationList = [];
|
|
||||||
let idx = 0;
|
|
||||||
while (value && value.indexOf('/') !== -1) {
|
|
||||||
locationList.push(value.indexOf('/') + idx);
|
|
||||||
value = value.replace('/', '');
|
|
||||||
// No of slashes already removed, so we need to increment the
|
|
||||||
// index accordingly when adding into location list
|
|
||||||
idx++;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
'slashLocations': locationList.join(','),
|
|
||||||
'title': encodeURIComponent(value),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
return sqlEditorUtils;
|
return sqlEditorUtils;
|
||||||
});
|
});
|
||||||
|
@ -199,3 +199,9 @@ export function fully_qualify(pgBrowser, data, item) {
|
|||||||
return quote_ident(data._label);
|
return quote_ident(data._label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getRandomInt(min, max) {
|
||||||
|
min = Math.ceil(min);
|
||||||
|
max = Math.floor(max);
|
||||||
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||||
|
}
|
||||||
|
@ -30,7 +30,7 @@ from pgadmin.utils.driver import get_driver
|
|||||||
from pgadmin.utils.exception import ConnectionLost, SSHTunnelConnectionLost
|
from pgadmin.utils.exception import ConnectionLost, SSHTunnelConnectionLost
|
||||||
from pgadmin.utils.preferences import Preferences
|
from pgadmin.utils.preferences import Preferences
|
||||||
from pgadmin.settings import get_setting
|
from pgadmin.settings import get_setting
|
||||||
from pgadmin.browser.utils import underscore_escape
|
from pgadmin.browser.utils import underscore_unescape
|
||||||
|
|
||||||
|
|
||||||
query_tool_close_session_lock = Lock()
|
query_tool_close_session_lock = Lock()
|
||||||
@ -114,13 +114,13 @@ def show_filter():
|
|||||||
|
|
||||||
|
|
||||||
@blueprint.route(
|
@blueprint.route(
|
||||||
'/initialize/datagrid/<int:cmd_type>/<obj_type>/<int:sgid>/<int:sid>/'
|
'/initialize/datagrid/<int:trans_id>/<int:cmd_type>/<obj_type>/'
|
||||||
'<int:did>/<int:obj_id>',
|
'<int:sgid>/<int:sid>/<int:did>/<int:obj_id>',
|
||||||
methods=["PUT", "POST"],
|
methods=["PUT", "POST"],
|
||||||
endpoint="initialize_datagrid"
|
endpoint="initialize_datagrid"
|
||||||
)
|
)
|
||||||
@login_required
|
@login_required
|
||||||
def initialize_datagrid(cmd_type, obj_type, sgid, sid, did, obj_id):
|
def initialize_datagrid(trans_id, cmd_type, obj_type, sgid, sid, did, obj_id):
|
||||||
"""
|
"""
|
||||||
This method is responsible for creating an asynchronous connection.
|
This method is responsible for creating an asynchronous connection.
|
||||||
After creating the connection it will instantiate and initialize
|
After creating the connection it will instantiate and initialize
|
||||||
@ -183,9 +183,6 @@ def initialize_datagrid(cmd_type, obj_type, sgid, sid, did, obj_id):
|
|||||||
app.logger.error(e)
|
app.logger.error(e)
|
||||||
return internal_server_error(errormsg=str(e))
|
return internal_server_error(errormsg=str(e))
|
||||||
|
|
||||||
# Create a unique id for the transaction
|
|
||||||
trans_id = str(random.randint(1, 9999999))
|
|
||||||
|
|
||||||
if 'gridData' not in session:
|
if 'gridData' not in session:
|
||||||
sql_grid_data = dict()
|
sql_grid_data = dict()
|
||||||
else:
|
else:
|
||||||
@ -193,7 +190,7 @@ def initialize_datagrid(cmd_type, obj_type, sgid, sid, did, obj_id):
|
|||||||
|
|
||||||
# Use pickle to store the command object which will be used later by the
|
# Use pickle to store the command object which will be used later by the
|
||||||
# sql grid module.
|
# sql grid module.
|
||||||
sql_grid_data[trans_id] = {
|
sql_grid_data[str(trans_id)] = {
|
||||||
# -1 specify the highest protocol version available
|
# -1 specify the highest protocol version available
|
||||||
'command_obj': pickle.dumps(command_obj, -1)
|
'command_obj': pickle.dumps(command_obj, -1)
|
||||||
}
|
}
|
||||||
@ -203,51 +200,34 @@ def initialize_datagrid(cmd_type, obj_type, sgid, sid, did, obj_id):
|
|||||||
|
|
||||||
return make_json_response(
|
return make_json_response(
|
||||||
data={
|
data={
|
||||||
'gridTransId': trans_id
|
'conn_id': conn_id
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@blueprint.route(
|
@blueprint.route(
|
||||||
'/panel/<int:trans_id>/<is_query_tool>/<path:editor_title>',
|
'/panel/<int:trans_id>',
|
||||||
methods=["GET"],
|
methods=["POST"],
|
||||||
endpoint='panel'
|
endpoint='panel'
|
||||||
)
|
)
|
||||||
def panel(trans_id, is_query_tool, editor_title):
|
def panel(trans_id):
|
||||||
"""
|
"""
|
||||||
This method calls index.html to render the data grid.
|
This method calls index.html to render the data grid.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
trans_id: unique transaction id
|
trans_id: unique transaction id
|
||||||
is_query_tool: True if panel calls when query tool menu is clicked.
|
|
||||||
editor_title: Title of the editor
|
|
||||||
"""
|
"""
|
||||||
# Let's fetch Script type URL from request
|
|
||||||
if request.args and request.args['query_url'] != '':
|
|
||||||
sURL = request.args['query_url']
|
|
||||||
else:
|
|
||||||
sURL = None
|
|
||||||
|
|
||||||
# Fetch server type from request
|
url_params = None
|
||||||
if request.args and request.args['server_type'] != '':
|
if request.args:
|
||||||
server_type = request.args['server_type']
|
url_params = {k: v for k, v in request.args.items()}
|
||||||
else:
|
|
||||||
server_type = None
|
|
||||||
|
|
||||||
if request.args and 'server_ver' in request.args:
|
if request.form:
|
||||||
server_ver = request.args['server_ver']
|
url_params['title'] = request.form['title']
|
||||||
else:
|
if 'sql_filter' in request.form:
|
||||||
server_ver = 0
|
url_params['sql_filter'] = request.form['sql_filter']
|
||||||
|
if 'query_url' in request.form:
|
||||||
# If title has slash(es) in it then replace it
|
url_params['query_url'] = request.form['query_url']
|
||||||
if request.args and request.args['fslashes'] != '':
|
|
||||||
try:
|
|
||||||
fslashesList = request.args['fslashes'].split(',')
|
|
||||||
for idx in fslashesList:
|
|
||||||
idx = int(idx)
|
|
||||||
editor_title = editor_title[:idx] + '/' + editor_title[idx:]
|
|
||||||
except IndexError as e:
|
|
||||||
app.logger.exception(e)
|
|
||||||
|
|
||||||
# We need client OS information to render correct Keyboard shortcuts
|
# We need client OS information to render correct Keyboard shortcuts
|
||||||
user_agent = UserAgent(request.headers.get('User-Agent'))
|
user_agent = UserAgent(request.headers.get('User-Agent'))
|
||||||
@ -277,12 +257,8 @@ def panel(trans_id, is_query_tool, editor_title):
|
|||||||
# Fetch the server details
|
# Fetch the server details
|
||||||
bgcolor = None
|
bgcolor = None
|
||||||
fgcolor = None
|
fgcolor = None
|
||||||
if 'gridData' in session and str(trans_id) in session['gridData']:
|
|
||||||
# Fetch the object for the specified transaction id.
|
s = Server.query.filter_by(id=url_params['sid']).first()
|
||||||
# Use pickle.loads function to get the command object
|
|
||||||
session_obj = session['gridData'][str(trans_id)]
|
|
||||||
trans_obj = pickle.loads(session_obj['command_obj'])
|
|
||||||
s = Server.query.filter_by(id=trans_obj.sid).first()
|
|
||||||
if s and s.bgcolor:
|
if s and s.bgcolor:
|
||||||
# If background is set to white means we do not have to change
|
# If background is set to white means we do not have to change
|
||||||
# the title background else change it as per user specified
|
# the title background else change it as per user specified
|
||||||
@ -293,48 +269,31 @@ def panel(trans_id, is_query_tool, editor_title):
|
|||||||
|
|
||||||
layout = get_setting('SQLEditor/Layout')
|
layout = get_setting('SQLEditor/Layout')
|
||||||
|
|
||||||
url_params = dict()
|
|
||||||
if is_query_tool == 'true':
|
|
||||||
url_params['sgid'] = trans_obj.sgid
|
|
||||||
url_params['sid'] = trans_obj.sid
|
|
||||||
url_params['did'] = trans_obj.did
|
|
||||||
else:
|
|
||||||
url_params['cmd_type'] = trans_obj.cmd_type
|
|
||||||
url_params['obj_type'] = trans_obj.object_type
|
|
||||||
url_params['sgid'] = trans_obj.sgid
|
|
||||||
url_params['sid'] = trans_obj.sid
|
|
||||||
url_params['did'] = trans_obj.did
|
|
||||||
url_params['obj_id'] = trans_obj.obj_id
|
|
||||||
|
|
||||||
return render_template(
|
return render_template(
|
||||||
"datagrid/index.html",
|
"datagrid/index.html",
|
||||||
_=gettext,
|
_=gettext,
|
||||||
uniqueId=trans_id,
|
uniqueId=trans_id,
|
||||||
is_query_tool=is_query_tool,
|
|
||||||
editor_title=underscore_escape(editor_title),
|
|
||||||
script_type_url=sURL,
|
|
||||||
is_desktop_mode=app.PGADMIN_RUNTIME,
|
is_desktop_mode=app.PGADMIN_RUNTIME,
|
||||||
is_linux=is_linux_platform,
|
is_linux=is_linux_platform,
|
||||||
server_type=server_type,
|
title=underscore_unescape(url_params['title']),
|
||||||
server_ver=server_ver,
|
url_params=json.dumps(url_params),
|
||||||
client_platform=user_agent.platform,
|
client_platform=user_agent.platform,
|
||||||
bgcolor=bgcolor,
|
bgcolor=bgcolor,
|
||||||
fgcolor=fgcolor,
|
fgcolor=fgcolor,
|
||||||
url_params=json.dumps(url_params),
|
|
||||||
layout=layout,
|
layout=layout,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@blueprint.route(
|
@blueprint.route(
|
||||||
'/initialize/query_tool/<int:sgid>/<int:sid>/<int:did>',
|
'/initialize/query_tool/<int:trans_id>/<int:sgid>/<int:sid>/<int:did>',
|
||||||
methods=["POST"], endpoint='initialize_query_tool_with_did'
|
methods=["POST"], endpoint='initialize_query_tool_with_did'
|
||||||
)
|
)
|
||||||
@blueprint.route(
|
@blueprint.route(
|
||||||
'/initialize/query_tool/<int:sgid>/<int:sid>',
|
'/initialize/query_tool/<int:trans_id>/<int:sgid>/<int:sid>',
|
||||||
methods=["POST"], endpoint='initialize_query_tool'
|
methods=["POST"], endpoint='initialize_query_tool'
|
||||||
)
|
)
|
||||||
@login_required
|
@login_required
|
||||||
def initialize_query_tool(sgid, sid, did=None):
|
def initialize_query_tool(trans_id, sgid, sid, did=None):
|
||||||
"""
|
"""
|
||||||
This method is responsible for instantiating and initializing
|
This method is responsible for instantiating and initializing
|
||||||
the query tool object. It will also create a unique
|
the query tool object. It will also create a unique
|
||||||
@ -346,16 +305,16 @@ def initialize_query_tool(sgid, sid, did=None):
|
|||||||
did: Database Id
|
did: Database Id
|
||||||
"""
|
"""
|
||||||
connect = True
|
connect = True
|
||||||
reqArgs = None
|
|
||||||
# Read the data if present. Skipping read may cause connection
|
# Read the data if present. Skipping read may cause connection
|
||||||
# reset error if data is sent from the client
|
# reset error if data is sent from the client
|
||||||
if request.data:
|
if request.data:
|
||||||
reqArgs = request.data
|
_ = request.data
|
||||||
|
|
||||||
reqArgs = request.args
|
reqArgs = request.args
|
||||||
if ('recreate' in reqArgs and
|
if ('recreate' in reqArgs and
|
||||||
reqArgs['recreate'] == '1'):
|
reqArgs['recreate'] == '1'):
|
||||||
connect = False
|
connect = False
|
||||||
|
|
||||||
# Create asynchronous connection using random connection id.
|
# Create asynchronous connection using random connection id.
|
||||||
conn_id = str(random.randint(1, 9999999))
|
conn_id = str(random.randint(1, 9999999))
|
||||||
|
|
||||||
@ -389,9 +348,6 @@ def initialize_query_tool(sgid, sid, did=None):
|
|||||||
app.logger.error(e)
|
app.logger.error(e)
|
||||||
return internal_server_error(errormsg=str(e))
|
return internal_server_error(errormsg=str(e))
|
||||||
|
|
||||||
# Create a unique id for the transaction
|
|
||||||
trans_id = str(random.randint(1, 9999999))
|
|
||||||
|
|
||||||
if 'gridData' not in session:
|
if 'gridData' not in session:
|
||||||
sql_grid_data = dict()
|
sql_grid_data = dict()
|
||||||
else:
|
else:
|
||||||
@ -404,7 +360,7 @@ def initialize_query_tool(sgid, sid, did=None):
|
|||||||
|
|
||||||
# Use pickle to store the command object which will be used
|
# Use pickle to store the command object which will be used
|
||||||
# later by the sql grid module.
|
# later by the sql grid module.
|
||||||
sql_grid_data[trans_id] = {
|
sql_grid_data[str(trans_id)] = {
|
||||||
# -1 specify the highest protocol version available
|
# -1 specify the highest protocol version available
|
||||||
'command_obj': pickle.dumps(command_obj, -1)
|
'command_obj': pickle.dumps(command_obj, -1)
|
||||||
}
|
}
|
||||||
@ -414,7 +370,7 @@ def initialize_query_tool(sgid, sid, did=None):
|
|||||||
|
|
||||||
return make_json_response(
|
return make_json_response(
|
||||||
data={
|
data={
|
||||||
'gridTransId': trans_id,
|
'connId': str(conn_id),
|
||||||
'serverVersion': manager.version,
|
'serverVersion': manager.version,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -13,10 +13,10 @@ define('pgadmin.datagrid', [
|
|||||||
'sources/sqleditor_utils', 'backbone',
|
'sources/sqleditor_utils', 'backbone',
|
||||||
'tools/datagrid/static/js/show_data',
|
'tools/datagrid/static/js/show_data',
|
||||||
'tools/datagrid/static/js/show_query_tool', 'pgadmin.browser.toolbar',
|
'tools/datagrid/static/js/show_query_tool', 'pgadmin.browser.toolbar',
|
||||||
'tools/datagrid/static/js/datagrid_panel_title', 'wcdocker',
|
'tools/datagrid/static/js/datagrid_panel_title', 'sources/utils', 'wcdocker',
|
||||||
], function(
|
], function(
|
||||||
gettext, url_for, $, _, alertify, pgAdmin, codemirror, sqlEditorUtils,
|
gettext, url_for, $, _, alertify, pgAdmin, codemirror, sqlEditorUtils,
|
||||||
Backbone, showData, showQueryTool, toolBar, panelTitleFunc
|
Backbone, showData, showQueryTool, toolBar, panelTitleFunc, commonUtils
|
||||||
) {
|
) {
|
||||||
// Some scripts do export their object in the window only.
|
// Some scripts do export their object in the window only.
|
||||||
// Generally the one, which do no have AMD support.
|
// Generally the one, which do no have AMD support.
|
||||||
@ -52,7 +52,6 @@ define('pgadmin.datagrid', [
|
|||||||
self.preferences = pgBrowser.get_preferences_for_module('sqleditor');
|
self.preferences = pgBrowser.get_preferences_for_module('sqleditor');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// Define list of nodes on which view data option appears
|
// Define list of nodes on which view data option appears
|
||||||
var supported_nodes = [
|
var supported_nodes = [
|
||||||
'table', 'view', 'mview',
|
'table', 'view', 'mview',
|
||||||
@ -195,97 +194,48 @@ define('pgadmin.datagrid', [
|
|||||||
|
|
||||||
// This is a callback function to show data when user click on menu item.
|
// This is a callback function to show data when user click on menu item.
|
||||||
show_data_grid: function(data, i) {
|
show_data_grid: function(data, i) {
|
||||||
showData.showDataGrid(this, pgBrowser, alertify, data, i);
|
const transId = commonUtils.getRandomInt(1, 9999999);
|
||||||
|
showData.showDataGrid(this, pgBrowser, alertify, data, i, transId);
|
||||||
},
|
},
|
||||||
|
|
||||||
// This is a callback function to show filtered data when user click on menu item.
|
// This is a callback function to show filtered data when user click on menu item.
|
||||||
show_filtered_row: function(data, i) {
|
show_filtered_row: function(data, i) {
|
||||||
showData.showDataGrid(this, pgBrowser, alertify, data, i, true, this.preferences);
|
const transId = commonUtils.getRandomInt(1, 9999999);
|
||||||
|
showData.showDataGrid(this, pgBrowser, alertify, data, i, transId, true, this.preferences);
|
||||||
},
|
},
|
||||||
|
|
||||||
// This is a callback function to show query tool when user click on menu item.
|
// This is a callback function to show query tool when user click on menu item.
|
||||||
show_query_tool: function(url, aciTreeIdentifier) {
|
show_query_tool: function(url, aciTreeIdentifier) {
|
||||||
showQueryTool.showQueryTool(this, pgBrowser, alertify, url, aciTreeIdentifier);
|
const transId = commonUtils.getRandomInt(1, 9999999);
|
||||||
|
showQueryTool.showQueryTool(this, pgBrowser, alertify, url, aciTreeIdentifier, transId);
|
||||||
},
|
},
|
||||||
|
|
||||||
create_transaction: function(baseUrl, target, is_query_tool, server_type, sURL, panel_title, sql_filter, recreate) {
|
launch_grid: function(trans_id, panel_url, is_query_tool, panel_title, sURL=null, sql_filter=null) {
|
||||||
var self = this;
|
var self = this;
|
||||||
target = target || self;
|
|
||||||
if (recreate) {
|
let queryToolForm = `
|
||||||
baseUrl += '?recreate=1';
|
<form id="queryToolForm" action="${panel_url}" method="post">
|
||||||
|
<input id="title" name="title" hidden />`;
|
||||||
|
|
||||||
|
if(sURL){
|
||||||
|
queryToolForm +=`<input name="query_url" value="${sURL}" hidden />`;
|
||||||
|
}
|
||||||
|
if(sql_filter) {
|
||||||
|
queryToolForm +=`<textarea name="sql_filter" hidden>${sql_filter}</textarea>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send the data only if required. Sending non required data may
|
queryToolForm +=`
|
||||||
* cause connection reset error if data is not read by flask server
|
</form>
|
||||||
*/
|
<script>
|
||||||
let reqData = null;
|
document.getElementById("title").value = "${panel_title}";
|
||||||
if(sql_filter != '') {
|
document.getElementById("queryToolForm").submit();
|
||||||
reqData = JSON.stringify(sql_filter);
|
</script>
|
||||||
}
|
`;
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url: baseUrl,
|
|
||||||
method: 'POST',
|
|
||||||
dataType: 'json',
|
|
||||||
data: reqData,
|
|
||||||
contentType: 'application/json',
|
|
||||||
})
|
|
||||||
.done(function(res) {
|
|
||||||
res.data.is_query_tool = is_query_tool;
|
|
||||||
res.data.server_type = server_type;
|
|
||||||
res.data.sURL = sURL;
|
|
||||||
res.data.panel_title = panel_title;
|
|
||||||
target.trigger('pgadmin-datagrid:transaction:created', res.data);
|
|
||||||
})
|
|
||||||
.fail(function(xhr) {
|
|
||||||
if (target !== self) {
|
|
||||||
if(xhr.status == 503 && xhr.responseJSON.info != undefined &&
|
|
||||||
xhr.responseJSON.info == 'CONNECTION_LOST') {
|
|
||||||
setTimeout(function() {
|
|
||||||
target.handle_connection_lost(true, xhr);
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
var err = JSON.parse(xhr.responseText);
|
|
||||||
alertify.alert(gettext('Query Tool initialization error'),
|
|
||||||
err.errormsg
|
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
alertify.alert(gettext('Query Tool initialization error'),
|
|
||||||
e.statusText
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
launch_grid: function(trans_obj) {
|
|
||||||
var self = this,
|
|
||||||
panel_title = trans_obj.panel_title,
|
|
||||||
grid_title = trans_obj.panel_title;
|
|
||||||
|
|
||||||
// Open the panel if frame is initialized
|
|
||||||
let titileForURLObj = sqlEditorUtils.removeSlashInTheString(grid_title);
|
|
||||||
var url_params = {
|
|
||||||
'trans_id': trans_obj.gridTransId,
|
|
||||||
'is_query_tool': trans_obj.is_query_tool,
|
|
||||||
'editor_title': titileForURLObj.title,
|
|
||||||
},
|
|
||||||
baseUrl = url_for('datagrid.panel', url_params) +
|
|
||||||
'?' + 'query_url=' + encodeURI(trans_obj.sURL) +
|
|
||||||
'&server_type=' + encodeURIComponent(trans_obj.server_type) +
|
|
||||||
'&server_ver=' + trans_obj.serverVersion+
|
|
||||||
'&fslashes=' + titileForURLObj.slashLocations;
|
|
||||||
|
|
||||||
if (self.preferences.new_browser_tab) {
|
if (self.preferences.new_browser_tab) {
|
||||||
var newWin = window.open(baseUrl, '_blank');
|
var newWin = window.open('', '_blank');
|
||||||
|
newWin.document.write(queryToolForm);
|
||||||
// add a load listener to the window so that the title gets changed on page load
|
|
||||||
newWin.addEventListener('load', function() {
|
|
||||||
newWin.document.title = panel_title;
|
newWin.document.title = panel_title;
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* On successfully initialization find the dashboard panel,
|
/* On successfully initialization find the dashboard panel,
|
||||||
* create new panel and add it to the dashboard panel.
|
* create new panel and add it to the dashboard panel.
|
||||||
@ -294,13 +244,13 @@ define('pgadmin.datagrid', [
|
|||||||
var queryToolPanel = pgBrowser.docker.addPanel('frm_datagrid', wcDocker.DOCK.STACKED, propertiesPanel[0]);
|
var queryToolPanel = pgBrowser.docker.addPanel('frm_datagrid', wcDocker.DOCK.STACKED, propertiesPanel[0]);
|
||||||
|
|
||||||
// Set panel title and icon
|
// Set panel title and icon
|
||||||
panelTitleFunc.setQueryToolDockerTitle(queryToolPanel, trans_obj.is_query_tool, panel_title);
|
panelTitleFunc.setQueryToolDockerTitle(queryToolPanel, is_query_tool, panel_title);
|
||||||
queryToolPanel.focus();
|
queryToolPanel.focus();
|
||||||
|
|
||||||
// Listen on the panel closed event.
|
// Listen on the panel closed event.
|
||||||
queryToolPanel.on(wcDocker.EVENT.CLOSED, function() {
|
queryToolPanel.on(wcDocker.EVENT.CLOSED, function() {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: url_for('datagrid.close', {'trans_id': trans_obj.gridTransId}),
|
url: url_for('datagrid.close', {'trans_id': trans_id}),
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -325,7 +275,7 @@ define('pgadmin.datagrid', [
|
|||||||
frame.onLoaded(()=>{
|
frame.onLoaded(()=>{
|
||||||
$spinner_el.remove();
|
$spinner_el.remove();
|
||||||
});
|
});
|
||||||
frame.openURL(baseUrl);
|
frame.openHTML(queryToolForm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
|
@ -52,6 +52,6 @@ export function setQueryToolDockerTitle(panel, is_query_tool, panel_title, is_fi
|
|||||||
panel_icon = 'fa fa-bolt';
|
panel_icon = 'fa fa-bolt';
|
||||||
}
|
}
|
||||||
|
|
||||||
panel.title('<span title="'+_.escape(panel_tooltip)+'">'+_.escape(panel_title)+'</span>');
|
panel.title('<span title="'+ panel_tooltip +'">'+ panel_title +'</span>');
|
||||||
panel.icon(panel_icon);
|
panel.icon(panel_icon);
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ export function showDataGrid(
|
|||||||
alertify,
|
alertify,
|
||||||
connectionData,
|
connectionData,
|
||||||
aciTreeIdentifier,
|
aciTreeIdentifier,
|
||||||
|
transId,
|
||||||
filter=false,
|
filter=false,
|
||||||
preferences=null
|
preferences=null
|
||||||
) {
|
) {
|
||||||
@ -42,43 +43,25 @@ export function showDataGrid(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const baseUrl = generateUrl(connectionData, node.getData(), parentData);
|
const gridUrl = generateUrl(transId, connectionData, node.getData(), parentData);
|
||||||
const grid_title = generateDatagridTitle(pgBrowser, aciTreeIdentifier);
|
const queryToolTitle = generateDatagridTitle(pgBrowser, aciTreeIdentifier);
|
||||||
|
|
||||||
if(filter) {
|
if(filter) {
|
||||||
initFilterDialog(alertify, pgBrowser, preferences);
|
initFilterDialog(alertify, pgBrowser, preferences);
|
||||||
|
|
||||||
const validateUrl = generateFilterValidateUrl(node.getData(), parentData);
|
const validateUrl = generateFilterValidateUrl(node.getData(), parentData);
|
||||||
|
|
||||||
let okCallback = function(sql) {
|
let okCallback = function(sql) {
|
||||||
datagrid.create_transaction(
|
datagrid.launch_grid(transId, gridUrl, false, queryToolTitle, null, sql);
|
||||||
baseUrl,
|
|
||||||
null,
|
|
||||||
'false',
|
|
||||||
parentData.server.server_type,
|
|
||||||
'',
|
|
||||||
grid_title,
|
|
||||||
sql,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$.get(url_for('datagrid.filter'),
|
$.get(url_for('datagrid.filter'),
|
||||||
function(data) {
|
function(data) {
|
||||||
alertify.filterDialog(`Data Filter - ${grid_title}`, data, validateUrl, preferences, okCallback)
|
alertify.filterDialog(`Data Filter - ${queryToolTitle}`, data, validateUrl, preferences, okCallback)
|
||||||
.resizeTo(pgBrowser.stdW.sm,pgBrowser.stdH.sm);
|
.resizeTo(pgBrowser.stdW.sm,pgBrowser.stdH.sm);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
datagrid.create_transaction(
|
datagrid.launch_grid(transId, gridUrl, false, queryToolTitle);
|
||||||
baseUrl,
|
|
||||||
null,
|
|
||||||
'false',
|
|
||||||
parentData.server.server_type,
|
|
||||||
'',
|
|
||||||
grid_title,
|
|
||||||
''
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,17 +79,21 @@ export function retrieveNameSpaceName(parentData) {
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateUrl(connectionData, nodeData, parentData) {
|
function generateUrl(trans_id, connectionData, nodeData, parentData) {
|
||||||
const url_params = {
|
let url_endpoint = url_for('datagrid.panel', {
|
||||||
'cmd_type': connectionData.mnuid,
|
'trans_id': trans_id,
|
||||||
'obj_type': nodeData._type,
|
});
|
||||||
'sgid': parentData.server_group._id,
|
|
||||||
'sid': parentData.server._id,
|
|
||||||
'did': parentData.database._id,
|
|
||||||
'obj_id': nodeData._id,
|
|
||||||
};
|
|
||||||
|
|
||||||
return url_for('datagrid.initialize_datagrid', url_params);
|
url_endpoint += `?is_query_tool=${false}`
|
||||||
|
+`&cmd_type=${connectionData.mnuid}`
|
||||||
|
+`&obj_type=${nodeData._type}`
|
||||||
|
+`&obj_id=${nodeData._id}`
|
||||||
|
+`&sgid=${parentData.server_group._id}`
|
||||||
|
+`&sid=${parentData.server._id}`
|
||||||
|
+`&did=${parentData.database._id}`
|
||||||
|
+`&server_type=${parentData.server.server_type}`;
|
||||||
|
|
||||||
|
return url_endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateFilterValidateUrl(nodeData, parentData) {
|
function generateFilterValidateUrl(nodeData, parentData) {
|
||||||
|
@ -16,19 +16,21 @@ function hasDatabaseInformation(parentData) {
|
|||||||
return parentData.database;
|
return parentData.database;
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateUrl(parentData) {
|
function generateUrl(trans_id, title, parentData) {
|
||||||
let url_endpoint = 'datagrid.initialize_query_tool';
|
let url_endpoint = url_for('datagrid.panel', {
|
||||||
let url_params = {
|
'trans_id': trans_id,
|
||||||
'sgid': parentData.server_group._id,
|
});
|
||||||
'sid': parentData.server._id,
|
|
||||||
};
|
url_endpoint += `?is_query_tool=${true}`
|
||||||
|
+`&sgid=${parentData.server_group._id}`
|
||||||
|
+`&sid=${parentData.server._id}`
|
||||||
|
+`&server_type=${parentData.server.server_type}`;
|
||||||
|
|
||||||
if (hasDatabaseInformation(parentData)) {
|
if (hasDatabaseInformation(parentData)) {
|
||||||
url_params['did'] = parentData.database._id;
|
url_endpoint += `&did=${parentData.database._id}`;
|
||||||
url_endpoint = 'datagrid.initialize_query_tool_with_did';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return url_for(url_endpoint, url_params);
|
return url_endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasServerInformations(parentData) {
|
function hasServerInformations(parentData) {
|
||||||
@ -40,7 +42,7 @@ function generateTitle(pgBrowser, aciTreeIdentifier) {
|
|||||||
return baseTitle;
|
return baseTitle;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function showQueryTool(datagrid, pgBrowser, alertify, url, aciTreeIdentifier) {
|
export function showQueryTool(datagrid, pgBrowser, alertify, url, aciTreeIdentifier, transId) {
|
||||||
const sURL = url || '';
|
const sURL = url || '';
|
||||||
const queryToolTitle = generateTitle(pgBrowser, aciTreeIdentifier);
|
const queryToolTitle = generateTitle(pgBrowser, aciTreeIdentifier);
|
||||||
|
|
||||||
@ -60,9 +62,7 @@ export function showQueryTool(datagrid, pgBrowser, alertify, url, aciTreeIdentif
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const baseUrl = generateUrl(parentData);
|
const gridUrl = generateUrl(transId, queryToolTitle, parentData);
|
||||||
|
|
||||||
datagrid.create_transaction(
|
datagrid.launch_grid(transId, gridUrl, true, queryToolTitle, sURL);
|
||||||
baseUrl, null, 'true',
|
|
||||||
parentData.server.server_type, sURL, queryToolTitle, '', false);
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% block title %}{{ config.APP_NAME }} - Datagrid{% endblock %}
|
{% block title %}{{title}}{% endblock %}
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<style>
|
<style>
|
||||||
body {padding: 0px;}
|
body {padding: 0px;}
|
||||||
@ -228,7 +228,7 @@
|
|||||||
</button>
|
</button>
|
||||||
<button id="btn-flash" data-test-selector="execute-refresh-button" type="button" class="btn btn-sm btn-secondary" style="width: 32px;"
|
<button id="btn-flash" data-test-selector="execute-refresh-button" type="button" class="btn btn-sm btn-secondary" style="width: 32px;"
|
||||||
title=""
|
title=""
|
||||||
tabindex="0">
|
tabindex="0" disabled>
|
||||||
<i class="fa fa-bolt sql-icon-lg" aria-hidden="true"></i>
|
<i class="fa fa-bolt sql-icon-lg" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
<button id="btn-query-dropdown" type="button" class="btn btn-sm btn-secondary dropdown-toggle dropdown-toggle-split"
|
<button id="btn-query-dropdown" type="button" class="btn btn-sm btn-secondary dropdown-toggle dropdown-toggle-split"
|
||||||
@ -256,12 +256,12 @@
|
|||||||
<button id="btn-explain" type="button" class="btn btn-sm btn-secondary"
|
<button id="btn-explain" type="button" class="btn btn-sm btn-secondary"
|
||||||
title=""
|
title=""
|
||||||
accesskey=""
|
accesskey=""
|
||||||
tabindex="0">
|
tabindex="0" disabled>
|
||||||
<i class="fa fa-hand-pointer-o sql-icon-lg" aria-hidden="true"></i>
|
<i class="fa fa-hand-pointer-o sql-icon-lg" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
<button id="btn-explain-analyze" type="button" class="btn btn-sm btn-secondary"
|
<button id="btn-explain-analyze" type="button" class="btn btn-sm btn-secondary"
|
||||||
title=""
|
title=""
|
||||||
accesskey="">
|
accesskey="" disabled>
|
||||||
<i class="fa fa-list-alt sql-icon-lg" aria-hidden="true"></i>
|
<i class="fa fa-list-alt sql-icon-lg" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
<button id="btn-explain-options-dropdown" type="button" class="btn btn-sm btn-secondary dropdown-toggle dropdown-toggle-split"
|
<button id="btn-explain-options-dropdown" type="button" class="btn btn-sm btn-secondary dropdown-toggle dropdown-toggle-split"
|
||||||
@ -358,20 +358,20 @@
|
|||||||
data-panel-visible="visible"
|
data-panel-visible="visible"
|
||||||
accesskey=""
|
accesskey=""
|
||||||
tabindex="0">
|
tabindex="0">
|
||||||
<i class="fa-custom fa-query-tool-disconnected" aria-hidden="true"
|
<i class="fa-custom fa-query-tool-disconnected obtaining-conn" aria-hidden="true"
|
||||||
title="">
|
title="">
|
||||||
</i>
|
</i>
|
||||||
</div>
|
</div>
|
||||||
<div class="editor-title"
|
<div class="editor-title"
|
||||||
style="background-color: {% if fgcolor %}{{ bgcolor or '#FFFFFF' }}{% endif %}; color: {% if fgcolor %}{{ fgcolor }}{% endif %};"></div>
|
style="background-color: {% if fgcolor %}{{ bgcolor or '#FFFFFF' }}{% endif %}; color: {% if fgcolor %}{{ fgcolor }}{% endif %};"> </div>
|
||||||
</div>
|
</div>
|
||||||
<div id="editor-panel" tabindex="0">
|
<div id="editor-panel" tabindex="0">
|
||||||
<div id="fetching_data" class="pg-sp-container sql-editor-busy-fetching d-none">
|
<div id="fetching_data" class="pg-sp-container sql-editor-busy-fetching">
|
||||||
<div class="pg-sp-content">
|
<div class="pg-sp-content">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12 pg-sp-icon sql-editor-busy-icon"></div>
|
<div class="col-12 pg-sp-icon sql-editor-busy-icon"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row"><div class="col-12 pg-sp-text sql-editor-busy-text">{{ _('Loading {0} v{1}...').format(config.APP_NAME, config.APP_VERSION) }}</div></div>
|
<div class="row"><div class="col-12 pg-sp-text sql-editor-busy-text">{{ _('Loading...') }}</div></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -427,13 +427,8 @@
|
|||||||
// Start the query tool.
|
// Start the query tool.
|
||||||
sqlEditorController.start(
|
sqlEditorController.start(
|
||||||
{{ uniqueId }},
|
{{ uniqueId }},
|
||||||
{{ is_query_tool }},
|
|
||||||
"{{ editor_title }}",
|
|
||||||
script_type_url,
|
|
||||||
"{{ server_type }}",
|
|
||||||
{{ url_params|safe}},
|
{{ url_params|safe}},
|
||||||
'{{ layout|safe }}',
|
'{{ layout|safe }}',
|
||||||
{{ server_ver }}
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -291,6 +291,10 @@ input.editor-checkbox:focus {
|
|||||||
background-image: url('../img/disconnect.svg');
|
background-image: url('../img/disconnect.svg');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.connection_status .obtaining-conn {
|
||||||
|
background-image: url('../img/loading.gif') !important;
|
||||||
|
}
|
||||||
|
|
||||||
.icon-commit, .icon-rollback, .icon-save-data-changes, .icon-view-data {
|
.icon-commit, .icon-rollback, .icon-save-data-changes, .icon-view-data {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
align-content: center;
|
align-content: center;
|
||||||
|
BIN
web/pgadmin/tools/sqleditor/static/img/loading.gif
Normal file
BIN
web/pgadmin/tools/sqleditor/static/img/loading.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
@ -83,7 +83,6 @@ define('tools.querytool', [
|
|||||||
this.handler.preferences = this.preferences;
|
this.handler.preferences = this.preferences;
|
||||||
this.connIntervalId = null;
|
this.connIntervalId = null;
|
||||||
this.layout = opts.layout;
|
this.layout = opts.layout;
|
||||||
this.set_server_version(opts.server_ver);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Bind all the events
|
// Bind all the events
|
||||||
@ -188,12 +187,14 @@ define('tools.querytool', [
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
set_editor_title: function(title) {
|
||||||
|
this.$el.find('.editor-title').text(title);
|
||||||
|
},
|
||||||
|
|
||||||
// This function is used to render the template.
|
// This function is used to render the template.
|
||||||
render: function() {
|
render: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
$('.editor-title').text(_.unescape(self.editor_title));
|
|
||||||
|
|
||||||
// Updates connection status flag
|
// Updates connection status flag
|
||||||
self.gain_focus = function() {
|
self.gain_focus = function() {
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
@ -207,7 +208,6 @@ define('tools.querytool', [
|
|||||||
}, 100);
|
}, 100);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Create main wcDocker instance
|
// Create main wcDocker instance
|
||||||
self.docker = new wcDocker(
|
self.docker = new wcDocker(
|
||||||
'#editor-panel', {
|
'#editor-panel', {
|
||||||
@ -338,6 +338,10 @@ define('tools.querytool', [
|
|||||||
});
|
});
|
||||||
|
|
||||||
self.render_history_grid();
|
self.render_history_grid();
|
||||||
|
pgBrowser.Events.on('pgadmin:query_tool:connected:'+self.handler.transId, ()=>{
|
||||||
|
self.fetch_query_history();
|
||||||
|
});
|
||||||
|
|
||||||
queryToolNotifications.renderNotificationsGrid(self.notifications_panel);
|
queryToolNotifications.renderNotificationsGrid(self.notifications_panel);
|
||||||
|
|
||||||
var text_container = $('<textarea id="sql_query_tool" tabindex="-1"></textarea>');
|
var text_container = $('<textarea id="sql_query_tool" tabindex="-1"></textarea>');
|
||||||
@ -1327,6 +1331,24 @@ define('tools.querytool', [
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
fetch_query_history: function() {
|
||||||
|
let self = this;
|
||||||
|
$.ajax({
|
||||||
|
url: url_for('sqleditor.get_query_history', {
|
||||||
|
'trans_id': self.handler.transId,
|
||||||
|
}),
|
||||||
|
method: 'GET',
|
||||||
|
contentType: 'application/json',
|
||||||
|
}).done(function(res) {
|
||||||
|
res.data.result.map((entry) => {
|
||||||
|
let newEntry = JSON.parse(entry);
|
||||||
|
newEntry.start_time = new Date(newEntry.start_time);
|
||||||
|
self.history_collection.add(newEntry);
|
||||||
|
});
|
||||||
|
}).fail(function() {
|
||||||
|
/* history fetch fail should not affect query tool */
|
||||||
|
});
|
||||||
|
},
|
||||||
/* This function is responsible to create and render the
|
/* This function is responsible to create and render the
|
||||||
* new backgrid for the history tab.
|
* new backgrid for the history tab.
|
||||||
*/
|
*/
|
||||||
@ -1363,25 +1385,6 @@ define('tools.querytool', [
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make ajax call to get history data
|
|
||||||
$.ajax({
|
|
||||||
url: url_for('sqleditor.get_query_history', {
|
|
||||||
'trans_id': self.handler.transId,
|
|
||||||
}),
|
|
||||||
method: 'GET',
|
|
||||||
contentType: 'application/json',
|
|
||||||
})
|
|
||||||
.done(function(res) {
|
|
||||||
res.data.result.map((entry) => {
|
|
||||||
let newEntry = JSON.parse(entry);
|
|
||||||
newEntry.start_time = new Date(newEntry.start_time);
|
|
||||||
self.history_collection.add(newEntry);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.fail(function() {
|
|
||||||
/* history fetch fail should not affect query tool */
|
|
||||||
});
|
|
||||||
|
|
||||||
if(!self.handler.is_query_tool) {
|
if(!self.handler.is_query_tool) {
|
||||||
self.historyComponent.setEditorPref({'copy_to_editor':false});
|
self.historyComponent.setEditorPref({'copy_to_editor':false});
|
||||||
}
|
}
|
||||||
@ -2016,13 +2019,13 @@ define('tools.querytool', [
|
|||||||
},
|
},
|
||||||
|
|
||||||
initTransaction: function() {
|
initTransaction: function() {
|
||||||
var url_endpoint;
|
var self = this, url_endpoint;
|
||||||
if (this.is_query_tool) {
|
if (self.is_query_tool) {
|
||||||
url_endpoint = 'datagrid.initialize_query_tool';
|
url_endpoint = 'datagrid.initialize_query_tool';
|
||||||
|
|
||||||
// If database not present then use Maintenance database
|
// If database not present then use Maintenance database
|
||||||
// We will handle this at server side
|
// We will handle this at server side
|
||||||
if (this.url_params.did) {
|
if (self.url_params.did) {
|
||||||
url_endpoint = 'datagrid.initialize_query_tool_with_did';
|
url_endpoint = 'datagrid.initialize_query_tool_with_did';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2030,10 +2033,25 @@ define('tools.querytool', [
|
|||||||
url_endpoint = 'datagrid.initialize_datagrid';
|
url_endpoint = 'datagrid.initialize_datagrid';
|
||||||
}
|
}
|
||||||
|
|
||||||
var baseUrl = url_for(url_endpoint, this.url_params);
|
var baseUrl = url_for(url_endpoint, {
|
||||||
|
...self.url_params,
|
||||||
|
'trans_id': self.transId,
|
||||||
|
});
|
||||||
|
|
||||||
Datagrid.create_transaction(baseUrl, this, this.is_query_tool,
|
$.ajax({
|
||||||
this.server_type, '', '', '', true);
|
url: baseUrl,
|
||||||
|
type: 'POST',
|
||||||
|
data: self.is_query_tool?null:JSON.stringify(self.url_params.sql_filter),
|
||||||
|
contentType: 'application/json',
|
||||||
|
}).done((res)=>{
|
||||||
|
pgBrowser.Events.trigger(
|
||||||
|
'pgadmin:query_tool:connected:' + self.transId, res.data
|
||||||
|
);
|
||||||
|
}).fail((xhr, status, error)=>{
|
||||||
|
pgBrowser.Events.trigger(
|
||||||
|
'pgadmin:query_tool:connected_fail:' + self.transId, xhr, error
|
||||||
|
);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
handle_connection_lost: function(create_transaction, xhr) {
|
handle_connection_lost: function(create_transaction, xhr) {
|
||||||
@ -2138,12 +2156,10 @@ define('tools.querytool', [
|
|||||||
* call the render method of the grid view to render the backgrid
|
* call the render method of the grid view to render the backgrid
|
||||||
* header and loading icon and start execution of the sql query.
|
* header and loading icon and start execution of the sql query.
|
||||||
*/
|
*/
|
||||||
start: function(transId, is_query_tool, editor_title, script_type_url,
|
start: function(transId, url_params, layout) {
|
||||||
server_type, url_params, layout, server_ver
|
|
||||||
) {
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self.is_query_tool = is_query_tool;
|
self.is_query_tool = url_params.is_query_tool==='true'?true:false;
|
||||||
self.rows_affected = 0;
|
self.rows_affected = 0;
|
||||||
self.marked_line_no = 0;
|
self.marked_line_no = 0;
|
||||||
self.has_more_rows = false;
|
self.has_more_rows = false;
|
||||||
@ -2151,9 +2167,8 @@ define('tools.querytool', [
|
|||||||
self.close_on_save = false;
|
self.close_on_save = false;
|
||||||
self.close_on_idle_transaction = false;
|
self.close_on_idle_transaction = false;
|
||||||
self.last_transaction_status = -1;
|
self.last_transaction_status = -1;
|
||||||
self.server_type = server_type;
|
self.server_type = url_params.server_type;
|
||||||
self.url_params = url_params;
|
self.url_params = url_params;
|
||||||
self.script_type_url = script_type_url;
|
|
||||||
self.is_transaction_buttons_disabled = true;
|
self.is_transaction_buttons_disabled = true;
|
||||||
|
|
||||||
// We do not allow to call the start multiple times.
|
// We do not allow to call the start multiple times.
|
||||||
@ -2164,16 +2179,48 @@ define('tools.querytool', [
|
|||||||
el: self.container,
|
el: self.container,
|
||||||
handler: self,
|
handler: self,
|
||||||
layout: layout,
|
layout: layout,
|
||||||
server_ver: server_ver,
|
|
||||||
});
|
});
|
||||||
self.transId = self.gridView.transId = transId;
|
self.transId = self.gridView.transId = transId;
|
||||||
|
|
||||||
self.gridView.editor_title = _.unescape(editor_title);
|
|
||||||
self.gridView.current_file = undefined;
|
self.gridView.current_file = undefined;
|
||||||
|
|
||||||
// Render the header
|
// Render the header
|
||||||
self.gridView.render();
|
self.gridView.render();
|
||||||
|
|
||||||
|
self.trigger('pgadmin-sqleditor:loading-icon:hide');
|
||||||
|
|
||||||
|
self.gridView.set_editor_title(`(${gettext('Obtaining connection...')} ${_.unescape(url_params.title)}`);
|
||||||
|
|
||||||
|
let afterConn = function() {
|
||||||
|
let enableBtns = [];
|
||||||
|
|
||||||
|
if(self.is_query_tool){
|
||||||
|
enableBtns = ['#btn-flash', '#btn-explain', '#btn-explain-analyze'];
|
||||||
|
} else {
|
||||||
|
enableBtns = ['#btn-flash'];
|
||||||
|
}
|
||||||
|
|
||||||
|
enableBtns.forEach((selector)=>{
|
||||||
|
$(selector).prop('disabled', false);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#btn-conn-status i').removeClass('obtaining-conn');
|
||||||
|
self.gridView.set_editor_title(_.unescape(url_params.title));
|
||||||
|
};
|
||||||
|
|
||||||
|
pgBrowser.Events.on('pgadmin:query_tool:connected:' + transId, afterConn);
|
||||||
|
pgBrowser.Events.on('pgadmin:query_tool:connected_fail:' + transId, afterConn);
|
||||||
|
|
||||||
|
pgBrowser.Events.on('pgadmin:query_tool:connected:' + transId, (res_data)=>{
|
||||||
|
self.gridView.set_server_version(res_data.serverVersion);
|
||||||
|
});
|
||||||
|
|
||||||
|
pgBrowser.Events.on('pgadmin:query_tool:connected_fail:' + transId, (xhr, error)=>{
|
||||||
|
alertify.pgRespErrorNotify(xhr, error);
|
||||||
|
});
|
||||||
|
|
||||||
|
self.initTransaction();
|
||||||
|
|
||||||
/* wcDocker focuses on window always, and all our shortcuts are
|
/* wcDocker focuses on window always, and all our shortcuts are
|
||||||
* bind to editor-panel. So when we use wcDocker focus, editor-panel
|
* bind to editor-panel. So when we use wcDocker focus, editor-panel
|
||||||
* loses focus and events don't work.
|
* loses focus and events don't work.
|
||||||
@ -2187,9 +2234,9 @@ define('tools.querytool', [
|
|||||||
if (self.is_query_tool) {
|
if (self.is_query_tool) {
|
||||||
// Fetch the SQL for Scripts (eg: CREATE/UPDATE/DELETE/SELECT)
|
// Fetch the SQL for Scripts (eg: CREATE/UPDATE/DELETE/SELECT)
|
||||||
// Call AJAX only if script type url is present
|
// Call AJAX only if script type url is present
|
||||||
if (script_type_url) {
|
if (url_params.query_url) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: script_type_url,
|
url: url_params.query_url,
|
||||||
type:'GET',
|
type:'GET',
|
||||||
})
|
})
|
||||||
.done(function(res) {
|
.done(function(res) {
|
||||||
@ -2224,7 +2271,9 @@ define('tools.querytool', [
|
|||||||
cm.className += ' bg-gray-lighter opacity-5 hide-cursor-workaround';
|
cm.className += ' bg-gray-lighter opacity-5 hide-cursor-workaround';
|
||||||
}
|
}
|
||||||
self.disable_tool_buttons(true);
|
self.disable_tool_buttons(true);
|
||||||
|
pgBrowser.Events.on('pgadmin:query_tool:connected:'+ transId,()=>{
|
||||||
self.execute_data_query();
|
self.execute_data_query();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -3334,7 +3383,7 @@ define('tools.querytool', [
|
|||||||
// Find the title of the visible panel
|
// Find the title of the visible panel
|
||||||
_.each(window.top.pgAdmin.Browser.docker.findPanels('frm_datagrid'), function(p) {
|
_.each(window.top.pgAdmin.Browser.docker.findPanels('frm_datagrid'), function(p) {
|
||||||
if (p.isVisible()) {
|
if (p.isVisible()) {
|
||||||
self.gridView.panel_title = $(p._title).text();
|
self.gridView.panel_title = $(p._title).html();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ class TestDownloadCSV(BaseTestGenerator):
|
|||||||
'Download csv URL with valid query',
|
'Download csv URL with valid query',
|
||||||
dict(
|
dict(
|
||||||
sql='SELECT 1 as "A",2 as "B",3 as "C"',
|
sql='SELECT 1 as "A",2 as "B",3 as "C"',
|
||||||
init_url='/datagrid/initialize/query_tool/{0}/{1}/{2}',
|
init_url='/datagrid/initialize/query_tool/{0}/{1}/{2}/{3}',
|
||||||
donwload_url="/sqleditor/query_tool/download/{0}",
|
donwload_url="/sqleditor/query_tool/download/{0}",
|
||||||
output_columns='"A","B","C"',
|
output_columns='"A","B","C"',
|
||||||
output_values='1,2,3',
|
output_values='1,2,3',
|
||||||
@ -39,7 +39,7 @@ class TestDownloadCSV(BaseTestGenerator):
|
|||||||
'Download csv URL with wrong TX id',
|
'Download csv URL with wrong TX id',
|
||||||
dict(
|
dict(
|
||||||
sql='SELECT 1 as "A",2 as "B",3 as "C"',
|
sql='SELECT 1 as "A",2 as "B",3 as "C"',
|
||||||
init_url='/datagrid/initialize/query_tool/{0}/{1}/{2}',
|
init_url='/datagrid/initialize/query_tool/{0}/{1}/{2}/{3}',
|
||||||
donwload_url="/sqleditor/query_tool/download/{0}",
|
donwload_url="/sqleditor/query_tool/download/{0}",
|
||||||
output_columns=None,
|
output_columns=None,
|
||||||
output_values=None,
|
output_values=None,
|
||||||
@ -51,7 +51,7 @@ class TestDownloadCSV(BaseTestGenerator):
|
|||||||
'Download csv URL with wrong query',
|
'Download csv URL with wrong query',
|
||||||
dict(
|
dict(
|
||||||
sql='SELECT * FROM this_table_does_not_exist',
|
sql='SELECT * FROM this_table_does_not_exist',
|
||||||
init_url='/datagrid/initialize/query_tool/{0}/{1}/{2}',
|
init_url='/datagrid/initialize/query_tool/{0}/{1}/{2}/{3}',
|
||||||
donwload_url="/sqleditor/query_tool/download/{0}",
|
donwload_url="/sqleditor/query_tool/download/{0}",
|
||||||
output_columns=None,
|
output_columns=None,
|
||||||
output_values=None,
|
output_values=None,
|
||||||
@ -81,13 +81,12 @@ class TestDownloadCSV(BaseTestGenerator):
|
|||||||
raise Exception("Could not connect to the database.")
|
raise Exception("Could not connect to the database.")
|
||||||
|
|
||||||
# Initialize query tool
|
# Initialize query tool
|
||||||
|
self.trans_id = str(random.randint(1, 9999999))
|
||||||
url = self.init_url.format(
|
url = self.init_url.format(
|
||||||
test_utils.SERVER_GROUP, self._sid, self._did)
|
self.trans_id, test_utils.SERVER_GROUP, self._sid, self._did)
|
||||||
response = self.tester.post(url)
|
response = self.tester.post(url)
|
||||||
self.assertEquals(response.status_code, 200)
|
self.assertEquals(response.status_code, 200)
|
||||||
|
|
||||||
response_data = json.loads(response.data.decode('utf-8'))
|
|
||||||
self.trans_id = response_data['data']['gridTransId']
|
|
||||||
# If invalid tx test then make the Tx id invalid so that tests fails
|
# If invalid tx test then make the Tx id invalid so that tests fails
|
||||||
if not self.is_valid_tx:
|
if not self.is_valid_tx:
|
||||||
self.trans_id = self.trans_id + '007'
|
self.trans_id = self.trans_id + '007'
|
||||||
|
@ -14,6 +14,7 @@ from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
|||||||
from pgadmin.utils.route import BaseTestGenerator
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
from regression import parent_node_dict
|
from regression import parent_node_dict
|
||||||
from regression.python_test_utils import test_utils as utils
|
from regression.python_test_utils import test_utils as utils
|
||||||
|
import random
|
||||||
|
|
||||||
|
|
||||||
class TestEditorHistory(BaseTestGenerator):
|
class TestEditorHistory(BaseTestGenerator):
|
||||||
@ -68,14 +69,12 @@ class TestEditorHistory(BaseTestGenerator):
|
|||||||
raise Exception("Could not connect to the database.")
|
raise Exception("Could not connect to the database.")
|
||||||
|
|
||||||
# Initialize query tool
|
# Initialize query tool
|
||||||
url = '/datagrid/initialize/query_tool/{0}/{1}/{2}'.format(
|
self.trans_id = str(random.randint(1, 9999999))
|
||||||
utils.SERVER_GROUP, self.server_id, self.db_id)
|
url = '/datagrid/initialize/query_tool/{0}/{1}/{2}/{3}'.format(
|
||||||
|
self.trans_id, utils.SERVER_GROUP, self.server_id, self.db_id)
|
||||||
response = self.tester.post(url)
|
response = self.tester.post(url)
|
||||||
self.assertEquals(response.status_code, 200)
|
self.assertEquals(response.status_code, 200)
|
||||||
|
|
||||||
response_data = json.loads(response.data.decode('utf-8'))
|
|
||||||
self.trans_id = response_data['data']['gridTransId']
|
|
||||||
|
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
url = '/sqleditor/query_history/{0}'.format(self.trans_id)
|
url = '/sqleditor/query_history/{0}'.format(self.trans_id)
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
from pgadmin.utils.route import BaseTestGenerator
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
||||||
database_utils
|
database_utils
|
||||||
from regression import parent_node_dict
|
|
||||||
from regression.python_test_utils import test_utils
|
from regression.python_test_utils import test_utils
|
||||||
import json
|
import json
|
||||||
from pgadmin.utils import server_utils, IS_PY2
|
from pgadmin.utils import server_utils, IS_PY2
|
||||||
@ -256,14 +255,13 @@ class TestEncodingCharset(BaseTestGenerator):
|
|||||||
raise Exception("Could not connect to the database.")
|
raise Exception("Could not connect to the database.")
|
||||||
|
|
||||||
# Initialize query tool
|
# Initialize query tool
|
||||||
url = '/datagrid/initialize/query_tool/{0}/{1}/{2}'.format(
|
self.trans_id = str(random.randint(1, 9999999))
|
||||||
test_utils.SERVER_GROUP, self.encode_sid, self.encode_did)
|
url = '/datagrid/initialize/query_tool/{0}/{1}/{2}/{3}'\
|
||||||
|
.format(self.trans_id, test_utils.SERVER_GROUP, self.encode_sid,
|
||||||
|
self.encode_did)
|
||||||
response = self.tester.post(url)
|
response = self.tester.post(url)
|
||||||
self.assertEquals(response.status_code, 200)
|
self.assertEquals(response.status_code, 200)
|
||||||
|
|
||||||
response_data = json.loads(response.data.decode('utf-8'))
|
|
||||||
self.trans_id = response_data['data']['gridTransId']
|
|
||||||
|
|
||||||
# Check character
|
# Check character
|
||||||
url = "/sqleditor/query_tool/start/{0}".format(self.trans_id)
|
url = "/sqleditor/query_tool/start/{0}".format(self.trans_id)
|
||||||
sql = "select E'{0}';".format(self.test_str)
|
sql = "select E'{0}';".format(self.test_str)
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
import random
|
||||||
|
|
||||||
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
||||||
database_utils
|
database_utils
|
||||||
@ -32,14 +33,12 @@ class TestExplainPlan(BaseTestGenerator):
|
|||||||
raise Exception("Could not connect to the database.")
|
raise Exception("Could not connect to the database.")
|
||||||
|
|
||||||
# Initialize query tool
|
# Initialize query tool
|
||||||
url = '/datagrid/initialize/query_tool/{0}/{1}/{2}'.format(
|
self.trans_id = str(random.randint(1, 9999999))
|
||||||
utils.SERVER_GROUP, self.server_id, self.db_id)
|
url = '/datagrid/initialize/query_tool/{0}/{1}/{2}/{3}'.format(
|
||||||
|
self.trans_id, utils.SERVER_GROUP, self.server_id, self.db_id)
|
||||||
response = self.tester.post(url)
|
response = self.tester.post(url)
|
||||||
self.assertEquals(response.status_code, 200)
|
self.assertEquals(response.status_code, 200)
|
||||||
|
|
||||||
response_data = json.loads(response.data.decode('utf-8'))
|
|
||||||
self.trans_id = response_data['data']['gridTransId']
|
|
||||||
|
|
||||||
# Start query tool transaction
|
# Start query tool transaction
|
||||||
url = '/sqleditor/query_tool/start/{0}'.format(self.trans_id)
|
url = '/sqleditor/query_tool/start/{0}'.format(self.trans_id)
|
||||||
response = self.tester.post(
|
response = self.tester.post(
|
||||||
|
@ -14,6 +14,7 @@ from pgadmin.browser.server_groups.servers.databases.tests import utils as \
|
|||||||
from pgadmin.utils.route import BaseTestGenerator
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
from regression import parent_node_dict
|
from regression import parent_node_dict
|
||||||
from regression.python_test_utils import test_utils as utils
|
from regression.python_test_utils import test_utils as utils
|
||||||
|
import random
|
||||||
|
|
||||||
|
|
||||||
class TestPollQueryTool(BaseTestGenerator):
|
class TestPollQueryTool(BaseTestGenerator):
|
||||||
@ -75,14 +76,12 @@ NOTICE: Hello, world!
|
|||||||
raise Exception("Could not connect to the database.")
|
raise Exception("Could not connect to the database.")
|
||||||
|
|
||||||
# Initialize query tool
|
# Initialize query tool
|
||||||
url = '/datagrid/initialize/query_tool/{0}/{1}/{2}'.format(
|
self.trans_id = str(random.randint(1, 9999999))
|
||||||
utils.SERVER_GROUP, self.server_id, self.db_id)
|
url = '/datagrid/initialize/query_tool/{0}/{1}/{2}/{3}'.format(
|
||||||
|
self.trans_id, utils.SERVER_GROUP, self.server_id, self.db_id)
|
||||||
response = self.tester.post(url)
|
response = self.tester.post(url)
|
||||||
self.assertEquals(response.status_code, 200)
|
self.assertEquals(response.status_code, 200)
|
||||||
|
|
||||||
response_data = json.loads(response.data.decode('utf-8'))
|
|
||||||
self.trans_id = response_data['data']['gridTransId']
|
|
||||||
|
|
||||||
cnt = 0
|
cnt = 0
|
||||||
for s in self.sql:
|
for s in self.sql:
|
||||||
print("Executing and polling with: " + self.print_messages[cnt])
|
print("Executing and polling with: " + self.print_messages[cnt])
|
||||||
|
@ -301,14 +301,12 @@ class TestTransactionControl(BaseTestGenerator):
|
|||||||
raise Exception("Could not connect to the database.")
|
raise Exception("Could not connect to the database.")
|
||||||
|
|
||||||
def _initialize_query_tool(self):
|
def _initialize_query_tool(self):
|
||||||
url = '/datagrid/initialize/query_tool/{0}/{1}/{2}'.format(
|
self.trans_id = str(random.randint(1, 9999999))
|
||||||
utils.SERVER_GROUP, self.server_id, self.db_id)
|
url = '/datagrid/initialize/query_tool/{0}/{1}/{2}/{3}'.format(
|
||||||
|
self.trans_id, utils.SERVER_GROUP, self.server_id, self.db_id)
|
||||||
response = self.tester.post(url)
|
response = self.tester.post(url)
|
||||||
self.assertEquals(response.status_code, 200)
|
self.assertEquals(response.status_code, 200)
|
||||||
|
|
||||||
response_data = json.loads(response.data.decode('utf-8'))
|
|
||||||
self.trans_id = response_data['data']['gridTransId']
|
|
||||||
|
|
||||||
def _initialize_urls(self):
|
def _initialize_urls(self):
|
||||||
self.start_query_tool_url = \
|
self.start_query_tool_url = \
|
||||||
'/sqleditor/query_tool/start/{0}'.format(self.trans_id)
|
'/sqleditor/query_tool/start/{0}'.format(self.trans_id)
|
||||||
|
@ -70,15 +70,14 @@ class TestViewData(BaseTestGenerator):
|
|||||||
table_id = result[0][0]
|
table_id = result[0][0]
|
||||||
|
|
||||||
# Initialize query tool
|
# Initialize query tool
|
||||||
url = '/datagrid/initialize/datagrid/3/table/{0}/{1}/{2}/{3}'.format(
|
self.trans_id = str(random.randint(1, 9999999))
|
||||||
test_utils.SERVER_GROUP, self.server_id, self.db_id, table_id)
|
url = '/datagrid/initialize/datagrid/{0}/3/table/{1}/{2}/{3}/{4}'\
|
||||||
|
.format(self.trans_id, test_utils.SERVER_GROUP, self.server_id,
|
||||||
|
self.db_id, table_id)
|
||||||
response = self.tester.post(url)
|
response = self.tester.post(url)
|
||||||
|
|
||||||
self.assertEquals(response.status_code, 200)
|
self.assertEquals(response.status_code, 200)
|
||||||
|
|
||||||
response_data = json.loads(response.data.decode('utf-8'))
|
|
||||||
self.trans_id = response_data['data']['gridTransId']
|
|
||||||
|
|
||||||
url = "/sqleditor/view_data/start/{0}".format(self.trans_id)
|
url = "/sqleditor/view_data/start/{0}".format(self.trans_id)
|
||||||
response = self.tester.get(url)
|
response = self.tester.get(url)
|
||||||
self.assertEquals(response.status_code, 200)
|
self.assertEquals(response.status_code, 200)
|
||||||
|
@ -149,14 +149,12 @@ class TestQueryUpdatableResultset(BaseTestGenerator):
|
|||||||
raise Exception("Could not connect to the database.")
|
raise Exception("Could not connect to the database.")
|
||||||
|
|
||||||
def _initialize_query_tool(self):
|
def _initialize_query_tool(self):
|
||||||
url = '/datagrid/initialize/query_tool/{0}/{1}/{2}'.format(
|
self.trans_id = str(random.randint(1, 9999999))
|
||||||
utils.SERVER_GROUP, self.server_id, self.db_id)
|
url = '/datagrid/initialize/query_tool/{0}/{1}/{2}/{3}'.format(
|
||||||
|
self.trans_id, utils.SERVER_GROUP, self.server_id, self.db_id)
|
||||||
response = self.tester.post(url)
|
response = self.tester.post(url)
|
||||||
self.assertEquals(response.status_code, 200)
|
self.assertEquals(response.status_code, 200)
|
||||||
|
|
||||||
response_data = json.loads(response.data.decode('utf-8'))
|
|
||||||
self.trans_id = response_data['data']['gridTransId']
|
|
||||||
|
|
||||||
def _initialize_urls(self):
|
def _initialize_urls(self):
|
||||||
self.start_query_tool_url = \
|
self.start_query_tool_url = \
|
||||||
'/sqleditor/query_tool/start/{0}'.format(self.trans_id)
|
'/sqleditor/query_tool/start/{0}'.format(self.trans_id)
|
||||||
|
@ -323,14 +323,12 @@ class TestSaveChangedData(BaseTestGenerator):
|
|||||||
raise Exception("Could not connect to the database.")
|
raise Exception("Could not connect to the database.")
|
||||||
|
|
||||||
def _initialize_query_tool(self):
|
def _initialize_query_tool(self):
|
||||||
url = '/datagrid/initialize/query_tool/{0}/{1}/{2}'.format(
|
self.trans_id = str(random.randint(1, 9999999))
|
||||||
utils.SERVER_GROUP, self.server_id, self.db_id)
|
url = '/datagrid/initialize/query_tool/{0}/{1}/{2}/{3}'.format(
|
||||||
|
self.trans_id, utils.SERVER_GROUP, self.server_id, self.db_id)
|
||||||
response = self.tester.post(url)
|
response = self.tester.post(url)
|
||||||
self.assertEquals(response.status_code, 200)
|
self.assertEquals(response.status_code, 200)
|
||||||
|
|
||||||
response_data = json.loads(response.data.decode('utf-8'))
|
|
||||||
self.trans_id = response_data['data']['gridTransId']
|
|
||||||
|
|
||||||
def _initialize_urls_and_select_sql(self):
|
def _initialize_urls_and_select_sql(self):
|
||||||
self.start_query_tool_url = \
|
self.start_query_tool_url = \
|
||||||
'/sqleditor/query_tool/start/{0}'.format(self.trans_id)
|
'/sqleditor/query_tool/start/{0}'.format(self.trans_id)
|
||||||
|
@ -17,10 +17,11 @@ describe('#show_data', () => {
|
|||||||
let datagrid;
|
let datagrid;
|
||||||
let pgBrowser;
|
let pgBrowser;
|
||||||
let alertify;
|
let alertify;
|
||||||
|
let transId = 98765432;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
alertify = jasmine.createSpyObj('alertify', ['alert']);
|
alertify = jasmine.createSpyObj('alertify', ['alert']);
|
||||||
datagrid = {
|
datagrid = {
|
||||||
create_transaction: jasmine.createSpy('create_transaction'),
|
launch_grid: jasmine.createSpy('launch_grid'),
|
||||||
};
|
};
|
||||||
pgBrowser = {
|
pgBrowser = {
|
||||||
treeMenu: new TreeFake(),
|
treeMenu: new TreeFake(),
|
||||||
@ -98,12 +99,12 @@ describe('#show_data', () => {
|
|||||||
|
|
||||||
context('cannot find the tree node', () => {
|
context('cannot find the tree node', () => {
|
||||||
it('does not create a transaction', () => {
|
it('does not create a transaction', () => {
|
||||||
showDataGrid(datagrid, pgBrowser, alertify, {}, [{id: '10'}]);
|
showDataGrid(datagrid, pgBrowser, alertify, {}, [{id: '10'}], transId);
|
||||||
expect(datagrid.create_transaction).not.toHaveBeenCalled();
|
expect(datagrid.launch_grid).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('display alert', () => {
|
it('display alert', () => {
|
||||||
showDataGrid(datagrid, pgBrowser, alertify, {}, [{id: '10'}]);
|
showDataGrid(datagrid, pgBrowser, alertify, {}, [{id: '10'}], transId);
|
||||||
expect(alertify.alert).toHaveBeenCalledWith(
|
expect(alertify.alert).toHaveBeenCalledWith(
|
||||||
'Data Grid Error',
|
'Data Grid Error',
|
||||||
'No object selected.'
|
'No object selected.'
|
||||||
@ -113,59 +114,52 @@ describe('#show_data', () => {
|
|||||||
|
|
||||||
context('current node is not underneath a server', () => {
|
context('current node is not underneath a server', () => {
|
||||||
it('does not create a transaction', () => {
|
it('does not create a transaction', () => {
|
||||||
showDataGrid(datagrid, pgBrowser, alertify, {}, [{id: 'parent'}]);
|
showDataGrid(datagrid, pgBrowser, alertify, {}, [{id: 'parent'}], transId);
|
||||||
expect(datagrid.create_transaction).not.toHaveBeenCalled();
|
expect(datagrid.launch_grid).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
context('current node is not underneath a schema or view or catalog', () => {
|
context('current node is not underneath a schema or view or catalog', () => {
|
||||||
it('does not create a transaction', () => {
|
it('does not create a transaction', () => {
|
||||||
showDataGrid(datagrid, pgBrowser, alertify, {}, [{id: 'database1'}]);
|
showDataGrid(datagrid, pgBrowser, alertify, {}, [{id: 'database1'}], transId);
|
||||||
expect(datagrid.create_transaction).not.toHaveBeenCalled();
|
expect(datagrid.launch_grid).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
context('current node is underneath a schema', () => {
|
context('current node is underneath a schema', () => {
|
||||||
it('does not create a transaction', () => {
|
it('does not create a transaction', () => {
|
||||||
showDataGrid(datagrid, pgBrowser, alertify, {mnuid: 11}, [{id: 'schema1'}]);
|
showDataGrid(datagrid, pgBrowser, alertify, {mnuid: 11}, [{id: 'schema1'}], transId);
|
||||||
expect(datagrid.create_transaction).toHaveBeenCalledWith(
|
|
||||||
'/initialize/datagrid/11/schema/1/2/3/4',
|
expect(datagrid.launch_grid).toHaveBeenCalledWith(
|
||||||
null,
|
98765432,
|
||||||
'false',
|
'/panel/98765432?is_query_tool=false&cmd_type=11&obj_type=schema&obj_id=4&sgid=1&sid=2&did=3&server_type=pg',
|
||||||
'pg',
|
false,
|
||||||
'',
|
'schema1.schema1/database1/someuser@server1'
|
||||||
'schema1.schema1/database1/someuser@server1',
|
|
||||||
''
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
context('current node is underneath a view', () => {
|
context('current node is underneath a view', () => {
|
||||||
it('does not create a transaction', () => {
|
it('does not create a transaction', () => {
|
||||||
showDataGrid(datagrid, pgBrowser, alertify, {mnuid: 11}, [{id: 'view1'}]);
|
showDataGrid(datagrid, pgBrowser, alertify, {mnuid: 11}, [{id: 'view1'}], transId);
|
||||||
expect(datagrid.create_transaction).toHaveBeenCalledWith(
|
|
||||||
'/initialize/datagrid/11/view/1/2/3/5',
|
expect(datagrid.launch_grid).toHaveBeenCalledWith(
|
||||||
null,
|
98765432,
|
||||||
'false',
|
'/panel/98765432?is_query_tool=false&cmd_type=11&obj_type=view&obj_id=5&sgid=1&sid=2&did=3&server_type=pg',
|
||||||
'pg',
|
false,
|
||||||
'',
|
'view1.view1/database1/someuser@server1'
|
||||||
'view1.view1/database1/someuser@server1',
|
|
||||||
''
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
context('current node is underneath a catalog', () => {
|
context('current node is underneath a catalog', () => {
|
||||||
it('does not create a transaction', () => {
|
it('does not create a transaction', () => {
|
||||||
showDataGrid(datagrid, pgBrowser, alertify, {mnuid: 11}, [{id: 'catalog1'}]);
|
showDataGrid(datagrid, pgBrowser, alertify, {mnuid: 11}, [{id: 'catalog1'}], transId);
|
||||||
expect(datagrid.create_transaction).toHaveBeenCalledWith(
|
expect(datagrid.launch_grid).toHaveBeenCalledWith(
|
||||||
'/initialize/datagrid/11/catalog/1/2/3/6',
|
98765432,
|
||||||
null,
|
'/panel/98765432?is_query_tool=false&cmd_type=11&obj_type=catalog&obj_id=6&sgid=1&sid=2&did=3&server_type=pg',
|
||||||
'false',
|
false,
|
||||||
'pg',
|
'catalog1.catalog1/database1/someuser@server1'
|
||||||
'',
|
|
||||||
'catalog1.catalog1/database1/someuser@server1',
|
|
||||||
''
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -17,10 +17,11 @@ describe('#showQueryTool', () => {
|
|||||||
let queryTool;
|
let queryTool;
|
||||||
let pgBrowser;
|
let pgBrowser;
|
||||||
let alertify;
|
let alertify;
|
||||||
|
let transId = 98765432;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
alertify = jasmine.createSpyObj('alertify', ['alert']);
|
alertify = jasmine.createSpyObj('alertify', ['alert']);
|
||||||
queryTool = {
|
queryTool = {
|
||||||
create_transaction: jasmine.createSpy('create_transaction'),
|
launch_grid: jasmine.createSpy('launch_grid'),
|
||||||
};
|
};
|
||||||
pgBrowser = {
|
pgBrowser = {
|
||||||
treeMenu: new TreeFake(),
|
treeMenu: new TreeFake(),
|
||||||
@ -66,10 +67,10 @@ describe('#showQueryTool', () => {
|
|||||||
|
|
||||||
context('cannot find the tree node', () => {
|
context('cannot find the tree node', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
showQueryTool(queryTool, pgBrowser, alertify, '', [{id: '10'}]);
|
showQueryTool(queryTool, pgBrowser, alertify, '', [{id: '10'}], transId);
|
||||||
});
|
});
|
||||||
it('does not create a transaction', () => {
|
it('does not create a transaction', () => {
|
||||||
expect(queryTool.create_transaction).not.toHaveBeenCalled();
|
expect(queryTool.launch_grid).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('display alert', () => {
|
it('display alert', () => {
|
||||||
@ -82,8 +83,8 @@ describe('#showQueryTool', () => {
|
|||||||
|
|
||||||
context('current node is not underneath a server', () => {
|
context('current node is not underneath a server', () => {
|
||||||
it('does not create a transaction', () => {
|
it('does not create a transaction', () => {
|
||||||
showQueryTool(queryTool, pgBrowser, alertify, '', [{id: 'parent'}], 'title');
|
showQueryTool(queryTool, pgBrowser, alertify, '', [{id: 'parent'}], transId);
|
||||||
expect(queryTool.create_transaction).not.toHaveBeenCalled();
|
expect(queryTool.launch_grid).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('no alert is displayed', () => {
|
it('no alert is displayed', () => {
|
||||||
@ -94,32 +95,26 @@ describe('#showQueryTool', () => {
|
|||||||
context('current node is underneath a server', () => {
|
context('current node is underneath a server', () => {
|
||||||
context('current node is not underneath a database', () => {
|
context('current node is not underneath a database', () => {
|
||||||
it('creates a transaction', () => {
|
it('creates a transaction', () => {
|
||||||
showQueryTool(queryTool, pgBrowser, alertify, 'http://someurl', [{id: 'server1'}]);
|
showQueryTool(queryTool, pgBrowser, alertify, 'http://someurl', [{id: 'server1'}], transId);
|
||||||
expect(queryTool.create_transaction).toHaveBeenCalledWith(
|
expect(queryTool.launch_grid).toHaveBeenCalledWith(
|
||||||
'/initialize/query_tool/1/2',
|
98765432,
|
||||||
null,
|
'/panel/98765432?is_query_tool=true&sgid=1&sid=2&server_type=pg',
|
||||||
'true',
|
true,
|
||||||
'pg',
|
|
||||||
'http://someurl',
|
|
||||||
'otherdblabel/someuser@server1',
|
'otherdblabel/someuser@server1',
|
||||||
'',
|
'http://someurl'
|
||||||
false
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
context('current node is underneath a database', () => {
|
context('current node is underneath a database', () => {
|
||||||
it('creates a transaction', () => {
|
it('creates a transaction', () => {
|
||||||
showQueryTool(queryTool, pgBrowser, alertify, 'http://someurl', [{id: 'database1'}], 'title');
|
showQueryTool(queryTool, pgBrowser, alertify, 'http://someurl', [{id: 'database1'}], transId);
|
||||||
expect(queryTool.create_transaction).toHaveBeenCalledWith(
|
expect(queryTool.launch_grid).toHaveBeenCalledWith(
|
||||||
'/initialize/query_tool/1/2/3',
|
98765432,
|
||||||
null,
|
'/panel/98765432?is_query_tool=true&sgid=1&sid=2&server_type=pg&did=3',
|
||||||
'true',
|
true,
|
||||||
'pg',
|
|
||||||
'http://someurl',
|
|
||||||
'database1/someuser@server1',
|
'database1/someuser@server1',
|
||||||
'',
|
'http://someurl'
|
||||||
false
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -18,5 +18,6 @@ define(function () {
|
|||||||
'datagrid.initialize_query_tool': '/initialize/query_tool/<int:sgid>/<int:sid>',
|
'datagrid.initialize_query_tool': '/initialize/query_tool/<int:sgid>/<int:sid>',
|
||||||
'datagrid.initialize_query_tool_with_did': '/initialize/query_tool/<int:sgid>/<int:sid>/<int:did>',
|
'datagrid.initialize_query_tool_with_did': '/initialize/query_tool/<int:sgid>/<int:sid>/<int:did>',
|
||||||
'restore.create_job': '/restore/job/<int:sid>',
|
'restore.create_job': '/restore/job/<int:sid>',
|
||||||
|
'datagrid.panel': '/panel/<int:trans_id>',
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
import { getEpoch, getGCD, getMod, quote_ident, parseFuncParams } from 'sources/utils';
|
import { getEpoch, getGCD, getMod, quote_ident, parseFuncParams, getRandomInt } from 'sources/utils';
|
||||||
|
|
||||||
describe('getEpoch', function () {
|
describe('getEpoch', function () {
|
||||||
it('should return non zero', function () {
|
it('should return non zero', function () {
|
||||||
@ -135,3 +135,10 @@ describe('parseFuncParams', function () {
|
|||||||
expect(parseFuncParams(funcLabel)).toEqual(expectedObj);
|
expect(parseFuncParams(funcLabel)).toEqual(expectedObj);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('getRandomInt', function () {
|
||||||
|
it('is between', function () {
|
||||||
|
let id = getRandomInt(1, 9999999);
|
||||||
|
expect(1 <= id && id <= 9999999).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -36,61 +36,5 @@ define(['sources/sqleditor_utils'],
|
|||||||
expect(SqlEditorUtils.calcFontSize(2)).toEqual('2em');
|
expect(SqlEditorUtils.calcFontSize(2)).toEqual('2em');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Remove the slashes', function () {
|
|
||||||
it('it will remove the slashes', function () {
|
|
||||||
expect(
|
|
||||||
SqlEditorUtils.removeSlashInTheString('/')
|
|
||||||
).toEqual({
|
|
||||||
'slashLocations': '0',
|
|
||||||
'title': '',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('it will remove if slashes are present', function () {
|
|
||||||
expect(
|
|
||||||
SqlEditorUtils.removeSlashInTheString('my/test')
|
|
||||||
).toEqual({
|
|
||||||
'slashLocations': '2',
|
|
||||||
'title': 'mytest',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('it will remove all the slashes are present', function () {
|
|
||||||
expect(
|
|
||||||
SqlEditorUtils.removeSlashInTheString('my/test/value')
|
|
||||||
).toEqual({
|
|
||||||
'slashLocations': '2,7',
|
|
||||||
'title': 'mytestvalue',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('it will remove all the slashes are present', function () {
|
|
||||||
expect(
|
|
||||||
SqlEditorUtils.removeSlashInTheString('a/bb/ccc/dddd/eeeee')
|
|
||||||
).toEqual({
|
|
||||||
'slashLocations': '1,4,8,13',
|
|
||||||
'title': 'abbcccddddeeeee',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('it will not remove if slash is not present', function () {
|
|
||||||
expect(
|
|
||||||
SqlEditorUtils.removeSlashInTheString('mytest')
|
|
||||||
).toEqual({
|
|
||||||
'slashLocations': '',
|
|
||||||
'title': 'mytest',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('it will not remove if value is not present', function () {
|
|
||||||
expect(
|
|
||||||
SqlEditorUtils.removeSlashInTheString('')
|
|
||||||
).toEqual({
|
|
||||||
'slashLocations': '',
|
|
||||||
'title': '',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -3519,9 +3519,9 @@ eslint-scope@^4.0.2, eslint-scope@^4.0.3:
|
|||||||
estraverse "^4.1.1"
|
estraverse "^4.1.1"
|
||||||
|
|
||||||
eslint-utils@^1.3.1:
|
eslint-utils@^1.3.1:
|
||||||
version "1.4.0"
|
version "1.4.2"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.0.tgz#e2c3c8dba768425f897cf0f9e51fe2e241485d4c"
|
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.2.tgz#166a5180ef6ab7eb462f162fd0e6f2463d7309ab"
|
||||||
integrity sha512-7ehnzPaP5IIEh1r1tkjuIrxqhNkzUJa9z3R92tLJdZIVdWaczEhr3EbhGtsMrVxi1KeR8qA7Off6SWc5WNQqyQ==
|
integrity sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==
|
||||||
dependencies:
|
dependencies:
|
||||||
eslint-visitor-keys "^1.0.0"
|
eslint-visitor-keys "^1.0.0"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user