mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Fix logic around validation and highlighting of Sort/Filter in the Query Tool. Fixes #3607
This commit is contained in:
parent
38ddea038a
commit
0ec3224212
@ -19,5 +19,6 @@ Bug fixes
|
|||||||
|
|
||||||
| `Bug #3576 <https://redmine.postgresql.org/issues/3576>`_ - Ensure queries are no longer executed when dashboards are closed.
|
| `Bug #3576 <https://redmine.postgresql.org/issues/3576>`_ - Ensure queries are no longer executed when dashboards are closed.
|
||||||
| `Bug #3596 <https://redmine.postgresql.org/issues/3596>`_ - Fix support for the CLOB datatype in EPAS.
|
| `Bug #3596 <https://redmine.postgresql.org/issues/3596>`_ - Fix support for the CLOB datatype in EPAS.
|
||||||
|
| `Bug #3607 <https://redmine.postgresql.org/issues/3607>`_ - Fix logic around validation and highlighting of Sort/Filter in the Query Tool.
|
||||||
| `Bug #3630 <https://redmine.postgresql.org/issues/3630>`_ - Ensure auto-complete works for objects in schemas other than public and pg_catalog.
|
| `Bug #3630 <https://redmine.postgresql.org/issues/3630>`_ - Ensure auto-complete works for objects in schemas other than public and pg_catalog.
|
||||||
|
|
||||||
|
@ -215,11 +215,15 @@ let FilterDialog = {
|
|||||||
'trans_id': handler.transId,
|
'trans_id': handler.transId,
|
||||||
}),
|
}),
|
||||||
filterCollectionModel
|
filterCollectionModel
|
||||||
).then(function () {
|
).then(function (result) {
|
||||||
// Hide Progress ...
|
// Hide Progress ...
|
||||||
$(
|
$(
|
||||||
self.showFilterProgress[0]
|
self.showFilterProgress[0]
|
||||||
).addClass('hidden');
|
).addClass('hidden');
|
||||||
|
|
||||||
|
let response = result.data.data;
|
||||||
|
|
||||||
|
if (response.status) {
|
||||||
setTimeout(
|
setTimeout(
|
||||||
function() {
|
function() {
|
||||||
self.close(); // Close the dialog now
|
self.close(); // Close the dialog now
|
||||||
@ -227,6 +231,12 @@ let FilterDialog = {
|
|||||||
queryToolActions.executeQuery(handler);
|
queryToolActions.executeQuery(handler);
|
||||||
}, 10
|
}, 10
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
Alertify.alert(
|
||||||
|
gettext('Validation Error'),
|
||||||
|
response.result
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}).catch(function (error) {
|
}).catch(function (error) {
|
||||||
// Hide Progress ...
|
// Hide Progress ...
|
||||||
|
@ -302,6 +302,8 @@ define('pgadmin.datagrid', [
|
|||||||
);
|
);
|
||||||
|
|
||||||
this.setContent($content.get(0));
|
this.setContent($content.get(0));
|
||||||
|
// Disable OK button
|
||||||
|
that.__internal.buttons[0].element.disabled = true;
|
||||||
|
|
||||||
// Apply CodeMirror to filter text area.
|
// Apply CodeMirror to filter text area.
|
||||||
this.filter_obj = CodeMirror.fromTextArea($sql_filter.get(0), {
|
this.filter_obj = CodeMirror.fromTextArea($sql_filter.get(0), {
|
||||||
@ -324,6 +326,14 @@ define('pgadmin.datagrid', [
|
|||||||
that.filter_obj.refresh();
|
that.filter_obj.refresh();
|
||||||
that.filter_obj.focus();
|
that.filter_obj.focus();
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
|
that.filter_obj.on('change', function() {
|
||||||
|
if (that.filter_obj.getValue() !== '') {
|
||||||
|
that.__internal.buttons[0].element.disabled = false;
|
||||||
|
} else {
|
||||||
|
that.__internal.buttons[0].element.disabled = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
callback: function(closeEvent) {
|
callback: function(closeEvent) {
|
||||||
@ -331,6 +341,7 @@ define('pgadmin.datagrid', [
|
|||||||
if (closeEvent.button.text == gettext('OK')) {
|
if (closeEvent.button.text == gettext('OK')) {
|
||||||
var sql = this.filter_obj.getValue();
|
var sql = this.filter_obj.getValue();
|
||||||
var that = this;
|
var that = this;
|
||||||
|
closeEvent.cancel = true; // Do not close dialog
|
||||||
|
|
||||||
// Make ajax call to include the filter by selection
|
// Make ajax call to include the filter by selection
|
||||||
$.ajax({
|
$.ajax({
|
||||||
@ -344,6 +355,7 @@ define('pgadmin.datagrid', [
|
|||||||
if (res.data.status) {
|
if (res.data.status) {
|
||||||
// Initialize the data grid.
|
// Initialize the data grid.
|
||||||
self.create_transaction(that.baseUrl, null, 'false', parentData.server.server_type, '', grid_title, sql, false);
|
self.create_transaction(that.baseUrl, null, 'false', parentData.server.server_type, '', grid_title, sql, false);
|
||||||
|
that.close(); // Close the dialog
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
alertify.alert(
|
alertify.alert(
|
||||||
|
@ -236,12 +236,13 @@ def start_view_data(trans_id):
|
|||||||
trans_obj is not None and session_obj is not None:
|
trans_obj is not None and session_obj is not None:
|
||||||
# set fetched row count to 0 as we are executing query again.
|
# set fetched row count to 0 as we are executing query again.
|
||||||
trans_obj.update_fetched_row_cnt(0)
|
trans_obj.update_fetched_row_cnt(0)
|
||||||
session_obj['command_obj'] = pickle.dumps(trans_obj, -1)
|
|
||||||
|
|
||||||
# Fetch the sql and primary_keys from the object
|
# Fetch the sql and primary_keys from the object
|
||||||
sql = trans_obj.get_sql(default_conn)
|
sql = trans_obj.get_sql(default_conn)
|
||||||
pk_names, primary_keys = trans_obj.get_primary_keys(default_conn)
|
pk_names, primary_keys = trans_obj.get_primary_keys(default_conn)
|
||||||
|
|
||||||
|
session_obj['command_obj'] = pickle.dumps(trans_obj, -1)
|
||||||
|
|
||||||
has_oids = False
|
has_oids = False
|
||||||
if trans_obj.object_type == 'table':
|
if trans_obj.object_type == 'table':
|
||||||
# Fetch OIDs status
|
# Fetch OIDs status
|
||||||
|
@ -166,6 +166,7 @@ class SQLFilter(object):
|
|||||||
self.obj_id = kwargs['obj_id']
|
self.obj_id = kwargs['obj_id']
|
||||||
self.__row_filter = kwargs.get('sql_filter', None)
|
self.__row_filter = kwargs.get('sql_filter', None)
|
||||||
self.__dara_sorting = kwargs.get('data_sorting', None)
|
self.__dara_sorting = kwargs.get('data_sorting', None)
|
||||||
|
self.__set_sorting_from_filter_dialog = False
|
||||||
|
|
||||||
manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(self.sid)
|
manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(self.sid)
|
||||||
conn = manager.connection(did=self.did)
|
conn = manager.connection(did=self.did)
|
||||||
@ -222,12 +223,17 @@ class SQLFilter(object):
|
|||||||
return self.__dara_sorting
|
return self.__dara_sorting
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def set_data_sorting(self, data_filter):
|
def set_data_sorting(self, data_filter, set_from_filter_dialog=False):
|
||||||
"""
|
"""
|
||||||
This function validates the filter and set the
|
This function validates the filter and set the
|
||||||
given filter to member variable.
|
given filter to member variable.
|
||||||
"""
|
"""
|
||||||
self.__dara_sorting = data_filter['data_sorting']
|
self.__dara_sorting = data_filter['data_sorting']
|
||||||
|
self.__set_sorting_from_filter_dialog = set_from_filter_dialog
|
||||||
|
|
||||||
|
def is_sorting_set_from_filter_dialog(self):
|
||||||
|
"""This function return whether sorting is set from filter dialog"""
|
||||||
|
return self.__set_sorting_from_filter_dialog
|
||||||
|
|
||||||
def is_filter_applied(self):
|
def is_filter_applied(self):
|
||||||
"""
|
"""
|
||||||
@ -276,10 +282,9 @@ class SQLFilter(object):
|
|||||||
status = True
|
status = True
|
||||||
result = None
|
result = None
|
||||||
|
|
||||||
if row_filter is None or row_filter == '':
|
if row_filter is not None and row_filter != '':
|
||||||
return False, gettext('Filter string is empty.')
|
manager = \
|
||||||
|
get_driver(PG_DEFAULT_DRIVER).connection_manager(self.sid)
|
||||||
manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(self.sid)
|
|
||||||
conn = manager.connection(did=self.did)
|
conn = manager.connection(did=self.did)
|
||||||
|
|
||||||
if conn.connected():
|
if conn.connected():
|
||||||
@ -466,23 +471,35 @@ class TableCommand(GridCommand):
|
|||||||
sql_filter = self.get_filter()
|
sql_filter = self.get_filter()
|
||||||
data_sorting = self.get_data_sorting()
|
data_sorting = self.get_data_sorting()
|
||||||
|
|
||||||
|
# If data sorting is none and not reset from the filter dialog then
|
||||||
|
# set the data sorting in following conditions:
|
||||||
|
# 1. When command type is VIEW_FIRST_100_ROWS or VIEW_LAST_100_ROWS.
|
||||||
|
# 2. When command type is VIEW_ALL_ROWS and limit is greater than 0
|
||||||
|
|
||||||
|
if data_sorting is None and \
|
||||||
|
not self.is_sorting_set_from_filter_dialog() \
|
||||||
|
and (self.cmd_type in (VIEW_FIRST_100_ROWS, VIEW_LAST_100_ROWS) or
|
||||||
|
(self.cmd_type == VIEW_ALL_ROWS and self.limit > 0)):
|
||||||
|
sorting = {'data_sorting': []}
|
||||||
|
for pk in primary_keys:
|
||||||
|
sorting['data_sorting'].append(
|
||||||
|
{'name': pk, 'order': self.get_pk_order()})
|
||||||
|
self.set_data_sorting(sorting)
|
||||||
|
data_sorting = self.get_data_sorting()
|
||||||
|
|
||||||
if sql_filter is None:
|
if sql_filter is None:
|
||||||
sql = render_template(
|
sql = render_template(
|
||||||
"/".join([self.sql_path, 'objectquery.sql']),
|
"/".join([self.sql_path, 'objectquery.sql']),
|
||||||
object_name=self.object_name,
|
object_name=self.object_name,
|
||||||
nsp_name=self.nsp_name, pk_names=pk_names,
|
nsp_name=self.nsp_name, limit=self.limit, has_oids=has_oids,
|
||||||
cmd_type=self.cmd_type, limit=self.limit,
|
|
||||||
primary_keys=primary_keys, has_oids=has_oids,
|
|
||||||
data_sorting=data_sorting
|
data_sorting=data_sorting
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
sql = render_template(
|
sql = render_template(
|
||||||
"/".join([self.sql_path, 'objectquery.sql']),
|
"/".join([self.sql_path, 'objectquery.sql']),
|
||||||
object_name=self.object_name,
|
object_name=self.object_name,
|
||||||
nsp_name=self.nsp_name, pk_names=pk_names,
|
nsp_name=self.nsp_name, limit=self.limit, has_oids=has_oids,
|
||||||
cmd_type=self.cmd_type, sql_filter=sql_filter,
|
sql_filter=sql_filter, data_sorting=data_sorting
|
||||||
limit=self.limit, primary_keys=primary_keys,
|
|
||||||
has_oids=has_oids, data_sorting=data_sorting
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return sql
|
return sql
|
||||||
@ -563,12 +580,6 @@ class TableCommand(GridCommand):
|
|||||||
|
|
||||||
for row in result['rows']:
|
for row in result['rows']:
|
||||||
all_columns.append(row['attname'])
|
all_columns.append(row['attname'])
|
||||||
all_sorted_columns.append(
|
|
||||||
{
|
|
||||||
'name': row['attname'],
|
|
||||||
'order': self.get_pk_order()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
# Fetch the rest of the column names
|
# Fetch the rest of the column names
|
||||||
query = render_template(
|
query = render_template(
|
||||||
@ -919,15 +930,13 @@ class ViewCommand(GridCommand):
|
|||||||
if sql_filter is None:
|
if sql_filter is None:
|
||||||
sql = render_template(
|
sql = render_template(
|
||||||
"/".join([self.sql_path, 'objectquery.sql']),
|
"/".join([self.sql_path, 'objectquery.sql']),
|
||||||
object_name=self.object_name,
|
object_name=self.object_name, nsp_name=self.nsp_name,
|
||||||
nsp_name=self.nsp_name, cmd_type=self.cmd_type,
|
|
||||||
limit=self.limit, data_sorting=data_sorting
|
limit=self.limit, data_sorting=data_sorting
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
sql = render_template(
|
sql = render_template(
|
||||||
"/".join([self.sql_path, 'objectquery.sql']),
|
"/".join([self.sql_path, 'objectquery.sql']),
|
||||||
object_name=self.object_name,
|
object_name=self.object_name, nsp_name=self.nsp_name,
|
||||||
nsp_name=self.nsp_name, cmd_type=self.cmd_type,
|
|
||||||
sql_filter=sql_filter, limit=self.limit,
|
sql_filter=sql_filter, limit=self.limit,
|
||||||
data_sorting=data_sorting
|
data_sorting=data_sorting
|
||||||
)
|
)
|
||||||
@ -982,15 +991,13 @@ class ForeignTableCommand(GridCommand):
|
|||||||
if sql_filter is None:
|
if sql_filter is None:
|
||||||
sql = render_template(
|
sql = render_template(
|
||||||
"/".join([self.sql_path, 'objectquery.sql']),
|
"/".join([self.sql_path, 'objectquery.sql']),
|
||||||
object_name=self.object_name,
|
object_name=self.object_name, nsp_name=self.nsp_name,
|
||||||
nsp_name=self.nsp_name, cmd_type=self.cmd_type,
|
|
||||||
limit=self.limit, data_sorting=data_sorting
|
limit=self.limit, data_sorting=data_sorting
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
sql = render_template(
|
sql = render_template(
|
||||||
"/".join([self.sql_path, 'objectquery.sql']),
|
"/".join([self.sql_path, 'objectquery.sql']),
|
||||||
object_name=self.object_name,
|
object_name=self.object_name, nsp_name=self.nsp_name,
|
||||||
nsp_name=self.nsp_name, cmd_type=self.cmd_type,
|
|
||||||
sql_filter=sql_filter, limit=self.limit,
|
sql_filter=sql_filter, limit=self.limit,
|
||||||
data_sorting=data_sorting
|
data_sorting=data_sorting
|
||||||
)
|
)
|
||||||
@ -1035,15 +1042,13 @@ class CatalogCommand(GridCommand):
|
|||||||
if sql_filter is None:
|
if sql_filter is None:
|
||||||
sql = render_template(
|
sql = render_template(
|
||||||
"/".join([self.sql_path, 'objectquery.sql']),
|
"/".join([self.sql_path, 'objectquery.sql']),
|
||||||
object_name=self.object_name,
|
object_name=self.object_name, nsp_name=self.nsp_name,
|
||||||
nsp_name=self.nsp_name, cmd_type=self.cmd_type,
|
|
||||||
limit=self.limit, data_sorting=data_sorting
|
limit=self.limit, data_sorting=data_sorting
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
sql = render_template(
|
sql = render_template(
|
||||||
"/".join([self.sql_path, 'objectquery.sql']),
|
"/".join([self.sql_path, 'objectquery.sql']),
|
||||||
object_name=self.object_name,
|
object_name=self.object_name, nsp_name=self.nsp_name,
|
||||||
nsp_name=self.nsp_name, cmd_type=self.cmd_type,
|
|
||||||
sql_filter=sql_filter, limit=self.limit,
|
sql_filter=sql_filter, limit=self.limit,
|
||||||
data_sorting=data_sorting
|
data_sorting=data_sorting
|
||||||
)
|
)
|
||||||
|
@ -7,9 +7,6 @@ WHERE {{ sql_filter }}
|
|||||||
ORDER BY {% for obj in data_sorting %}
|
ORDER BY {% for obj in data_sorting %}
|
||||||
{{ conn|qtIdent(obj.name) }} {{ obj.order|upper }}{% if not loop.last %}, {% else %} {% endif %}
|
{{ conn|qtIdent(obj.name) }} {{ obj.order|upper }}{% if not loop.last %}, {% else %} {% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% elif primary_keys %}
|
|
||||||
ORDER BY {% for p in primary_keys %}{{conn|qtIdent(p)}}{% if cmd_type == 1 or cmd_type == 3 %} ASC{% elif cmd_type == 2 %} DESC{% endif %}
|
|
||||||
{% if not loop.last %}, {% else %} {% endif %}{% endfor %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if limit > 0 %}
|
{% if limit > 0 %}
|
||||||
LIMIT {{ limit }}
|
LIMIT {{ limit }}
|
||||||
|
@ -86,8 +86,9 @@ class FilterDialog(object):
|
|||||||
|
|
||||||
if status and conn is not None and \
|
if status and conn is not None and \
|
||||||
trans_obj is not None and session_obj is not None:
|
trans_obj is not None and session_obj is not None:
|
||||||
trans_obj.set_data_sorting(data)
|
trans_obj.set_data_sorting(data, True)
|
||||||
trans_obj.set_filter(data.get('sql'))
|
status, res = trans_obj.set_filter(data.get('sql'))
|
||||||
|
if status:
|
||||||
# As we changed the transaction object we need to
|
# As we changed the transaction object we need to
|
||||||
# restore it and update the session variable.
|
# restore it and update the session variable.
|
||||||
session_obj['command_obj'] = pickle.dumps(trans_obj, -1)
|
session_obj['command_obj'] = pickle.dumps(trans_obj, -1)
|
||||||
|
Loading…
Reference in New Issue
Block a user