Add support for LISTEN/NOTIFY in the query tool. Fixes #3204

This commit is contained in:
Akshay Joshi
2018-05-30 21:58:28 -04:00
committed by Dave Page
parent 2b4605a9d3
commit 38ee39ae7a
11 changed files with 335 additions and 19 deletions

View File

@@ -82,6 +82,8 @@ class ExecuteQuery {
self.loadingScreen.hide();
self.enableSQLEditorButtons();
self.sqlServerObject.update_msg_history(false, httpMessageData.data.result);
if ('notifies' in httpMessageData.data)
self.sqlServerObject.update_notifications(httpMessageData.data.notifies);
// Highlight the error in the sql panel
self.sqlServerObject._highlight_error(httpMessageData.data.result);
@@ -116,6 +118,8 @@ class ExecuteQuery {
self.loadingScreen.setMessage('Loading data from the database server and rendering...');
self.sqlServerObject.call_render_after_poll(httpMessage.data.data);
if ('notifies' in httpMessage.data.data)
self.sqlServerObject.update_notifications(httpMessage.data.data.notifies);
} else if (ExecuteQuery.isQueryStillRunning(httpMessage)) {
// If status is Busy then poll the result by recursive call to the poll function
this.delayedPoll();

View File

@@ -0,0 +1,131 @@
import gettext from 'sources/gettext';
import Backgrid from 'pgadmin.backgrid';
import Backbone from 'backbone';
import Alertify from 'pgadmin.alertifyjs';
let NotificationsModel = Backbone.Model.extend({
defaults: {
recorded_time: undefined,
event: undefined,
pid: undefined,
payload: undefined,
},
schema: [{
id: 'recorded_time',
label: gettext('Recorded time'),
cell: 'string',
type: 'text',
editable: false,
cellHeaderClasses: 'width_percent_20',
headerCell: Backgrid.Extension.CustomHeaderCell,
},{
id: 'channel',
label: gettext('Event'),
cell: 'string',
type: 'text',
editable: false,
cellHeaderClasses: 'width_percent_20',
headerCell: Backgrid.Extension.CustomHeaderCell,
},{
id: 'pid',
label: gettext('Process ID'),
cell: 'string',
type: 'text',
editable: false,
cellHeaderClasses: 'width_percent_20',
headerCell: Backgrid.Extension.CustomHeaderCell,
},{
id: 'payload',
label: gettext('Payload'),
cell: 'string',
type: 'text',
editable: false,
cellHeaderClasses: 'width_percent_40',
headerCell: Backgrid.Extension.CustomHeaderCell,
}],
});
let NotificationCollection = Backbone.Collection.extend({
model: NotificationsModel,
});
let queryToolNotifications = {
collection: null,
/* This function is responsible to create and render the
* new backgrid for the notification tab.
*/
renderNotificationsGrid: function(notifications_panel) {
if (!queryToolNotifications.collection)
queryToolNotifications.collection = new NotificationCollection();
let gridCols = [{
name: 'recorded_time',
label: gettext('Recorded time'),
type: 'text',
editable: false,
cell: 'string',
}, {
name: 'channel',
label: gettext('Event'),
type: 'text',
editable: false,
cell: 'string',
}, {
name: 'pid',
label: gettext('Process ID'),
type: 'text',
editable: false,
cell: 'string',
}, {
name: 'payload',
label: gettext('Payload'),
type: 'text',
editable: false,
cell: 'string',
}];
// Set up the grid
let notifications_grid = new Backgrid.Grid({
columns: gridCols,
collection: queryToolNotifications.collection,
className: 'backgrid table-bordered presentation table backgrid-striped',
});
// Render the grid
if (notifications_grid)
notifications_panel.$container.append(notifications_grid.render().el);
},
// This function is used to raise notify messages and update the
// notification grid.
updateNotifications: function(notify_messages) {
if (notify_messages != null && notify_messages.length > 0) {
for (let i in notify_messages) {
let notify_msg = '';
if (notify_messages[i].payload != '') {
notify_msg = gettext('Asynchronous notification "')
+ notify_messages[i].channel
+ gettext('" with payload "')
+ notify_messages[i].payload
+ gettext('" received from server process with PID ')
+ notify_messages[i].pid;
}
else {
notify_msg = gettext('Asynchronous notification "')
+ notify_messages[i].channel
+ gettext('" received from server process with PID ')
+ notify_messages[i].pid;
}
Alertify.info(notify_msg);
}
// Add notify messages to the collection.
queryToolNotifications.collection.add(notify_messages);
}
},
};
module.exports = queryToolNotifications;

View File

@@ -72,6 +72,9 @@ define(['jquery', 'sources/gettext', 'sources/url_for'],
$el.data('panel-visible') !== 'visible' ) {
return;
}
let sqleditor_obj = target;
// Start polling..
$.ajax({
url: url,
@@ -82,6 +85,9 @@ define(['jquery', 'sources/gettext', 'sources/url_for'],
msg = res.data.message,
is_status_changed = false;
// Raise notify messages comes from database server.
sqleditor_obj.update_notifications(res.data.notifies);
// Inject CSS as required
switch(status) {
// Busy