mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Add support for LISTEN/NOTIFY in the query tool. Fixes #3204
This commit is contained in:
@@ -543,10 +543,12 @@ def poll(trans_id):
|
||||
# There may be additional messages even if result is present
|
||||
# eg: Function can provide result as well as RAISE messages
|
||||
additional_messages = None
|
||||
notifies = None
|
||||
if status == 'Success':
|
||||
messages = conn.messages()
|
||||
if messages:
|
||||
additional_messages = ''.join(messages)
|
||||
notifies = conn.get_notifies()
|
||||
|
||||
# Procedure/Function output may comes in the form of Notices from the
|
||||
# database server, so we need to append those outputs with the
|
||||
@@ -564,6 +566,7 @@ def poll(trans_id):
|
||||
'rows_fetched_from': rows_fetched_from,
|
||||
'rows_fetched_to': rows_fetched_to,
|
||||
'additional_messages': additional_messages,
|
||||
'notifies': notifies,
|
||||
'has_more_rows': has_more_rows,
|
||||
'colinfo': columns_info,
|
||||
'primary_keys': primary_keys,
|
||||
@@ -1476,12 +1479,18 @@ def query_tool_status(trans_id):
|
||||
|
||||
if conn and trans_obj and session_obj:
|
||||
status = conn.transaction_status()
|
||||
|
||||
# Check for the asynchronous notifies statements.
|
||||
conn.check_notifies(True)
|
||||
notifies = conn.get_notifies()
|
||||
|
||||
return make_json_response(
|
||||
data={
|
||||
'status': status,
|
||||
'message': gettext(
|
||||
CONNECTION_STATUS_MESSAGE_MAPPING.get(status)
|
||||
)
|
||||
CONNECTION_STATUS_MESSAGE_MAPPING.get(status),
|
||||
),
|
||||
'notifies': notifies
|
||||
}
|
||||
)
|
||||
else:
|
||||
|
@@ -20,6 +20,7 @@ define('tools.querytool', [
|
||||
'react', 'react-dom',
|
||||
'sources/keyboard_shortcuts',
|
||||
'sources/sqleditor/query_tool_actions',
|
||||
'sources/sqleditor/query_tool_notifications',
|
||||
'pgadmin.datagrid',
|
||||
'sources/modify_animation',
|
||||
'sources/sqleditor/calculate_query_run_time',
|
||||
@@ -36,8 +37,8 @@ define('tools.querytool', [
|
||||
pgExplain, GridSelector, ActiveCellCapture, clipboard, copyData, RangeSelectionHelper, handleQueryOutputKeyboardEvent,
|
||||
XCellSelectionModel, setStagedRows, SqlEditorUtils, ExecuteQuery, httpErrorHandler, FilterHandler,
|
||||
HistoryBundle, queryHistory, React, ReactDOM,
|
||||
keyboardShortcuts, queryToolActions, Datagrid, modifyAnimation,
|
||||
calculateQueryRunTime, callRenderAfterPoll) {
|
||||
keyboardShortcuts, queryToolActions, queryToolNotifications, Datagrid,
|
||||
modifyAnimation, calculateQueryRunTime, callRenderAfterPoll) {
|
||||
/* Return back, this has been called more than once */
|
||||
if (pgAdmin.SqlEditor)
|
||||
return pgAdmin.SqlEditor;
|
||||
@@ -242,19 +243,32 @@ define('tools.querytool', [
|
||||
content: '<div id ="history_grid" class="sql-editor-history-container" tabindex: "0"></div>',
|
||||
});
|
||||
|
||||
var notifications = new pgAdmin.Browser.Panel({
|
||||
name: 'notifications',
|
||||
title: gettext('Notifications'),
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
isCloseable: false,
|
||||
isPrivate: true,
|
||||
content: '<div id ="notification_grid" class="sql-editor-notifications" tabindex: "0"></div>',
|
||||
});
|
||||
|
||||
// Load all the created panels
|
||||
data_output.load(main_docker);
|
||||
explain.load(main_docker);
|
||||
messages.load(main_docker);
|
||||
history.load(main_docker);
|
||||
notifications.load(main_docker);
|
||||
|
||||
// Add all the panels to the docker
|
||||
self.data_output_panel = main_docker.addPanel('data_output', wcDocker.DOCK.BOTTOM, sql_panel_obj);
|
||||
self.explain_panel = main_docker.addPanel('explain', wcDocker.DOCK.STACKED, self.data_output_panel);
|
||||
self.messages_panel = main_docker.addPanel('messages', wcDocker.DOCK.STACKED, self.data_output_panel);
|
||||
self.history_panel = main_docker.addPanel('history', wcDocker.DOCK.STACKED, self.data_output_panel);
|
||||
self.notifications_panel = main_docker.addPanel('notifications', wcDocker.DOCK.STACKED, self.data_output_panel);
|
||||
|
||||
self.render_history_grid();
|
||||
queryToolNotifications.renderNotificationsGrid(self.notifications_panel);
|
||||
|
||||
if (!self.handler.is_new_browser_tab) {
|
||||
// Listen on the panel closed event and notify user to save modifications.
|
||||
@@ -3832,6 +3846,12 @@ define('tools.querytool', [
|
||||
}
|
||||
});
|
||||
},
|
||||
/* This function is used to raise notify messages and update
|
||||
* the notification grid.
|
||||
*/
|
||||
update_notifications: function (notifications) {
|
||||
queryToolNotifications.updateNotifications(notifications);
|
||||
},
|
||||
});
|
||||
|
||||
pgAdmin.SqlEditor = {
|
||||
|
@@ -47,6 +47,7 @@ class StartRunningQuery:
|
||||
transaction_object = pickle.loads(session_obj['command_obj'])
|
||||
can_edit = False
|
||||
can_filter = False
|
||||
notifies = None
|
||||
if transaction_object is not None and session_obj is not None:
|
||||
# set fetched row count to 0 as we are executing query again.
|
||||
transaction_object.update_fetched_row_cnt(0)
|
||||
@@ -88,6 +89,8 @@ class StartRunningQuery:
|
||||
can_edit = transaction_object.can_edit()
|
||||
can_filter = transaction_object.can_filter()
|
||||
|
||||
# Get the notifies
|
||||
notifies = conn.get_notifies()
|
||||
else:
|
||||
status = False
|
||||
result = gettext(
|
||||
@@ -97,7 +100,8 @@ class StartRunningQuery:
|
||||
'status': status, 'result': result,
|
||||
'can_edit': can_edit, 'can_filter': can_filter,
|
||||
'info_notifier_timeout':
|
||||
self.blueprint_object.info_notifier_timeout.get()
|
||||
self.blueprint_object.info_notifier_timeout.get(),
|
||||
'notifies': notifies
|
||||
}
|
||||
)
|
||||
|
||||
|
@@ -117,7 +117,8 @@ class StartRunningQueryTest(BaseTestGenerator):
|
||||
'not found.',
|
||||
can_edit=False,
|
||||
can_filter=False,
|
||||
info_notifier_timeout=5
|
||||
info_notifier_timeout=5,
|
||||
notifies=None
|
||||
)
|
||||
),
|
||||
expect_internal_server_error_called_with=None,
|
||||
@@ -276,7 +277,8 @@ class StartRunningQueryTest(BaseTestGenerator):
|
||||
result='async function result output',
|
||||
can_edit=True,
|
||||
can_filter=True,
|
||||
info_notifier_timeout=5
|
||||
info_notifier_timeout=5,
|
||||
notifies=None
|
||||
)
|
||||
),
|
||||
expect_internal_server_error_called_with=None,
|
||||
@@ -319,7 +321,8 @@ class StartRunningQueryTest(BaseTestGenerator):
|
||||
result='async function result output',
|
||||
can_edit=True,
|
||||
can_filter=True,
|
||||
info_notifier_timeout=5
|
||||
info_notifier_timeout=5,
|
||||
notifies=None
|
||||
)
|
||||
),
|
||||
expect_internal_server_error_called_with=None,
|
||||
@@ -362,7 +365,8 @@ class StartRunningQueryTest(BaseTestGenerator):
|
||||
result='async function result output',
|
||||
can_edit=True,
|
||||
can_filter=True,
|
||||
info_notifier_timeout=5
|
||||
info_notifier_timeout=5,
|
||||
notifies=None
|
||||
)
|
||||
),
|
||||
expect_internal_server_error_called_with=None,
|
||||
@@ -406,7 +410,8 @@ class StartRunningQueryTest(BaseTestGenerator):
|
||||
result='async function result output',
|
||||
can_edit=True,
|
||||
can_filter=True,
|
||||
info_notifier_timeout=5
|
||||
info_notifier_timeout=5,
|
||||
notifies=None
|
||||
)
|
||||
),
|
||||
expect_internal_server_error_called_with=None,
|
||||
@@ -511,8 +516,10 @@ class StartRunningQueryTest(BaseTestGenerator):
|
||||
connect=MagicMock(),
|
||||
execute_async=MagicMock(),
|
||||
execute_void=MagicMock(),
|
||||
get_notifies=MagicMock(),
|
||||
)
|
||||
self.connection.connect.return_value = self.connection_connect_return
|
||||
self.connection.get_notifies.return_value = None
|
||||
self.connection.execute_async.return_value = \
|
||||
self.execute_async_return_value
|
||||
if self.manager_connection_exception is None:
|
||||
|
Reference in New Issue
Block a user