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

pull/3/head
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,18 +456,23 @@ 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 Procedure/Function output may comes in the form of Notices from the
database server, so we need to append those outputs with the database server, so we need to append those outputs with the
original result. original result.
""" """
if isinstance(additional_result, list) \ if status == 'Success' and result is None:
and len(additional_result) > 0: result = conn.status_message()
result = "{0} {1}".format(additional_result[-1], result) 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() rows_affected = conn.rows_affected()

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) {
if (clear_grid) {
// Delete grid and paginator // Delete grid and paginator
if (self.gridView.grid) { if (self.gridView.grid) {
self.gridView.grid.remove(); self.gridView.grid.remove();
}
// Misc cleaning
self.columns = undefined; self.columns = undefined;
self.collection = undefined; self.collection = undefined;
}
if (self.gridView.paginator) if (self.gridView.paginator)
self.gridView.paginator.remove(); self.gridView.paginator.remove();
$('.sql-editor-message').text(msg);
} else {
$('.sql-editor-message').append(msg);
} }
}
// 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);
self.trigger('pgadmin-sqleditor:loading-icon:hide');
self.gridView.history_collection.add({
'status' : status, 'start_time': self.query_start_time.toString(),
'query': self.query, 'row_affected': self.rows_affected, 'query': self.query, 'row_affected': self.rows_affected,
'total_time': self.total_time, 'message':msg 'total_time': self.total_time, 'message':msg
}); });
self.gridView.history_collection.sort(); 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
# 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 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
# 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 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):
""" """