mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Fix an issue where debugger not showing all arguments anymore after hitting SQL error while debugging. Fixes #5101
Added a "Clear All" button to the argument dialog which will clear all the saved arguments values from SQLite DB.
This commit is contained in:
parent
c9d04684ce
commit
4db0a6524d
@ -81,6 +81,8 @@ Use the fields on the *Debugger* dialog to provide a value for each parameter:
|
||||
|
||||
Provide values required by the program, and click the *Debug* button to start
|
||||
stepping through the program.
|
||||
The values of the arguments provided here are saved. The values will be pre-filled
|
||||
next time the dialog opens. To clear the values, use the *Clear All* button.
|
||||
|
||||
.. image:: images/debug_step_in.png
|
||||
:alt: Debugger step-in demo
|
||||
|
BIN
docs/en_US/images/debug_params.png
Executable file → Normal file
BIN
docs/en_US/images/debug_params.png
Executable file → Normal file
Binary file not shown.
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 48 KiB |
@ -28,6 +28,7 @@ Bug fixes
|
||||
| `Issue #4996 <https://redmine.postgresql.org/issues/4996>`_ - Improve the style of the highlighted code after query execution for Dark mode.
|
||||
| `Issue #5058 <https://redmine.postgresql.org/issues/5058>`_ - Ensure that AlertifyJS should not be visible as a title for alert dialog.
|
||||
| `Issue #5077 <https://redmine.postgresql.org/issues/5077>`_ - Changed background pattern for geometry viewer to use #fff for all themes.
|
||||
| `Issue #5101 <https://redmine.postgresql.org/issues/5101>`_ - Fix an issue where debugger not showing all arguments anymore after hitting SQL error while debugging.
|
||||
| `Issue #5107 <https://redmine.postgresql.org/issues/5107>`_ - Set proper focus on tab navigation for file manager dialog.
|
||||
| `Issue #5115 <https://redmine.postgresql.org/issues/5115>`_ - Fix an issue where command and statements were parsed incorrectly for Rules.
|
||||
| `Issue #5142 <https://redmine.postgresql.org/issues/5142>`_ - Ensure that all the transactions should be canceled before closing the connections when a server is disconnected using pgAdmin.
|
||||
|
@ -1916,6 +1916,58 @@ define([
|
||||
},
|
||||
});
|
||||
|
||||
Backgrid.BooleanCell = Backgrid.BooleanCell.extend({
|
||||
className: 'boolean-cell',
|
||||
|
||||
enterEditMode: function() {
|
||||
this.$el.addClass('editor');
|
||||
$(this.$el.find('input[type=checkbox]')).trigger('focus');
|
||||
},
|
||||
|
||||
exitEditMode: function() {
|
||||
this.$el.removeClass('editor');
|
||||
},
|
||||
|
||||
events: {
|
||||
'change input': 'onChange',
|
||||
'blur input': 'exitEditMode',
|
||||
'keydown': 'onKeyDown',
|
||||
},
|
||||
|
||||
onChange: function(e) {
|
||||
var model = this.model,
|
||||
column = this.column,
|
||||
val = this.formatter.toRaw(this.$input.prop('checked'), model);
|
||||
|
||||
this.enterEditMode();
|
||||
// on bootstrap change we also need to change model's value
|
||||
model.set(column.get('name'), val);
|
||||
model.trigger('backgrid:edited', model, column, new Backgrid.Command(e));
|
||||
},
|
||||
|
||||
render: function () {
|
||||
this.$el.empty();
|
||||
var model = this.model, column = this.column;
|
||||
var editable = Backgrid.callByNeed(column.editable(), column, model);
|
||||
var align_center = column.get('align_center') || false;
|
||||
let checked = this.formatter.fromRaw(model.get(column.get('name')), model);
|
||||
let id = `column.get('name')_${_.uniqueId()}`;
|
||||
|
||||
this.$el.empty();
|
||||
this.$el.append(
|
||||
$(`<div class="custom-control custom-checkbox custom-checkbox-no-label ${align_center?'text-center':''}">
|
||||
<input tabindex="0" type="checkbox" class="custom-control-input" id="${id}" ${!editable?'disabled':''} ${checked?'checked':''}/>
|
||||
<label class="custom-control-label" for="${id}">
|
||||
<span class="sr-only">Select<span>
|
||||
</label>
|
||||
</div>`)
|
||||
);
|
||||
this.$input = this.$el.find('input');
|
||||
this.delegateEvents();
|
||||
return this;
|
||||
},
|
||||
});
|
||||
|
||||
return Backgrid;
|
||||
|
||||
});
|
||||
|
@ -241,7 +241,7 @@ class DebuggerModule(PgAdminModule):
|
||||
'debugger.start_execution', 'debugger.set_breakpoint',
|
||||
'debugger.clear_all_breakpoint', 'debugger.deposit_value',
|
||||
'debugger.select_frame', 'debugger.get_arguments',
|
||||
'debugger.set_arguments',
|
||||
'debugger.set_arguments', 'debugger.clear_arguments',
|
||||
'debugger.poll_end_execution_result', 'debugger.poll_result'
|
||||
]
|
||||
|
||||
@ -1797,9 +1797,10 @@ def set_arguments_sqlite(sid, did, scid, func_id):
|
||||
|
||||
db.session.add(debugger_func_args)
|
||||
|
||||
db.session.commit()
|
||||
db.session.commit()
|
||||
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
current_app.logger.exception(e)
|
||||
return make_json_response(
|
||||
status=410,
|
||||
@ -1810,6 +1811,51 @@ def set_arguments_sqlite(sid, did, scid, func_id):
|
||||
return make_json_response(data={'status': True, 'result': 'Success'})
|
||||
|
||||
|
||||
@blueprint.route(
|
||||
'/clear_arguments/<int:sid>/<int:did>/<int:scid>/<int:func_id>',
|
||||
methods=['POST'], endpoint='clear_arguments'
|
||||
)
|
||||
@login_required
|
||||
def clear_arguments_sqlite(sid, did, scid, func_id):
|
||||
"""
|
||||
clear_arguments_sqlite(sid, did, scid, func_id)
|
||||
|
||||
This method is responsible for clearing function arguments
|
||||
from sqlite database
|
||||
|
||||
Parameters:
|
||||
sid
|
||||
- Server Id
|
||||
did
|
||||
- Database Id
|
||||
scid
|
||||
- Schema Id
|
||||
func_id
|
||||
- Function Id
|
||||
"""
|
||||
|
||||
try:
|
||||
db.session.query(DebuggerFunctionArguments) \
|
||||
.filter(DebuggerFunctionArguments.server_id == sid,
|
||||
DebuggerFunctionArguments.database_id == did,
|
||||
DebuggerFunctionArguments.schema_id == scid,
|
||||
DebuggerFunctionArguments.function_id == func_id) \
|
||||
.delete()
|
||||
|
||||
db.session.commit()
|
||||
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
current_app.logger.exception(e)
|
||||
return make_json_response(
|
||||
status=410,
|
||||
success=0,
|
||||
errormsg=str(e)
|
||||
)
|
||||
|
||||
return make_json_response(data={'status': True, 'result': 'Success'})
|
||||
|
||||
|
||||
def convert_data_to_dict(conn, result):
|
||||
"""
|
||||
This function helps us to convert result set into dict
|
||||
|
@ -69,7 +69,7 @@ define([
|
||||
// As we are getting this value as text from sqlite database so we need to type cast it.
|
||||
if (model.get('value') != undefined) {
|
||||
model.set({
|
||||
'value': parseInt(model.get('value')),
|
||||
'value': isNaN(parseInt(model.get('value'))) ? null : parseInt(model.get('value')),
|
||||
}, {
|
||||
silent: true,
|
||||
});
|
||||
@ -176,6 +176,7 @@ define([
|
||||
this.set('debug_info', debug_info);
|
||||
this.set('restart_debug', restart_debug);
|
||||
this.set('trans_id', trans_id);
|
||||
this.set('is_edb_proc', is_edb_proc);
|
||||
|
||||
// Variables to store the data sent from sqlite database
|
||||
var func_args_data = this.func_args_data = [];
|
||||
@ -289,6 +290,7 @@ define([
|
||||
label: gettext('Null?'),
|
||||
type: 'boolean',
|
||||
cell: 'boolean',
|
||||
align_center: true,
|
||||
},
|
||||
{
|
||||
name: 'expr',
|
||||
@ -296,6 +298,7 @@ define([
|
||||
type: 'boolean',
|
||||
cellFunction: cellExprControlFunction,
|
||||
editable: disableExpressionControl,
|
||||
align_center: true,
|
||||
},
|
||||
{
|
||||
name: 'value',
|
||||
@ -304,6 +307,7 @@ define([
|
||||
editable: true,
|
||||
cellFunction: cellFunction,
|
||||
headerCell: value_header,
|
||||
align_center: true,
|
||||
},
|
||||
{
|
||||
name: 'use_default',
|
||||
@ -413,12 +417,12 @@ define([
|
||||
// Need to update the func_obj variable from sqlite database if available
|
||||
if (func_args_data.length != 0) {
|
||||
for (i = 0; i < func_args_data.length; i++) {
|
||||
index = func_args_data[i]['arg_id'];
|
||||
if (debug_info['proargmodes'] != null &&
|
||||
(argmode[i] == 'o' && !is_edb_proc)) {
|
||||
(argmode[index] == 'o' && !is_edb_proc)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
index = func_args_data[i]['arg_id'];
|
||||
values = [];
|
||||
if (argtype[index].indexOf('[]') != -1) {
|
||||
vals = func_args_data[i]['value'].split(',');
|
||||
@ -565,14 +569,17 @@ define([
|
||||
});
|
||||
|
||||
grid.render();
|
||||
$(this.elements.content).html(grid.el);
|
||||
let wrap_div = document.createElement('div');
|
||||
wrap_div.classList.add('debugger-args');
|
||||
wrap_div.appendChild(grid.el);
|
||||
$(this.elements.content).html(wrap_div);
|
||||
|
||||
// For keyboard navigation in the grid
|
||||
// we'll set focus on checkbox from the first row if any
|
||||
var grid_checkbox = $(grid.el).find('input:checkbox').first();
|
||||
if (grid_checkbox.length) {
|
||||
setTimeout(function() {
|
||||
grid_checkbox.trigger('click');
|
||||
grid_checkbox.trigger('focus');
|
||||
}, 250);
|
||||
}
|
||||
|
||||
@ -585,6 +592,9 @@ define([
|
||||
setup: function() {
|
||||
return {
|
||||
buttons: [{
|
||||
text: gettext('Clear All'),
|
||||
className: 'btn btn-secondary pull-left fa fa-eraser pg-alertify-button',
|
||||
},{
|
||||
text: gettext('Cancel'),
|
||||
key: 27,
|
||||
className: 'btn btn-secondary fa fa-times pg-alertify-button',
|
||||
@ -899,6 +909,69 @@ define([
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (e.button.text === gettext('Clear All')) {
|
||||
let self = this;
|
||||
let baseUrl = null;
|
||||
|
||||
if (self.setting('restart_debug') == 0) {
|
||||
let selected_item = pgBrowser.tree.selected();
|
||||
let item_data = pgBrowser.tree.itemData(selected_item);
|
||||
if (!item_data)
|
||||
return;
|
||||
|
||||
let node = pgBrowser.Nodes[item_data._type];
|
||||
let treeInfo = node.getTreeNodeHierarchy.call(node, selected_item);
|
||||
|
||||
let f_id;
|
||||
if (item_data._type == 'function') {
|
||||
f_id = item_data._id;
|
||||
} else if (item_data._type == 'procedure') {
|
||||
f_id = item_data._id;
|
||||
} else if (item_data._type == 'edbfunc') {
|
||||
f_id = item_data._id;
|
||||
} else if (item_data._type == 'edbproc') {
|
||||
f_id = item_data._id;
|
||||
}
|
||||
|
||||
baseUrl = url_for('debugger.clear_arguments', {
|
||||
'sid': treeInfo.server._id,
|
||||
'did': treeInfo.database._id,
|
||||
'scid': treeInfo.schema._id,
|
||||
'func_id': f_id,
|
||||
});
|
||||
} else {
|
||||
baseUrl = url_for('debugger.clear_arguments', {
|
||||
'sid': self.setting('debug_info').server_id,
|
||||
'did': self.setting('debug_info').database_id,
|
||||
'scid': self.setting('debug_info').schema_id,
|
||||
'func_id': self.setting('debug_info').function_id,
|
||||
});
|
||||
}
|
||||
$.ajax({
|
||||
url: baseUrl,
|
||||
method: 'POST',
|
||||
data: {
|
||||
'data': JSON.stringify(args_value_list),
|
||||
},
|
||||
}).done(function() {
|
||||
/* Disable debug button */
|
||||
self.__internal.buttons[2].element.disabled = true;
|
||||
self.main(self.setting('title'), self.setting('debug_info'),
|
||||
self.setting('restart_debug'), self.setting('is_edb_proc'),
|
||||
self.setting('trans_id')
|
||||
);
|
||||
self.prepare();
|
||||
}).fail(function(e) {
|
||||
Alertify.alert(
|
||||
gettext('Clear failed'),
|
||||
e.responseJSON.errormsg
|
||||
);
|
||||
});
|
||||
|
||||
e.cancel = true;
|
||||
return true;
|
||||
}
|
||||
},
|
||||
build: function() {
|
||||
Alertify.pgDialogBuild.apply(this);
|
||||
@ -914,9 +987,9 @@ define([
|
||||
enable the debug button otherwise disable the debug button.
|
||||
*/
|
||||
if (this.func_args_data.length == 0) {
|
||||
this.__internal.buttons[1].element.disabled = true;
|
||||
this.__internal.buttons[2].element.disabled = true;
|
||||
} else {
|
||||
this.__internal.buttons[1].element.disabled = false;
|
||||
this.__internal.buttons[2].element.disabled = false;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -933,7 +1006,7 @@ define([
|
||||
for (var i = 0; i < this.collection.length; i++) {
|
||||
|
||||
if (this.collection.models[i].get('is_null')) {
|
||||
obj.__internal.buttons[1].element.disabled = false;
|
||||
obj.__internal.buttons[2].element.disabled = false;
|
||||
enable_btn = true;
|
||||
continue;
|
||||
}
|
||||
@ -944,15 +1017,15 @@ define([
|
||||
enable_btn = true;
|
||||
|
||||
if (this.collection.models[i].get('use_default')) {
|
||||
obj.__internal.buttons[1].element.disabled = false;
|
||||
obj.__internal.buttons[2].element.disabled = false;
|
||||
} else {
|
||||
obj.__internal.buttons[1].element.disabled = true;
|
||||
obj.__internal.buttons[2].element.disabled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!enable_btn)
|
||||
obj.__internal.buttons[1].element.disabled = false;
|
||||
obj.__internal.buttons[2].element.disabled = false;
|
||||
};
|
||||
})(this)
|
||||
);
|
||||
@ -960,7 +1033,7 @@ define([
|
||||
this.grid.listenTo(this.debuggerInputArgsColl, 'backgrid:error',
|
||||
(function(obj) {
|
||||
return function() {
|
||||
obj.__internal.buttons[1].element.disabled = true;
|
||||
obj.__internal.buttons[2].element.disabled = true;
|
||||
};
|
||||
})(this)
|
||||
);
|
||||
|
@ -16,3 +16,10 @@
|
||||
-ms-user-select: text;
|
||||
user-select: text;
|
||||
}
|
||||
|
||||
.debugger-args {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user