Hi,

Please find patch to fix the below issues,

1) Debugger page layout
RM#2512

2) To fix the issue when you user clicks on Stop button and gets connection
lost error.
RM#2511

@Dave,
When we stop the debugger using pldbg_abort_target() function and try to
start it again in the same connection, we are not able to do so because we
do not get response from plugin(async query results shows busy status
only), I think that is the reason why in pgAdmin3 we have disable all the
buttons and release the connection if user clicks on stop button, For time
being I have done the same in pgAdmin4 until we find the solution for this
issue.

Misc changes are for PEP-8.

Please review.

--
Regards,
Murtuza Zabuawala
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
diff --git a/web/pgadmin/tools/debugger/__init__.py 
b/web/pgadmin/tools/debugger/__init__.py
index 8cebffc..35a0378 100644
--- a/web/pgadmin/tools/debugger/__init__.py
+++ b/web/pgadmin/tools/debugger/__init__.py
@@ -524,7 +524,7 @@ def initialize_target(debug_type, sid, did, scid, func_id, 
tri_id=None):
                                     'newBrowserTab': new_browser_tab})
 
 
-@blueprint.route('/close/<int:trans_id>', methods=["GET"])
+@blueprint.route('/close/<int:trans_id>', methods=["DELETE"])
 def close(trans_id):
     """
     close(trans_id)
@@ -849,10 +849,16 @@ def execute_debugger_query(trans_id, query_type):
         template_path = 'debugger/sql/v2'
 
     if conn.connected():
-        sql = render_template("/".join([template_path, query_type + ".sql"]), 
session_id=obj['session_id'])
-        # As the query type is continue or step_into or step_over then we may 
get result after some time so poll the
-        # result. We need to update the frame id variable when user move the 
next step for debugging.
-        if query_type == 'continue' or query_type == 'step_into' or query_type 
== 'step_over':
+        sql = render_template(
+            "/".join([template_path, query_type + ".sql"]),
+            session_id=obj['session_id']
+        )
+        # As the query type is continue or step_into or step_over then we
+        # may get result after some time so poll the result.
+        # We need to update the frame id variable when user move the next
+        # step for debugging.
+        if query_type == 'continue' or query_type == 'step_into' or \
+                        query_type == 'step_over':
             # We should set the frame_id to 0 when execution starts.
             if obj['frame_id'] != 0:
                 session_obj = debugger_data[str(trans_id)]
@@ -860,29 +866,30 @@ def execute_debugger_query(trans_id, query_type):
                 update_session_debugger_transaction(trans_id, session_obj)
 
             status, result = conn.execute_async(sql)
-            return make_json_response(data={'status': status, 'result': 
result})
+            return make_json_response(
+                data={'status': status, 'result': result}
+            )
         elif query_type == 'abort_target':
             status, result = conn.execute_dict(sql)
-
-            manager.release(did=obj['database_id'], conn_id=obj['conn_id'])
-
-            # Delete the existing debugger data in session variable
-            del session['debuggerData'][str(trans_id)]
-            del session['functionData'][str(trans_id)]
-
             if not status:
                 return internal_server_error(errormsg=result)
             else:
-                return make_json_response(info=gettext('Target Aborted.'), 
data={'status': status, 'result': result})
+                return make_json_response(
+                    info=gettext('Debugging aborted successfully.'),
+                    data={'status': 'Success', 'result': result}
+                )
         else:
             status, result = conn.execute_dict(sql)
         if not status:
             return internal_server_error(errormsg=result)
     else:
-        status = False
-        result = gettext('Not connected to server or connection with the 
server has been closed.')
+        result = gettext('Not connected to server or connection '
+                         'with the server has been closed.')
+        return internal_server_error(errormsg=result)
 
-    return make_json_response(data={'status': 'Success', 'result': 
result['rows']})
+    return make_json_response(
+        data={'status': 'Success', 'result': result['rows']}
+    )
 
 
 @blueprint.route('/messages/<int:trans_id>/', methods=["GET"])
@@ -915,9 +922,12 @@ def messages(trans_id):
         status, result = conn.poll()
         notify = conn.messages()
         if notify:
-            # In notice message we need to find "PLDBGBREAK" string to find 
the port number to attach.
-            # Notice message returned by the server is   "NOTICE:  
PLDBGBREAK:7".
-            # From the above message we need to find out port number as "7" so 
below logic will find 7 as port number
+            # In notice message we need to find "PLDBGBREAK" string to find the
+            # port number to attach.
+            # Notice message returned by the server is
+            # "NOTICE:  PLDBGBREAK:7".
+            # From the above message we need to find out port number
+            # as "7" so below logic will find 7 as port number
             # and attach listened to that port number
             offset = notify[0].find('PLDBGBREAK')
             str_len = len('PLDBGBREAK')
@@ -935,11 +945,18 @@ def messages(trans_id):
                 status = 'Busy'
         else:
             status = 'Busy'
+
+        return make_json_response(
+            data={'status': status, 'result': port_number}
+        )
     else:
-        status = 'NotConnected'
-        result = gettext('Not connected to server or connection with the 
server has been closed.')
+        result = gettext(
+            'Not connected to server or connection with the '
+            'server has been closed.'
+        )
+        return internal_server_error(errormsg=str(result))
+
 
-    return make_json_response(data={'status': status, 'result': port_number})
 
 
 @blueprint.route('/start_execution/<int:trans_id>/<int:port_num>', 
methods=['GET'])
@@ -1422,7 +1439,10 @@ def poll_end_execution_result(trans_id):
     if str(trans_id) not in debugger_data:
         return make_json_response(
             data={'status': 'NotConnected',
-                  'result': gettext('Not connected to server or connection 
with the server has been closed.')}
+                  'result': gettext(
+                      'Not connected to server or connection with the '
+                      'server has been closed.')
+                  }
         )
     obj = debugger_data[str(trans_id)]
 
@@ -1447,18 +1467,23 @@ def poll_end_execution_result(trans_id):
                 else:
                     statusmsg = additional_msgs
 
-            return make_json_response(success=1, info=gettext("Execution 
Completed."),
-                                      data={'status': status, 
'status_message': statusmsg})
+            return make_json_response(
+                success=1, info=gettext("Execution Completed."),
+                data={'status': status, 'status_message': statusmsg}
+            )
         if result:
             if 'ERROR' in result:
                 status = 'ERROR'
-                return make_json_response(info=gettext("Execution completed 
with error"),
-                                          data={'status': status, 
'status_message': result})
+                return make_json_response(
+                    info=gettext("Execution completed with error"),
+                    data={'status': status, 'status_message': result}
+                )
             else:
                 status = 'Success'
                 additional_msgs = conn.messages()
                 if len(additional_msgs) > 0:
-                    additional_msgs = [msg.strip("\n") for msg in 
additional_msgs]
+                    additional_msgs = [msg.strip("\n")
+                                       for msg in additional_msgs]
                     additional_msgs = "\n".join(additional_msgs)
                     if statusmsg:
                         statusmsg = additional_msgs + "\n" + statusmsg
@@ -1467,9 +1492,11 @@ def poll_end_execution_result(trans_id):
 
                 columns, result = convert_data_to_dict(conn, result)
 
-                return make_json_response(success=1, info=gettext("Execution 
Completed."),
-                                          data={'status': status, 'result': 
result,
-                                                'col_info': columns, 
'status_message': statusmsg})
+                return make_json_response(
+                    success=1, info=gettext("Execution Completed."),
+                    data={'status': status, 'result': result,
+                          'col_info': columns, 'status_message': statusmsg}
+                )
         else:
             status = 'Busy'
             additional_msgs = conn.messages()
@@ -1485,7 +1512,8 @@ def poll_end_execution_result(trans_id):
             })
     else:
         status = 'NotConnected'
-        result = gettext('Not connected to server or connection with the 
server has been closed.')
+        result = gettext('Not connected to server or connection with the '
+                         'server has been closed.')
 
     return make_json_response(data={'status': status, 'result': result})
 
diff --git a/web/pgadmin/tools/debugger/templates/debugger/direct.html 
b/web/pgadmin/tools/debugger/templates/debugger/direct.html
index 3e7bf2b..0e96817 100644
--- a/web/pgadmin/tools/debugger/templates/debugger/direct.html
+++ b/web/pgadmin/tools/debugger/templates/debugger/direct.html
@@ -11,7 +11,7 @@ try {
       window.onbeforeunload = function(ev) {
         $.ajax({
           url: "{{ url_for('debugger.index') }}close/{{ uniqueId }}",
-          method: 'GET'
+          method: 'DELETE'
         });
       };
     },
diff --git a/web/pgadmin/tools/debugger/templates/debugger/js/debugger.js 
b/web/pgadmin/tools/debugger/templates/debugger/js/debugger.js
index 624ca80..9664bc9 100644
--- a/web/pgadmin/tools/debugger/templates/debugger/js/debugger.js
+++ b/web/pgadmin/tools/debugger/templates/debugger/js/debugger.js
@@ -269,7 +269,7 @@ define([
                 var closeUrl = "{{ url_for('debugger.index') }}" + "close/" + 
res.data.debuggerTransId;
                 $.ajax({
                   url: closeUrl,
-                  method: 'GET'
+                  method: 'DELETE'
                 });
               });
             }
@@ -366,7 +366,7 @@ define([
                       var closeUrl = "{{ url_for('debugger.index') }}" + 
"close/" + res.data.debuggerTransId;
                       $.ajax({
                         url: closeUrl,
-                        method: 'GET'
+                        method: 'DELETE'
                       });
                     });
                   }
diff --git a/web/pgadmin/tools/debugger/templates/debugger/js/direct.js 
b/web/pgadmin/tools/debugger/templates/debugger/js/direct.js
index ba71acb..cbc3055 100644
--- a/web/pgadmin/tools/debugger/templates/debugger/js/direct.js
+++ b/web/pgadmin/tools/debugger/templates/debugger/js/direct.js
@@ -543,7 +543,10 @@ define([
 
               //Set the alertify message to inform the user that execution is 
completed with error.
               var alertifyWrapper = new AlertifyWrapper();
-              alertifyWrapper.error(res.info, 3);
+
+              if(!pgTools.DirectDebug.is_user_aborted_debugging) {
+                alertifyWrapper.error(res.info, 3);
+              }
 
               // Update the message tab of the debugger
               if (res.data.status_message) {
@@ -555,14 +558,21 @@ define([
               // remove progress cursor
               $('.debugger-container').removeClass('show_progress');
 
-              // Execution completed so disable the buttons other than 
"Continue/Start" button because user can still
-              // start the same execution again.
+              // 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);
-              self.enable('continue', true);
+              // If debugging is stopped by user then do not enable
+              // continue/restart button
+              if(!pgTools.DirectDebug.is_user_aborted_debugging)
+              {
+                self.enable('continue', true);
+                pgTools.DirectDebug.is_user_aborted_debugging = false;
+              }
 
               // Stop further pooling
               pgTools.DirectDebug.is_polling_required = false;
@@ -600,6 +610,7 @@ define([
           var restart_dbg = res.data.restart_debug ? 1 : 0;
 
           // Start pooling again
+          pgTools.DirectDebug.polling_timeout_idle = false;
           pgTools.DirectDebug.is_polling_required = true;
           self.poll_end_execution_result(trans_id);
           self.poll_result(trans_id);
@@ -768,7 +779,7 @@ define([
         self.enable('step_into', false);
         self.enable('toggle_breakpoint', false);
         self.enable('clear_all_breakpoints', false);
-        self.enable('continue', true);
+        self.enable('continue', false);
 
         // Make ajax call to listen the database message
         var baseUrl = "{{ url_for('debugger.index') }}" + "execute_query/" + 
trans_id + "/" + "abort_target";
@@ -781,14 +792,19 @@ define([
               // Call function to create and update local variables ....
               pgTools.DirectDebug.editor.removeLineClass(self.active_line_no, 
'wrap', 'CodeMirror-activeline-background');
               pgTools.DirectDebug.direct_execution_completed = true;
+              pgTools.DirectDebug.is_user_aborted_debugging = true;
 
-              //Set the alertify message to inform the user that execution is 
completed.
-              var alertifyWrapper = new AlertifyWrapper();
-              alertifyWrapper.success(res.info, 3);
+              // Stop further pooling
+              pgTools.DirectDebug.is_polling_required = false;
 
-              //Disable the buttons other than continue button. If user wants 
to again then it should allow to debug again...
-              self.enable('continue', true);
+              // Restarting debugging in the same transaction do not work
+              // We will give same behaviour as pgAdmin3 and disable all 
buttons
+              self.enable('continue', false);
 
+              // Set the alertify message to inform the user that execution
+              // is completed.
+              var alertifyWrapper = new AlertifyWrapper();
+              alertifyWrapper.success(res.info, 3);
             }
             else if (res.data.status === 'NotConnected') {
               Alertify.alert(
@@ -1353,6 +1369,7 @@ define([
       this.direct_execution_completed = false;
       this.polling_timeout_idle = false;
       this.debug_restarted = false;
+      this.is_user_aborted_debugging = false;
       this.is_polling_required = true; // Flag to stop unwanted ajax calls
 
       var docker = this.docker = new wcDocker(
@@ -1495,7 +1512,7 @@ define([
     intializePanels: function() {
       var self = this;
       this.registerPanel(
-        'code', false, '100%', '100%',
+        'code', false, '100%', '50%',
         function(panel) {
 
             // Create the parameters panel to display the arguments of the 
functions

Reply via email to