Various tweaks and improvements to the debugger

This commit is contained in:
Neel Patel
2016-04-18 08:34:18 -04:00
committed by Dave Page
parent 09cc78bd0a
commit 4f8b018b39
6 changed files with 229 additions and 130 deletions
+39 -31
View File
@@ -171,7 +171,7 @@ def init_function(node_type, sid, did, scid, fid):
if user['is_superuser']: if user['is_superuser']:
status_in, rid_pre = conn.execute_scalar("SHOW shared_preload_libraries") status_in, rid_pre = conn.execute_scalar("SHOW shared_preload_libraries")
if not status_in: if not status_in:
return internal_server_error("ERROR: Couldn't fetch debugger plugin information") return internal_server_error(gettext("ERROR: Couldn't fetch debugger plugin information"))
# Need to check if plugin is really loaded or not with "plugin_debugger" string # Need to check if plugin is really loaded or not with "plugin_debugger" string
if rid_pre: if rid_pre:
@@ -181,7 +181,7 @@ def init_function(node_type, sid, did, scid, fid):
status_in, rid_tar = conn.execute_scalar("SELECT count(*) FROM pg_proc WHERE proname = 'pldbg_get_target_info'") status_in, rid_tar = conn.execute_scalar("SELECT count(*) FROM pg_proc WHERE proname = 'pldbg_get_target_info'")
if not status_in: if not status_in:
current_app.logger.debug("ERROR: Couldn't fetch debugger target information") current_app.logger.debug("ERROR: Couldn't fetch debugger target information")
return internal_server_error("ERROR: Couldn't fetch debugger target information") return internal_server_error(gettext("ERROR: Couldn't fetch debugger target information"))
if rid_tar == 0: if rid_tar == 0:
ret_status = False ret_status = False
@@ -191,7 +191,7 @@ def init_function(node_type, sid, did, scid, fid):
# Return the response that function can not be debug... # Return the response that function can not be debug...
if not ret_status: if not ret_status:
current_app.logger.debug("Error: Function/Procedure can not be debug") current_app.logger.debug("Error: Function/Procedure can not be debug")
return internal_server_error("ERROR: Function/Procedure can not be debug.") return internal_server_error(gettext("ERROR: Function/Procedure cannot be debugged."))
# Store the function information in session variable # Store the function information in session variable
if 'funcData' not in session: if 'funcData' not in session:
@@ -199,25 +199,6 @@ def init_function(node_type, sid, did, scid, fid):
else: else:
function_data = session['funcData'] function_data = session['funcData']
function_data = {
'oid': fid,
'name': r_set['rows'][0]['name'],
'is_func': r_set['rows'][0]['isfunc'],
'is_callable': False,
'schema': r_set['rows'][0]['schemaname'],
'language': r_set['rows'][0]['lanname'],
'return_type': r_set['rows'][0]['rettype'],
'args_type': r_set['rows'][0]['proargtypenames'],
'args_name': r_set['rows'][0]['proargnames'],
'arg_mode': r_set['rows'][0]['proargmodes'],
'use_default': r_set['rows'][0]['pronargdefaults'],
'default_value': r_set['rows'][0]['proargdefaults'],
'pkg': r_set['rows'][0]['pkg'],
'args_value': ''
}
session['funcData'] = function_data;
data = {} data = {}
data['name'] = r_set['rows'][0]['proargnames'] data['name'] = r_set['rows'][0]['proargnames']
data['type'] = r_set['rows'][0]['proargtypenames'] data['type'] = r_set['rows'][0]['proargtypenames']
@@ -244,6 +225,26 @@ def init_function(node_type, sid, did, scid, fid):
r_set['rows'][0]['require_input'] = data['require_input'] r_set['rows'][0]['require_input'] = data['require_input']
function_data = {
'oid': fid,
'name': r_set['rows'][0]['name'],
'is_func': r_set['rows'][0]['isfunc'],
'is_callable': False,
'schema': r_set['rows'][0]['schemaname'],
'language': r_set['rows'][0]['lanname'],
'return_type': r_set['rows'][0]['rettype'],
'args_type': r_set['rows'][0]['proargtypenames'],
'args_name': r_set['rows'][0]['proargnames'],
'arg_mode': r_set['rows'][0]['proargmodes'],
'use_default': r_set['rows'][0]['pronargdefaults'],
'default_value': r_set['rows'][0]['proargdefaults'],
'pkg': r_set['rows'][0]['pkg'],
'require_input': data['require_input'],
'args_value': ''
}
session['funcData'] = function_data;
return make_json_response( return make_json_response(
data=r_set['rows'], data=r_set['rows'],
status=200 status=200
@@ -395,6 +396,7 @@ def initialize_target(debug_type, sid, did, scid, func_id):
'use_default': func_data['use_default'], 'use_default': func_data['use_default'],
'default_value': func_data['default_value'], 'default_value': func_data['default_value'],
'pkg': func_data['pkg'], 'pkg': func_data['pkg'],
'require_input': func_data['require_input'],
'args_value': func_data['args_value'] 'args_value': func_data['args_value']
} }
@@ -511,7 +513,8 @@ def restart_debugging(trans_id):
'proargtypenames': session['functionData'][str(trans_id)]['args_type'], 'proargtypenames': session['functionData'][str(trans_id)]['args_type'],
'pronargdefaults': session['functionData'][str(trans_id)]['use_default'], 'pronargdefaults': session['functionData'][str(trans_id)]['use_default'],
'proargdefaults': session['functionData'][str(trans_id)]['default_value'], 'proargdefaults': session['functionData'][str(trans_id)]['default_value'],
'proargnames': session['functionData'][str(trans_id)]['args_name'] 'proargnames': session['functionData'][str(trans_id)]['args_name'],
'require_input': session['functionData'][str(trans_id)]['require_input']
} }
return make_json_response(data={'status': True, 'restart_debug': True, 'result': function_data}) return make_json_response(data={'status': True, 'restart_debug': True, 'result': function_data})
@@ -762,7 +765,7 @@ def execute_debugger_query(trans_id, query_type):
if not status: if not status:
return internal_server_error(errormsg=result) return internal_server_error(errormsg=result)
else: else:
return make_json_response(info='Target Aborted.', data={'status': status, 'result': result}) return make_json_response(info=gettext('Target Aborted.'), data={'status': status, 'result': result})
else: else:
status, result = conn.execute_dict(sql) status, result = conn.execute_dict(sql)
if not status: if not status:
@@ -1267,14 +1270,19 @@ def poll_end_execution_result(trans_id):
return make_json_response(success=1, info=gettext("Execution Completed."), return make_json_response(success=1, info=gettext("Execution Completed."),
data={'status': status, 'status_message': statusmsg}) data={'status': status, 'status_message': statusmsg})
if result: if result:
status = 'Success' if 'ERROR' in result:
data = {} status = 'ERROR'
for i in result: return make_json_response(info=gettext("Execution completed with error"),
for k, v in i.items(): data={'status': status, 'status_message': result})
data["name"] = k else:
data.setdefault("value",[]).append(v) status = 'Success'
data = {}
for i in result:
for k, v in i.items():
data["name"] = k
data.setdefault("value",[]).append(v)
return make_json_response(success=1, info=gettext("Execution Completed."), return make_json_response(success=1, info=gettext("Execution Completed."),
data={'status': status, 'result': data, 'status_message': statusmsg}) data={'status': status, 'result': data, 'status_message': statusmsg})
else: else:
status = 'Busy' status = 'Busy'
@@ -1,17 +1,17 @@
.navbar-static-top, .navbar-fixed-top, .navbar-fixed-bottom { .btn-step-into, .btn-step-over, .btn-continue, .btn-toggle-breakpoint, .btn-clear-breakpoint, .btn-stop {
background-image: linear-gradient(to bottom, #CCC 0%, #D2D2D2 100%);
}
.btn-default {
background-color: #D2D2D2; background-color: #D2D2D2;
left: 0px; left: 0px;
right: 0px; right: 0px;
padding: 7px; padding: 7px;
} }
.btn-toolbar { .debugger-toolbar {
padding-top: 3px; background-color: #D2D2D2;
padding-bottom: 3px; border: 2px solid #A9A9A9;
left: 0px;
right: 0px;
padding: 0px;
padding-left: 2px;
} }
#container { #container {
@@ -63,10 +63,10 @@
text-align: center; text-align: center;
} }
.top-container .breakpoints { .pg-debugger-panel .breakpoints {
width: 0.9em; width: 0.9em;
} }
.top-container .CodeMirror-activeline-background { .pg-debugger-panel .CodeMirror-activeline-background {
background: #50B0F0; background: #50B0F0;
} }
@@ -19,7 +19,7 @@ try {
{% block body %} {% block body %}
<nav class="navbar-inverse navbar-fixed-top"> <nav class="navbar-inverse navbar-fixed-top">
<div class="container-fluid"> <div class="container-fluid debugger-toolbar">
<div class="collapse navbar-collapse"> <div class="collapse navbar-collapse">
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<div id="btn-toolbar" class="btn-toolbar" role="toolbar" aria-label=""> <div id="btn-toolbar" class="btn-toolbar" role="toolbar" aria-label="">
@@ -55,6 +55,7 @@ define(
width: 500, width: 500,
isCloseable: true, isCloseable: true,
isPrivate: true, isPrivate: true,
icon: 'fa fa-arrow-circle-right',
url: 'about:blank' url: 'about:blank'
}); });
@@ -153,8 +154,7 @@ define(
try { try {
var err = $.parseJSON(xhr.responseText); var err = $.parseJSON(xhr.responseText);
if (err.success == 0) { if (err.success == 0) {
msg = S('{{ _(' + err.errormsg + ')}}').value(); Alertify.alert(err.errormsg);
Alertify.alert("{{ _('" + err.errormsg + "') }}");
} }
} catch (e) {} } catch (e) {}
} }
@@ -316,8 +316,7 @@ define(
try { try {
var err = $.parseJSON(xhr.responseText); var err = $.parseJSON(xhr.responseText);
if (err.success == 0) { if (err.success == 0) {
msg = S('{{ _(' + err.errormsg + ')}}').value(); Alertify.alert(err.errormsg);
Alertify.alert("{{ _('" + err.errormsg + "') }}");
} }
} catch (e) {} } catch (e) {}
} }
@@ -326,4 +325,4 @@ define(
}; };
return pgAdmin.Tools.Debugger; return pgAdmin.Tools.Debugger;
}); });
@@ -558,7 +558,6 @@ define(
method: 'POST', method: 'POST',
data:{'data':JSON.stringify(args_value_list)}, data:{'data':JSON.stringify(args_value_list)},
success: function(res) { success: function(res) {
//TODO: Anything required ? .....
}, },
error: function(e) { error: function(e) {
Alertify.alert( Alertify.alert(
@@ -247,6 +247,18 @@ define(
// Make ajax call to listen the database message // Make ajax call to listen the database message
var baseUrl = "{{ url_for('debugger.index') }}" + "poll_result/" + trans_id; var baseUrl = "{{ url_for('debugger.index') }}" + "poll_result/" + trans_id;
/*
During the execution we should poll the result in minimum seconds but once the execution is completed
and wait for the another debugging session then we should decrease the polling frequency.
*/
if (pgTools.DirectDebug.direct_execution_completed) {
// poll the result after 1 second
var poll_timeout = 1000;
}
else {
// poll the result after 200 ms
var poll_timeout = 200;
}
setTimeout( setTimeout(
function() { function() {
@@ -257,12 +269,11 @@ define(
if (res.data.status === 'Success') { if (res.data.status === 'Success') {
// If no result then poll again to wait for results. // If no result then poll again to wait for results.
if (res.data.result == null || res.data.result.length == 0) { if (res.data.result == null || res.data.result.length == 0) {
// NEEL: THIS IS CONDITION IS ADDED
self.poll_result(trans_id); self.poll_result(trans_id);
} }
else { else {
if (res.data.result[0].src != undefined || res.data.result[0].src != null) { if (res.data.result[0].src != undefined || res.data.result[0].src != null) {
pgTools.DirectDebug.docker.finishLoading(500); pgTools.DirectDebug.docker.finishLoading(50);
pgTools.DirectDebug.editor.setValue(res.data.result[0].src); pgTools.DirectDebug.editor.setValue(res.data.result[0].src);
self.UpdateBreakpoint(trans_id); self.UpdateBreakpoint(trans_id);
pgTools.DirectDebug.editor.removeLineClass(self.active_line_no, 'wrap', 'CodeMirror-activeline-background'); pgTools.DirectDebug.editor.removeLineClass(self.active_line_no, 'wrap', 'CodeMirror-activeline-background');
@@ -272,9 +283,10 @@ define(
// Update the stack, local variables and parameters information // Update the stack, local variables and parameters information
self.GetStackInformation(trans_id); self.GetStackInformation(trans_id);
self.GetLocalVariables(trans_id); self.GetLocalVariables(trans_id);
} }
else if (!pgTools.DirectDebug.debug_type && !pgTools.DirectDebug.first_time_indirect_debug) { else if (!pgTools.DirectDebug.debug_type && !pgTools.DirectDebug.first_time_indirect_debug) {
pgTools.DirectDebug.docker.finishLoading(500); pgTools.DirectDebug.docker.finishLoading(50);
if (self.active_line_no != undefined) { if (self.active_line_no != undefined) {
pgTools.DirectDebug.editor.removeLineClass(self.active_line_no, 'wrap', 'CodeMirror-activeline-background'); pgTools.DirectDebug.editor.removeLineClass(self.active_line_no, 'wrap', 'CodeMirror-activeline-background');
} }
@@ -283,7 +295,7 @@ define(
pgTools.DirectDebug.first_time_indirect_debug = true; pgTools.DirectDebug.first_time_indirect_debug = true;
} }
else { else {
pgTools.DirectDebug.docker.finishLoading(500); pgTools.DirectDebug.docker.finishLoading(50);
// If the source is really changed then only update the breakpoint information // If the source is really changed then only update the breakpoint information
if (res.data.result[0].src != pgTools.DirectDebug.editor.getValue()) { if (res.data.result[0].src != pgTools.DirectDebug.editor.getValue()) {
pgTools.DirectDebug.editor.setValue(res.data.result[0].src); pgTools.DirectDebug.editor.setValue(res.data.result[0].src);
@@ -323,7 +335,6 @@ define(
self.poll_result(trans_id); self.poll_result(trans_id);
} }
else { else {
//TODO: NEEL ADDED
self.poll_result(trans_id); self.poll_result(trans_id);
} }
} }
@@ -339,7 +350,7 @@ define(
); );
} }
}); });
}, 1000 ); }, poll_timeout );
}, },
@@ -353,6 +364,19 @@ define(
// Make ajax call to listen the database message // Make ajax call to listen the database message
var baseUrl = "{{ url_for('debugger.index') }}" + "poll_end_execution_result/" + trans_id; var baseUrl = "{{ url_for('debugger.index') }}" + "poll_end_execution_result/" + trans_id;
/*
During the execution we should poll the result in minimum seconds but once the execution is completed
and wait for the another debugging session then we should decrease the polling frequency.
*/
if (pgTools.DirectDebug.direct_execution_completed) {
// poll the result to check that execution is completed or not after 1200 ms
var poll_end_timeout = 1200;
}
else {
// poll the result to check that execution is completed or not after 350 ms
var poll_end_timeout = 250;
}
setTimeout( setTimeout(
function() { function() {
$.ajax({ $.ajax({
@@ -392,7 +416,7 @@ define(
if (res.data.result.name != null) { if (res.data.result.name != null) {
pgTools.DirectDebug.editor.removeLineClass(self.active_line_no, 'wrap', 'CodeMirror-activeline-background'); pgTools.DirectDebug.editor.removeLineClass(self.active_line_no, 'wrap', 'CodeMirror-activeline-background');
self.AddResults(res.data.result); self.AddResults(res.data.result);
pgTools.DirectDebug.paramsTabFrame.tab(3,true); pgTools.DirectDebug.results_panel.focus();
pgTools.DirectDebug.direct_execution_completed = true; pgTools.DirectDebug.direct_execution_completed = true;
//Set the alertify message to inform the user that execution is completed. //Set the alertify message to inform the user that execution is completed.
@@ -404,7 +428,7 @@ define(
); );
// Update the message tab of the debugger // Update the message tab of the debugger
pgTools.DirectDebug.dbmsMessages.$elem.text(res.data.status_message); pgTools.DirectDebug.messages_panel.$container.find('.messages').text(res.data.status_message);
// Execution completed so disable the buttons other than "Continue/Start" button because user can still // Execution completed so disable the buttons other than "Continue/Start" button because user can still
// start the same execution again. // start the same execution again.
@@ -413,12 +437,6 @@ define(
self.enable('step_into', false); self.enable('step_into', false);
self.enable('toggle_breakpoint', false); self.enable('toggle_breakpoint', false);
self.enable('clear_all_breakpoints', false); self.enable('clear_all_breakpoints', false);
//TODO: Continue button should be enable and user will be able to do next debugging with same function.
//self.enable('continue', false);
// NEEL: TODO: Added Execution is completed so again poll the result until user start the another debugging
//self.poll_end_execution_result(pgTools.DirectDebug.trans_id);
} }
} }
} }
@@ -432,6 +450,29 @@ define(
res.data.result res.data.result
); );
} }
else if (res.data.status === 'ERROR') {
pgTools.DirectDebug.direct_execution_completed = true;
pgTools.DirectDebug.editor.removeLineClass(self.active_line_no, 'wrap', 'CodeMirror-activeline-background');
//Set the alertify message to inform the user that execution is completed with error.
Alertify.notify(
res.info,
'error',
3,
function() { }
);
pgTools.DirectDebug.messages_panel.$container.find('.messages').text(res.data.status_message);
pgTools.DirectDebug.messages_panel.focus();
// Execution completed so disable the buttons other than "Continue/Start" button because user can still
// start the same execution again.
self.enable('stop', false);
self.enable('step_over', false);
self.enable('step_into', false);
self.enable('toggle_breakpoint', false);
self.enable('clear_all_breakpoints', false);
}
}, },
error: function(e) { error: function(e) {
Alertify.alert( Alertify.alert(
@@ -440,7 +481,7 @@ define(
); );
} }
}); });
}, 1200); }, poll_end_timeout);
}, },
@@ -453,14 +494,38 @@ define(
success: function(res) { success: function(res) {
// Restart the same function debugging with previous arguments // Restart the same function debugging with previous arguments
var restart_dbg = res.data.restart_debug ? 1 : 0; var restart_dbg = res.data.restart_debug ? 1 : 0;
debug_function_again(res.data.result, restart_dbg);
/*
Need to check if restart debugging really require to open the input dialog ?
If yes then we will get the previous arguments from database and populate the input dialog
If no then we should directly start the listener.
*/
if (res.data.result.require_input) {
var res_val = debug_function_again(res.data.result, restart_dbg);
}
else {
// Debugging of void function is started again so we need to start the listener again
var baseUrl = "{{ url_for('debugger.index') }}" + "start_listener/" + trans_id;
$.ajax({
url: baseUrl,
method: 'GET',
success: function(res) {
},
error: function(e) {
Alertify.alert(
'Debugger listener starting error',
e.responseJSON.errormsg
);
}
});
}
}, },
error: function(xhr, status, error) { error: function(xhr, status, error) {
try { try {
var err = $.parseJSON(xhr.responseText); var err = $.parseJSON(xhr.responseText);
if (err.success == 0) { if (err.success == 0) {
msg = S('{{ _(' + err.errormsg + ')}}').value(); Alertify.alert(err.errormsg);
Alertify.alert("{{ _('" + err.errormsg + "') }}");
} }
} catch (e) {} } catch (e) {}
} }
@@ -473,9 +538,9 @@ define(
//Check first if previous execution was completed or not //Check first if previous execution was completed or not
if (pgTools.DirectDebug.direct_execution_completed) { if (pgTools.DirectDebug.direct_execution_completed) {
pgTools.DirectDebug.direct_execution_completed = false;
// TODO: We need to get the arguments given by the user from sqlite database // TODO: We need to get the arguments given by the user from sqlite database
self.Restart(trans_id); self.Restart(trans_id);
pgTools.DirectDebug.direct_execution_completed = false;
} }
else { else {
// Make ajax call to listen the database message // Make ajax call to listen the database message
@@ -490,8 +555,6 @@ define(
if (pgTools.DirectDebug.debug_type) { if (pgTools.DirectDebug.debug_type) {
self.poll_end_execution_result(trans_id); self.poll_end_execution_result(trans_id);
} }
//NEEL: ADDED
//self.poll_end_execution_result(trans_id);
} }
else { else {
Alertify.alert( Alertify.alert(
@@ -716,8 +779,6 @@ define(
self.stack_grid = null; self.stack_grid = null;
} }
pgTools.DirectDebug.stackTab.$elem.empty();
var DebuggerStackModel = Backbone.Model.extend({ var DebuggerStackModel = Backbone.Model.extend({
defaults: { defaults: {
name: undefined, name: undefined,
@@ -776,7 +837,10 @@ define(
}); });
stack_grid.render(); stack_grid.render();
pgTools.DirectDebug.stackTab.$elem.append(stack_grid.el);
// Render the stack grid into stack panel
pgTools.DirectDebug.stack_pane_panel.$container.find('.stack_pane').append(stack_grid.el);
}, },
AddResults: function(result) { AddResults: function(result) {
@@ -788,8 +852,6 @@ define(
self.result_grid = null; self.result_grid = null;
} }
pgTools.DirectDebug.retResults.$elem.empty();
var DebuggerResultsModel = Backbone.Model.extend({ var DebuggerResultsModel = Backbone.Model.extend({
defaults: { defaults: {
name: undefined name: undefined
@@ -822,7 +884,10 @@ define(
}); });
result_grid.render(); result_grid.render();
pgTools.DirectDebug.retResults.$elem.append(result_grid.el);
// Render the result grid into result panel
pgTools.DirectDebug.results_panel.$container.find('.debug_results').append(result_grid.el);
}, },
AddLocalVariables: function(result) { AddLocalVariables: function(result) {
@@ -834,8 +899,6 @@ define(
self.variable_grid = null; self.variable_grid = null;
} }
pgTools.DirectDebug.localVars.$elem.empty();
var DebuggerVariablesModel = Backbone.Model.extend({ var DebuggerVariablesModel = Backbone.Model.extend({
defaults: { defaults: {
name: undefined, name: undefined,
@@ -873,7 +936,10 @@ define(
}); });
variable_grid.render(); variable_grid.render();
pgTools.DirectDebug.localVars.$elem.append(variable_grid.el);
// Render the variables grid into local variables panel
pgTools.DirectDebug.local_variables_panel.$container.find('.local_variables').append(variable_grid.el);
}, },
AddParameters: function(result) { AddParameters: function(result) {
@@ -885,8 +951,6 @@ define(
self.param_grid = null; self.param_grid = null;
} }
pgTools.DirectDebug.paramsTab.$elem.empty();
var DebuggerParametersModel = Backbone.Model.extend({ var DebuggerParametersModel = Backbone.Model.extend({
defaults: { defaults: {
name: undefined, name: undefined,
@@ -926,7 +990,9 @@ define(
}); });
param_grid.render(); param_grid.render();
pgTools.DirectDebug.paramsTab.$elem.append(param_grid.el);
// Render the parameters grid into parameter panel
pgTools.DirectDebug.parameters_panel.$container.find('.parameters').append(param_grid.el);
}, },
deposit_parameter_value: function(model) { deposit_parameter_value: function(model) {
@@ -1250,6 +1316,7 @@ define(
this.registerPanel( this.registerPanel(
'code', false, '100%', '100%', 'code', false, '100%', '100%',
function(panel) { function(panel) {
var container = panel.layout().scene().find('.pg-debugger-panel'); var container = panel.layout().scene().find('.pg-debugger-panel');
// Create the wcSplitter used by wcDocker to split the single panel. // Create the wcSplitter used by wcDocker to split the single panel.
@@ -1267,65 +1334,91 @@ define(
// By default, the splitter splits down the middle, we split the main panel by 80%. // By default, the splitter splits down the middle, we split the main panel by 80%.
hSplitter.pos(0.65); hSplitter.pos(0.65);
var $params = $('<div class="full-container params"></div>'); var params = $('<div class="full-container params"></div>');
hSplitter.right().addItem($params); hSplitter.right().addItem(params);
// Add Local parameters tab to display function arguments value // Create wcDocker for tab set.
var paramsTabFrame = self.paramsTabFrame = new wcTabFrame($params, panel); var out_docker = new wcDocker(
var paramsTab = self.paramsTab = paramsTabFrame.addTab( '.full-container', {
'{{_('Parameters')}}', -1, wcDocker.LAYOUT.SIMPLE allowContextMenu: false,
); allowCollapse: false,
paramsTab.addItem($('<div id=parameters class="info"></div>')); themePath: '{{ url_for('static', filename='css/wcDocker/Themes') }}',
theme: 'pgadmin'
});
// Add Local variables tab // Create the parameters panel to display the arguments of the functions
var localVars = self.localVars = paramsTabFrame.addTab( var parameters = new pgAdmin.Browser.Panel({
'{{ _('Local variables') }}', -1, wcDocker.LAYOUT.SIMPLE name: 'parameters',
); title: '{{ _('Parameters') }}',
localVars.addItem($('<div id=local_variables class="info"></div>')); width: '100%',
height:'100%',
isCloseable: false,
isPrivate: true,
content: '<div id ="parameters" class="parameters"></div>'
})
// Add DBMS messages tab // Create the Local variables panel to display the local variables of the function.
var dbmsMessages = self.dbmsMessages = paramsTabFrame.addTab( var local_variables = new pgAdmin.Browser.Panel({
'{{ _('Messages') }}', -1, wcDocker.LAYOUT.SIMPLE name: 'local_variables',
); title: '{{ _('Local variables') }}',
dbmsMessages.addItem($('<div id=dbms_messages class="info"></div>')); width: '100%',
height:'100%',
isCloseable: false,
isPrivate: true,
content: '<div id ="local_variables" class="local_variables"></div>'
})
// Add function return results tab // Create the messages panel to display the message returned from the database server
var retResults = self.retResults = paramsTabFrame.addTab( var messages = new pgAdmin.Browser.Panel({
'{{ _('Results') }}', -1, wcDocker.LAYOUT.SIMPLE name: 'messages',
); title: '{{ _('Messages') }}',
retResults.addItem($('<div id=ret_results class="info"></div>')); width: '100%',
height:'100%',
isCloseable: false,
isPrivate: true,
content: '<div id="messages" class="messages"></div>'
})
// Now create a second splitter to go inside the existing one. // Create the result panel to display the result after debugging the function
var $topContainer = $('<div class="debugger top-container"></div>'); var results = new pgAdmin.Browser.Panel({
hSplitter.left().addItem($topContainer); name: 'results',
title: '{{ _('Results') }}',
width: '100%',
height:'100%',
isCloseable: false,
isPrivate: true,
content: '<div id="debug_results" class="debug_results"></div>'
})
// Create the wcSplitter used by wcDocker to split the single panel. // Create the stack pane panel to display the debugging stack information.
var vSplitter = new wcSplitter( var stack_pane = new pgAdmin.Browser.Panel({
$topContainer, panel, name: 'stack_pane',
wcDocker.ORIENTATION.HORIZONTAL title: '{{ _('Stack') }}',
); width: '100%',
height:'100%',
isCloseable: false,
isPrivate: true,
content: '<div id="stack_pane" class="stack_pane"></div>'
})
// Initialize this splitter with a layout in each pane. // Load all the created panels
vSplitter.initLayouts(wcDocker.LAYOUT.SIMPLE, wcDocker.LAYOUT.SIMPLE); parameters.load(out_docker);
local_variables.load(out_docker);
messages.load(out_docker);
results.load(out_docker);
stack_pane.load(out_docker);
// Add all the panels to the docker
self.parameters_panel = out_docker.addPanel('parameters', wcDocker.DOCK.LEFT);
self.local_variables_panel = out_docker.addPanel('local_variables', wcDocker.DOCK.STACKED, self.parameters_panel);
self.stack_pane_panel = out_docker.addPanel('stack_pane', wcDocker.DOCK.STACKED, self.parameters_panel);
self.messages_panel = out_docker.addPanel('messages', wcDocker.DOCK.STACKED, self.parameters_panel);
self.results_panel = out_docker.addPanel('results', wcDocker.DOCK.STACKED, self.parameters_panel);
// Now create a tab widget and put that into one of the sub splits. // Now create a tab widget and put that into one of the sub splits.
var $stack = $('<div class="full-container stack">'); var editor_pane = $('<div id="stack_editor_pane" class="full-container-pane info"></div>');
vSplitter.bottom().addItem($stack);
var stackFrame = new wcTabFrame($stack, panel);
var stackTab = self.stackTab = stackFrame.addTab(
'{{ _('Stack pane') }}', -1, wcDocker.LAYOUT.SIMPLE
);
stackTab.addItem(
$('<div id="stack_pane" class="full-container-pane info"></div>'));
// By default, the splitter splits down the middle, we split the main panel by 80%.
vSplitter.pos(0.75);
// Now create a tab widget and put that into one of the sub splits.
var editor_pane = $('<div id="stack_pane" class="full-container-pane info"></div>');
var code_editor_area = $('<textarea id="debugger-editor-textarea"></textarea>').append(editor_pane); var code_editor_area = $('<textarea id="debugger-editor-textarea"></textarea>').append(editor_pane);
vSplitter.top().addItem(code_editor_area); hSplitter.left().addItem(code_editor_area);
// To show the line-number and set breakpoint marker details by user. // To show the line-number and set breakpoint marker details by user.
var editor = self.editor = CodeMirror.fromTextArea( var editor = self.editor = CodeMirror.fromTextArea(