Properly display messages from the server in the query tool. Fixes #1523

This commit is contained in:
Murtuza Zabuawala 2016-08-18 17:08:40 +01:00 committed by Dave Page
parent 2b1b60bc2b
commit d6391c7e9b
4 changed files with 82 additions and 63 deletions

View File

@ -406,8 +406,10 @@ def poll(trans_id):
trans_id: unique transaction id trans_id: unique transaction id
""" """
col_info = None col_info = None
result = None
primary_keys = None primary_keys = None
rows_affected = 0 rows_affected = 0
additional_result = []
# Check the transaction and connection status # Check the transaction and connection status
status, error_msg, conn, trans_obj, session_obj = check_transaction_status(trans_id) status, error_msg, conn, trans_obj, session_obj = check_transaction_status(trans_id)
@ -430,6 +432,10 @@ def poll(trans_id):
status = 'Cancel' status = 'Cancel'
else: else:
status = 'Busy' status = 'Busy'
messages = conn.messages()
if messages and len(messages) > 0:
result = ''.join(messages)
else: else:
status = 'NotConnected' status = 'NotConnected'
result = error_msg result = error_msg
@ -450,20 +456,25 @@ def poll(trans_id):
# restore it and update the session variable. # restore it and update the session variable.
session_obj['columns_info'] = columns session_obj['columns_info'] = columns
update_session_grid_transaction(trans_id, session_obj) update_session_grid_transaction(trans_id, session_obj)
else:
if result is None:
result = conn.status_message()
additional_result = conn.messages()
"""
Procedure/Function output may comes in the form of Notices from the
database server, so we need to append those outputs with the
original result.
"""
if isinstance(additional_result, list) \
and len(additional_result) > 0:
result = "{0} {1}".format(additional_result[-1], result)
rows_affected = conn.rows_affected() """
Procedure/Function output may comes in the form of Notices from the
database server, so we need to append those outputs with the
original result.
"""
if status == 'Success' and result is None:
result = conn.status_message()
messages = conn.messages()
if messages:
additional_result = ''.join(messages)
else:
additional_result = ''
if result != 'SELECT 1' and result is not None:
result = additional_result + result
else:
result = additional_result
rows_affected = conn.rows_affected()
return make_json_response( return make_json_response(
data={ data={

View File

@ -160,6 +160,9 @@
font-family: monospace; font-family: monospace;
padding-top: 5px; padding-top: 5px;
padding-left: 10px; padding-left: 10px;
overflow: auto;
height: 100%;
font-size: 0.925em;
} }
.limit-enabled { .limit-enabled {

View File

@ -1291,7 +1291,13 @@ define(
else { else {
// Show message in message and history tab in case of query tool // Show message in message and history tab in case of query tool
self.total_time = self.get_query_run_time(self.query_start_time, self.query_end_time); self.total_time = self.get_query_run_time(self.query_start_time, self.query_end_time);
self.update_msg_history(true, res.data.result); var msg = S('{{ _('Query returned successfully in %s.') }}').sprintf(self.total_time).value();
res.data.result += "\n\n" + msg;
self.update_msg_history(true, res.data.result, false);
// Display the notifier if the timeout is set to >= 0
if (self.info_notifier_timeout >= 0) {
alertify.success(msg, self.info_notifier_timeout);
}
} }
// Enable/Disable query tool button only if is_query_tool is true. // Enable/Disable query tool button only if is_query_tool is true.
@ -1305,6 +1311,9 @@ define(
// If status is Busy then poll the result by recursive call to the poll function // If status is Busy then poll the result by recursive call to the poll function
self._poll(); self._poll();
is_query_running = true; is_query_running = true;
if (res.data.result) {
self.update_msg_history(res.data.status, res.data.result, false);
}
} }
else if (res.data.status === 'NotConnected') { else if (res.data.status === 'NotConnected') {
@ -1313,10 +1322,10 @@ define(
self.disable_tool_buttons(false); self.disable_tool_buttons(false);
$("#btn-cancel-query").prop('disabled', true); $("#btn-cancel-query").prop('disabled', true);
} }
self.update_msg_history(false, res.data.result); self.update_msg_history(false, res.data.result, true);
} }
else if (res.data.status === 'Cancel') { else if (res.data.status === 'Cancel') {
self.update_msg_history(false, "Execution Cancelled!") self.update_msg_history(false, "Execution Cancelled!", true)
} }
}, },
error: function(e) { error: function(e) {
@ -1687,35 +1696,43 @@ define(
// This function is used to raise appropriate message. // This function is used to raise appropriate message.
update_msg_history: function(status, msg, clear_grid) { update_msg_history: function(status, msg, clear_grid) {
var self = this; var self = this;
if (clear_grid === undefined) if (clear_grid === undefined)
clear_grid = true; clear_grid = true;
self.trigger('pgadmin-sqleditor:loading-icon:hide');
$("#btn-flash").prop('disabled', false);
$('.sql-editor-message').text(msg);
self.gridView.messages_panel.focus(); self.gridView.messages_panel.focus();
if (self.is_query_tool && clear_grid) { if (self.is_query_tool) {
// Delete grid and paginator if (clear_grid) {
if (self.gridView.grid) { // Delete grid and paginator
self.gridView.grid.remove(); if (self.gridView.grid) {
self.gridView.grid.remove();
}
// Misc cleaning
self.columns = undefined; self.columns = undefined;
self.collection = undefined; self.collection = undefined;
if (self.gridView.paginator)
self.gridView.paginator.remove();
$('.sql-editor-message').text(msg);
} else {
$('.sql-editor-message').append(msg);
} }
if (self.gridView.paginator)
self.gridView.paginator.remove();
} }
// Scroll automatically when msgs appends to element
setTimeout(function(){
$(".sql-editor-message").scrollTop($(".sql-editor-message")[0].scrollHeight);;
}, 10);
self.gridView.history_collection.add( if(status != 'Busy') {
{'status' : status, 'start_time': self.query_start_time.toString(), $("#btn-flash").prop('disabled', false);
'query': self.query, 'row_affected': self.rows_affected, self.trigger('pgadmin-sqleditor:loading-icon:hide');
'total_time': self.total_time, 'message':msg self.gridView.history_collection.add({
}); 'status' : status, 'start_time': self.query_start_time.toString(),
'query': self.query, 'row_affected': self.rows_affected,
self.gridView.history_collection.sort(); 'total_time': self.total_time, 'message':msg
});
self.gridView.history_collection.sort();
}
}, },
// This function will return the total query execution Time. // This function will return the total query execution Time.
@ -2140,10 +2157,12 @@ define(
var self = this; var self = this;
// Start execution of the query. // Start execution of the query.
if (self.is_query_tool) if (self.is_query_tool) {
$('.sql-editor-message').html('');
self._execute(); self._execute();
else } else {
self._execute_data_query(); self._execute_data_query();
}
}, },
// This function will show the filter in the text area. // This function will show the filter in the text area.

View File

@ -178,6 +178,7 @@ class Connection(BaseConnection):
self.__backend_pid = None self.__backend_pid = None
self.execution_aborted = False self.execution_aborted = False
self.row_count = 0 self.row_count = 0
self.__notices = None
super(Connection, self).__init__() super(Connection, self).__init__()
@ -639,6 +640,7 @@ Attempt to reconnect it failed with the error:
) )
try: try:
self.__notices = []
self.execution_aborted = False self.execution_aborted = False
cur.execute(query, params) cur.execute(query, params)
res = self._wait_timeout(cur.connection, ASYNC_WAIT_TIMEOUT) res = self._wait_timeout(cur.connection, ASYNC_WAIT_TIMEOUT)
@ -904,31 +906,9 @@ Failed to reset the connection to the server due to following error:
if state == psycopg2.extensions.POLL_OK: if state == psycopg2.extensions.POLL_OK:
return self.ASYNC_OK return self.ASYNC_OK
elif state == psycopg2.extensions.POLL_WRITE: elif state == psycopg2.extensions.POLL_WRITE:
# Wait for the given time and then check the return status return self.ASYNC_WRITE_TIMEOUT
# If three empty lists are returned then the time-out is reached.
timeout_status = select.select([], [conn.fileno()], [], time)
if timeout_status == ([], [], []):
return self.ASYNC_WRITE_TIMEOUT
# poll again to check the state if it is still POLL_WRITE
# then return ASYNC_WRITE_TIMEOUT else return ASYNC_OK.
state = conn.poll()
if state == psycopg2.extensions.POLL_WRITE:
return self.ASYNC_WRITE_TIMEOUT
return self.ASYNC_OK
elif state == psycopg2.extensions.POLL_READ: elif state == psycopg2.extensions.POLL_READ:
# Wait for the given time and then check the return status return self.ASYNC_READ_TIMEOUT
# If three empty lists are returned then the time-out is reached.
timeout_status = select.select([conn.fileno()], [], [], time)
if timeout_status == ([], [], []):
return self.ASYNC_READ_TIMEOUT
# poll again to check the state if it is still POLL_READ
# then return ASYNC_READ_TIMEOUT else return ASYNC_OK.
state = conn.poll()
if state == psycopg2.extensions.POLL_READ:
return self.ASYNC_READ_TIMEOUT
return self.ASYNC_OK
else: else:
raise psycopg2.OperationalError( raise psycopg2.OperationalError(
"poll() returned %s from _wait_timeout function" % state "poll() returned %s from _wait_timeout function" % state
@ -965,6 +945,10 @@ Failed to reset the connection to the server due to following error:
errmsg = self._formatted_exception_msg(pe, formatted_exception_msg) errmsg = self._formatted_exception_msg(pe, formatted_exception_msg)
return False, errmsg, None return False, errmsg, None
if self.conn.notices and self.__notices is not None:
while self.conn.notices:
self.__notices.append(self.conn.notices.pop(0)[:])
colinfo = None colinfo = None
result = None result = None
self.row_count = 0 self.row_count = 0
@ -996,7 +980,6 @@ Failed to reset the connection to the server due to following error:
result.append(dict(row)) result.append(dict(row))
except psycopg2.ProgrammingError: except psycopg2.ProgrammingError:
result = None result = None
return status, result, colinfo return status, result, colinfo
def status_message(self): def status_message(self):
@ -1094,7 +1077,10 @@ Failed to reset the connection to the server due to following error:
""" """
Returns the list of the messages/notices send from the database server. Returns the list of the messages/notices send from the database server.
""" """
return self.conn.notices if self.conn else [] resp = []
while self.__notices:
resp.append(self.__notices.pop(0))
return resp
def _formatted_exception_msg(self, exception_obj, formatted_msg): def _formatted_exception_msg(self, exception_obj, formatted_msg):
""" """