diff --git a/web/pgadmin/tools/debugger/__init__.py b/web/pgadmin/tools/debugger/__init__.py index 305c1522..3c0cd826 100644 --- a/web/pgadmin/tools/debugger/__init__.py +++ b/web/pgadmin/tools/debugger/__init__.py @@ -237,7 +237,6 @@ class DebuggerModule(PgAdminModule): fields=shortcut_fields ) - def get_exposed_url_endpoints(self): """ Returns the list of URLs exposed to the client. @@ -603,8 +602,6 @@ def direct_new(trans_id): # We need client OS information to render correct Keyboard shortcuts user_agent = UserAgent(request.headers.get('User-Agent')) - - return render_template( "debugger/direct.html", _=gettext, diff --git a/web/pgadmin/tools/sqleditor/__init__.py b/web/pgadmin/tools/sqleditor/__init__.py index 6db814c0..5c4c0b17 100644 --- a/web/pgadmin/tools/sqleditor/__init__.py +++ b/web/pgadmin/tools/sqleditor/__init__.py @@ -22,10 +22,12 @@ from flask_security import login_required from config import PG_DEFAULT_DRIVER, ON_DEMAND_RECORD_COUNT from pgadmin.misc.file_manager import Filemanager from pgadmin.tools.sqleditor.command import QueryToolCommand -from pgadmin.tools.sqleditor.utils.constant_definition import ASYNC_OK, ASYNC_EXECUTION_ABORTED, \ +from pgadmin.tools.sqleditor.utils.constant_definition import ASYNC_OK, \ + ASYNC_EXECUTION_ABORTED, \ CONNECTION_STATUS_MESSAGE_MAPPING, TX_STATUS_INERROR from pgadmin.tools.sqleditor.utils.start_running_query import StartRunningQuery -from pgadmin.tools.sqleditor.utils.update_session_grid_transaction import update_session_grid_transaction +from pgadmin.tools.sqleditor.utils.update_session_grid_transaction import \ + update_session_grid_transaction from pgadmin.utils import PgAdminModule from pgadmin.utils import get_storage_directory from pgadmin.utils.ajax import make_json_response, bad_request, \ @@ -432,8 +434,7 @@ def start_view_data(trans_id): status, error_msg, conn, trans_obj, session_obj = \ check_transaction_status(trans_id) - if error_msg == gettext( - 'Transaction ID not found in the session.'): + if error_msg == gettext('Transaction ID not found in the session.'): return make_json_response(success=0, errormsg=error_msg, info='DATAGRID_TRANSACTION_REQUIRED', status=404) @@ -460,8 +461,8 @@ def start_view_data(trans_id): data={'status': status, 'result': u"{}".format(msg)} ) - if status and conn is not None \ - and trans_obj is not None and session_obj is not None: + if status and conn is not None and \ + trans_obj is not None and session_obj is not None: # set fetched row count to 0 as we are executing query again. trans_obj.update_fetched_row_cnt(0) session_obj['command_obj'] = pickle.dumps(trans_obj, -1) @@ -566,14 +567,13 @@ def preferences(trans_id): status, error_msg, conn, trans_obj, session_obj = \ check_transaction_status(trans_id) - if error_msg == gettext( - 'Transaction ID not found in the session.'): + if error_msg == gettext('Transaction ID not found in the session.'): return make_json_response(success=0, errormsg=error_msg, info='DATAGRID_TRANSACTION_REQUIRED', status=404) - if status and conn is not None \ - and trans_obj is not None and session_obj is not None: + if status and conn is not None and \ + trans_obj is not None and session_obj is not None: # Call the set_auto_commit and set_auto_rollback method of # transaction object trans_obj.set_auto_commit(blueprint.auto_commit.get()) @@ -642,8 +642,7 @@ def poll(trans_id): status, error_msg, conn, trans_obj, session_obj = \ check_transaction_status(trans_id) - if error_msg == gettext( - 'Transaction ID not found in the session.'): + if error_msg == gettext('Transaction ID not found in the session.'): return make_json_response(success=0, errormsg=error_msg, info='DATAGRID_TRANSACTION_REQUIRED', status=404) @@ -656,9 +655,9 @@ def poll(trans_id): if messages and len(messages) > 0: additional_messages = ''.join(messages) result = '{0}\n{1}\n\n{2}'.format( - additional_messages, - gettext('******* Error *******'), - result + additional_messages, + gettext('******* Error *******'), + result ) return internal_server_error(result) elif status == ASYNC_OK: @@ -670,8 +669,8 @@ def poll(trans_id): # rollback to cleanup if isinstance(trans_obj, QueryToolCommand): trans_status = conn.transaction_status() - if (trans_status == TX_STATUS_INERROR and - trans_obj.auto_rollback): + if trans_status == TX_STATUS_INERROR and \ + trans_obj.auto_rollback: conn.execute_void("ROLLBACK;") st, result = conn.async_fetchmany_2darray(ON_DEMAND_RECORD_COUNT) @@ -701,7 +700,7 @@ def poll(trans_id): ) SQL = render_template( - "/".join([template_path,'nodes.sql']), + "/".join([template_path, 'nodes.sql']), tid=command_obj.obj_id, has_oids=True ) @@ -736,27 +735,7 @@ def poll(trans_id): if col_type['oid'] == col_info['type_code']: typname = col_type['typname'] - # If column is of type character, character[], - # character varying and character varying[] - # then add internal size to it's name for the - # correct sql query. - if col_info['internal_size'] >= 0: - if ( - typname == 'character' or - typname == 'character varying' - ): - typname = typname + '(' + \ - str( - col_info['internal_size'] - ) + ')' - elif ( - typname == 'character[]' or - typname == 'character varying[]' - ): - typname = typname[:-2] + '(' + \ - str( - col_info['internal_size'] - ) + ')[]' + typname = compose_type_name(col_info, typname) col_info['type_name'] = typname @@ -806,8 +785,8 @@ def poll(trans_id): # original result. if status == 'Success' and result is None: result = conn.status_message() - if (result != 'SELECT 1' or result != 'SELECT 0') \ - and result is not None and additional_messages: + if (result != 'SELECT 1' or result != 'SELECT 0') and \ + result is not None and additional_messages: result = additional_messages + result return make_json_response( @@ -828,6 +807,22 @@ def poll(trans_id): ) +def compose_type_name(col_info, typname): + # If column is of type character, character[], + # character varying and character varying[] + # then add internal size to it's name for the + # correct sql query. + if col_info['internal_size'] >= 0: + if typname == 'character' or typname == 'character varying': + typname = typname + '(' + str(col_info['internal_size']) + ')' + elif typname == 'character[]' or typname == 'character varying[]': + typname = '%s(%s)[]'.format( + typname[:-2], + str(col_info['internal_size']) + ) + return typname + + @blueprint.route( '/fetch/', methods=["GET"], endpoint='fetch' ) @@ -847,8 +842,7 @@ def fetch(trans_id, fetch_all=None): status, error_msg, conn, trans_obj, session_obj = \ check_transaction_status(trans_id) - if error_msg == gettext( - 'Transaction ID not found in the session.'): + if error_msg == gettext('Transaction ID not found in the session.'): return make_json_response(success=0, errormsg=error_msg, info='DATAGRID_TRANSACTION_REQUIRED', status=404) @@ -970,18 +964,18 @@ def save(trans_id): status, error_msg, conn, trans_obj, session_obj = \ check_transaction_status(trans_id) - if error_msg == gettext( - 'Transaction ID not found in the session.'): + if error_msg == gettext('Transaction ID not found in the session.'): return make_json_response(success=0, errormsg=error_msg, info='DATAGRID_TRANSACTION_REQUIRED', status=404) - if status and conn is not None \ - and trans_obj is not None and session_obj is not None: + if status and conn is not None and \ + trans_obj is not None and session_obj is not None: # If there is no primary key found then return from the function. - if (len(session_obj['primary_keys']) <= 0 or len(changed_data) <= 0) \ - and 'has_oids' not in session_obj: + if (len(session_obj['primary_keys']) <= 0 or + len(changed_data) <= 0) and \ + 'has_oids' not in session_obj: return make_json_response( data={ 'status': False, @@ -1039,13 +1033,12 @@ def get_filter(trans_id): status, error_msg, conn, trans_obj, session_obj = \ check_transaction_status(trans_id) - if error_msg == gettext( - 'Transaction ID not found in the session.'): + if error_msg == gettext('Transaction ID not found in the session.'): return make_json_response(success=0, errormsg=error_msg, info='DATAGRID_TRANSACTION_REQUIRED', status=404) - if status and conn is not None \ - and trans_obj is not None and session_obj is not None: + if status and conn is not None and \ + trans_obj is not None and session_obj is not None: res = trans_obj.get_filter() else: @@ -1076,14 +1069,13 @@ def apply_filter(trans_id): status, error_msg, conn, trans_obj, session_obj = \ check_transaction_status(trans_id) - if error_msg == gettext( - 'Transaction ID not found in the session.'): + if error_msg == gettext('Transaction ID not found in the session.'): return make_json_response(success=0, errormsg=error_msg, info='DATAGRID_TRANSACTION_REQUIRED', status=404) - if status and conn is not None \ - and trans_obj is not None and session_obj is not None: + if status and conn is not None and \ + trans_obj is not None and session_obj is not None: status, res = trans_obj.set_filter(filter_sql) @@ -1119,14 +1111,13 @@ def append_filter_inclusive(trans_id): status, error_msg, conn, trans_obj, session_obj = \ check_transaction_status(trans_id) - if error_msg == gettext( - 'Transaction ID not found in the session.'): + if error_msg == gettext('Transaction ID not found in the session.'): return make_json_response(success=0, errormsg=error_msg, info='DATAGRID_TRANSACTION_REQUIRED', status=404) - if status and conn is not None \ - and trans_obj is not None and session_obj is not None: + if status and conn is not None and \ + trans_obj is not None and session_obj is not None: res = None filter_sql = '' @@ -1175,13 +1166,12 @@ def append_filter_exclusive(trans_id): status, error_msg, conn, trans_obj, session_obj = \ check_transaction_status(trans_id) - if error_msg == gettext( - 'Transaction ID not found in the session.'): + if error_msg == gettext('Transaction ID not found in the session.'): return make_json_response(success=0, errormsg=error_msg, info='DATAGRID_TRANSACTION_REQUIRED', status=404) - if status and conn is not None \ - and trans_obj is not None and session_obj is not None: + if status and conn is not None and \ + trans_obj is not None and session_obj is not None: res = None filter_sql = '' @@ -1228,14 +1218,13 @@ def remove_filter(trans_id): status, error_msg, conn, trans_obj, session_obj = \ check_transaction_status(trans_id) - if error_msg == gettext( - 'Transaction ID not found in the session.'): + if error_msg == gettext('Transaction ID not found in the session.'): return make_json_response(success=0, errormsg=error_msg, info='DATAGRID_TRANSACTION_REQUIRED', status=404) - if status and conn is not None \ - and trans_obj is not None and session_obj is not None: + if status and conn is not None and \ + trans_obj is not None and session_obj is not None: res = None @@ -1273,14 +1262,13 @@ def set_limit(trans_id): status, error_msg, conn, trans_obj, session_obj = \ check_transaction_status(trans_id) - if error_msg == gettext( - 'Transaction ID not found in the session.'): + if error_msg == gettext('Transaction ID not found in the session.'): return make_json_response(success=0, errormsg=error_msg, info='DATAGRID_TRANSACTION_REQUIRED', status=404) - if status and conn is not None \ - and trans_obj is not None and session_obj is not None: + if status and conn is not None and \ + trans_obj is not None and session_obj is not None: res = None @@ -1394,14 +1382,13 @@ def get_object_name(trans_id): status, error_msg, conn, trans_obj, session_obj = \ check_transaction_status(trans_id) - if error_msg == gettext( - 'Transaction ID not found in the session.'): + if error_msg == gettext('Transaction ID not found in the session.'): return make_json_response(success=0, errormsg=error_msg, info='DATAGRID_TRANSACTION_REQUIRED', status=404) - if status and conn is not None \ - and trans_obj is not None and session_obj is not None: + if status and conn is not None and \ + trans_obj is not None and session_obj is not None: res = trans_obj.object_name else: status = False @@ -1431,14 +1418,13 @@ def set_auto_commit(trans_id): status, error_msg, conn, trans_obj, session_obj = \ check_transaction_status(trans_id) - if error_msg == gettext( - 'Transaction ID not found in the session.'): + if error_msg == gettext('Transaction ID not found in the session.'): return make_json_response(success=0, errormsg=error_msg, info='DATAGRID_TRANSACTION_REQUIRED', status=404) - if status and conn is not None \ - and trans_obj is not None and session_obj is not None: + if status and conn is not None and \ + trans_obj is not None and session_obj is not None: res = None @@ -1480,14 +1466,13 @@ def set_auto_rollback(trans_id): status, error_msg, conn, trans_obj, session_obj = \ check_transaction_status(trans_id) - if error_msg == gettext( - 'Transaction ID not found in the session.'): + if error_msg == gettext('Transaction ID not found in the session.'): return make_json_response(success=0, errormsg=error_msg, info='DATAGRID_TRANSACTION_REQUIRED', status=404) - if status and conn is not None \ - and trans_obj is not None and session_obj is not None: + if status and conn is not None and \ + trans_obj is not None and session_obj is not None: res = None @@ -1536,14 +1521,13 @@ def auto_complete(trans_id): status, error_msg, conn, trans_obj, session_obj = \ check_transaction_status(trans_id) - if error_msg == gettext( - 'Transaction ID not found in the session.'): + if error_msg == gettext('Transaction ID not found in the session.'): return make_json_response(success=0, errormsg=error_msg, info='DATAGRID_TRANSACTION_REQUIRED', status=404) - if status and conn is not None \ - and trans_obj is not None and session_obj is not None: + if status and conn is not None and \ + trans_obj is not None and session_obj is not None: # Create object of SQLAutoComplete class and pass connection object auto_complete_obj = SQLAutoComplete( @@ -1599,8 +1583,8 @@ def load_file(): file_path.lstrip('/').lstrip('\\') ) - status, err_msg, is_binary, \ - is_startswith_bom, enc = Filemanager.check_file_for_bom_and_binary( + (status, err_msg, is_binary, + is_startswith_bom, enc) = Filemanager.check_file_for_bom_and_binary( file_path ) @@ -1694,11 +1678,11 @@ def save_file(): @login_required def start_query_download_tool(trans_id): sync_conn = None - status, error_msg, conn, trans_obj, \ - session_obj = check_transaction_status(trans_id) + (status, error_msg, conn, trans_obj, + session_obj) = check_transaction_status(trans_id) - if status and conn is not None \ - and trans_obj is not None and session_obj is not None: + if status and conn is not None and \ + trans_obj is not None and session_obj is not None: data = request.args if request.args else None try: @@ -1797,8 +1781,8 @@ def query_tool_status(trans_id): TRANSACTION_STATUS_INERROR = 3 TRANSACTION_STATUS_UNKNOWN = 4 """ - status, error_msg, conn, trans_obj, \ - session_obj = check_transaction_status(trans_id) + (status, error_msg, conn, trans_obj, + session_obj) = check_transaction_status(trans_id) if not status and error_msg and type(error_msg) == str: return internal_server_error( diff --git a/web/pgadmin/tools/sqleditor/tests/test_explain_plan_templates.py b/web/pgadmin/tools/sqleditor/tests/test_explain_plan_templates.py index ab018788..1b3e09f5 100644 --- a/web/pgadmin/tools/sqleditor/tests/test_explain_plan_templates.py +++ b/web/pgadmin/tools/sqleditor/tests/test_explain_plan_templates.py @@ -23,19 +23,21 @@ class TestExplainPlanTemplates(BaseTestGenerator): 'when passing all parameters,' 'it returns the explain plan with all parameters', dict( - template_path=os.path.join('sqleditor', 'sql', 'default', 'explain_plan.sql'), + template_path=os.path.join('sqleditor', 'sql', 'default', + 'explain_plan.sql'), input_parameters=dict( - sql='select * from places', + sql='SELECT * FROM places', format='xml', analyze=True, verbose=True, costs=False, buffers=True ), - sql_statement='select * from places', + sql_statement='SELECT * FROM places', expected_return_value='EXPLAIN ' - '( FORMAT XML, ANALYZE True, VERBOSE True, ' - 'COSTS False, BUFFERS True) select * from places' + '( FORMAT XML, ANALYZE True, ' + 'VERBOSE True, COSTS False, ' + 'BUFFERS True) SELECT * FROM places' ) ), ( @@ -43,15 +45,17 @@ class TestExplainPlanTemplates(BaseTestGenerator): 'when not all parameters are present,' 'it returns the explain plan with the present parameters', dict( - template_path=os.path.join('sqleditor', 'sql', 'default', 'explain_plan.sql'), + template_path=os.path.join('sqleditor', 'sql', 'default', + 'explain_plan.sql'), input_parameters=dict( - sql='select * from places', + sql='SELECT * FROM places', format='json', buffers=True ), - sql_statement='select * from places', + sql_statement='SELECT * FROM places', expected_return_value='EXPLAIN ' - '( FORMAT JSON, BUFFERS True) select * from places' + '( FORMAT JSON, BUFFERS True) ' + 'SELECT * FROM places' ) ), ( @@ -59,16 +63,18 @@ class TestExplainPlanTemplates(BaseTestGenerator): 'when timing is present,' 'it returns the explain plan with timing', dict( - template_path=os.path.join('sqleditor', 'sql', '9.2_plus', 'explain_plan.sql'), + template_path=os.path.join('sqleditor', 'sql', '9.2_plus', + 'explain_plan.sql'), input_parameters=dict( - sql='select * from places', + sql='SELECT * FROM places', format='json', buffers=True, timing=False ), - sql_statement='select * from places', + sql_statement='SELECT * FROM places', expected_return_value='EXPLAIN ' - '( FORMAT JSON, TIMING False, BUFFERS True) select * from places' + '( FORMAT JSON, TIMING False, ' + 'BUFFERS True) SELECT * FROM places' ) ), ( @@ -76,17 +82,20 @@ class TestExplainPlanTemplates(BaseTestGenerator): 'when summary is present,' 'it returns the explain plan with summary', dict( - template_path=os.path.join('sqleditor', 'sql', '10_plus', 'explain_plan.sql'), + template_path=os.path.join('sqleditor', 'sql', '10_plus', + 'explain_plan.sql'), input_parameters=dict( - sql='select * from places', + sql='SELECT * FROM places', format='yaml', buffers=True, timing=False, summary=True ), - sql_statement='select * from places', + sql_statement='SELECT * FROM places', expected_return_value='EXPLAIN ' - '( FORMAT YAML, TIMING False, SUMMARY True, BUFFERS True) select * from places' + '( FORMAT YAML, TIMING False, ' + 'SUMMARY True, BUFFERS True) ' + 'SELECT * FROM places' ) ), ( @@ -94,14 +103,15 @@ class TestExplainPlanTemplates(BaseTestGenerator): 'when all parameters are present,' 'it returns the explain without parameters', dict( - template_path=os.path.join('sqleditor', 'sql', 'gpdb_5.0_plus', 'explain_plan.sql'), + template_path=os.path.join('sqleditor', 'sql', 'gpdb_5.0_plus', + 'explain_plan.sql'), input_parameters=dict( - sql='select * from places', + sql='SELECT * FROM places', format='json', buffers=True ), - sql_statement='select * from places', - expected_return_value='EXPLAIN select * from places' + sql_statement='SELECT * FROM places', + expected_return_value='EXPLAIN SELECT * FROM places' ) ), ( @@ -109,13 +119,14 @@ class TestExplainPlanTemplates(BaseTestGenerator): 'when analyze is true,' 'it returns the explain analyze', dict( - template_path=os.path.join('sqleditor', 'sql', 'gpdb_5.0_plus', 'explain_plan.sql'), + template_path=os.path.join('sqleditor', 'sql', 'gpdb_5.0_plus', + 'explain_plan.sql'), input_parameters=dict( - sql='select * from places', + sql='SELECT * FROM places', analyze=True ), - sql_statement='select * from places', - expected_return_value='EXPLAIN ANALYZE select * from places' + sql_statement='SELECT * FROM places', + expected_return_value='EXPLAIN ANALYZE SELECT * FROM places' ) ), ( @@ -123,13 +134,14 @@ class TestExplainPlanTemplates(BaseTestGenerator): 'when analyze is false,' 'it returns the only explain', dict( - template_path=os.path.join('sqleditor', 'sql', 'gpdb_5.0_plus', 'explain_plan.sql'), + template_path=os.path.join('sqleditor', 'sql', 'gpdb_5.0_plus', + 'explain_plan.sql'), input_parameters=dict( - sql='select * from places', + sql='SELECT * FROM places', analyze=False ), - sql_statement='select * from places', - expected_return_value='EXPLAIN select * from places' + sql_statement='SELECT * FROM places', + expected_return_value='EXPLAIN SELECT * FROM places' ) ), ] @@ -139,7 +151,8 @@ class TestExplainPlanTemplates(BaseTestGenerator): def runTest(self): with FakeApp().app_context(): - result = render_template(self.template_path, **self.input_parameters) + result = render_template(self.template_path, + **self.input_parameters) self.assertEqual( str(result).replace("\n", ""), self.expected_return_value) diff --git a/web/pgadmin/tools/sqleditor/tests/test_extract_sql_from_network_parameters.py b/web/pgadmin/tools/sqleditor/tests/test_extract_sql_from_network_parameters.py index c4e002cc..beca1657 100644 --- a/web/pgadmin/tools/sqleditor/tests/test_extract_sql_from_network_parameters.py +++ b/web/pgadmin/tools/sqleditor/tests/test_extract_sql_from_network_parameters.py @@ -29,7 +29,10 @@ class ExtractSQLFromNetworkParametersTest(BaseTestGenerator): expected_result=dict(sql='some sql', explain_plan=None) )), ('Payload that requests explain plan using json', dict( - request_strigified_data='{"sql": "some sql", "explain_plan": {"format": "json", "analyze": false, "verbose": false, "costs": false, "buffers": false, "timing": false}}', + request_strigified_data='{"sql": "some sql", "explain_plan": ' + '{"format": "json", "analyze": false, ' + '"verbose": false, "costs": false, ' + '"buffers": false, "timing": false}}', request_arguments=ImmutableMultiDict(), request_form_data=ImmutableMultiDict(), diff --git a/web/pgadmin/tools/sqleditor/tests/test_start_query_tool.py b/web/pgadmin/tools/sqleditor/tests/test_start_query_tool.py index 18624087..2a50259a 100644 --- a/web/pgadmin/tools/sqleditor/tests/test_start_query_tool.py +++ b/web/pgadmin/tools/sqleditor/tests/test_start_query_tool.py @@ -27,12 +27,21 @@ class StartQueryTool(BaseTestGenerator): def runTest(self, extract_sql_from_network_parameters_mock): """Check correct function is called to handle to run query.""" - extract_sql_from_network_parameters_mock.return_value = 'transformed sql' - - with patch.object(StartRunningQuery, 'execute', return_value='some result') as StartRunningQuery_execute_mock: - response = self.tester.post('/sqleditor/query_tool/start/1234', data='"some sql statement"') + extract_sql_from_network_parameters_mock.return_value = \ + 'transformed sql' + + with patch.object(StartRunningQuery, + 'execute', + return_value='some result' + ) as StartRunningQuery_execute_mock: + response = self.tester.post( + '/sqleditor/query_tool/start/1234', + data='"some sql statement"' + ) self.assertEquals(response.status, '200 OK') self.assertEquals(response.data, b'some result') - StartRunningQuery_execute_mock.assert_called_with('transformed sql', 1234, ANY) - extract_sql_from_network_parameters_mock.assert_called_with(b'"some sql statement"', ANY, ANY) + StartRunningQuery_execute_mock \ + .assert_called_with('transformed sql', 1234, ANY) + extract_sql_from_network_parameters_mock \ + .assert_called_with(b'"some sql statement"', ANY, ANY) diff --git a/web/pgadmin/tools/sqleditor/utils/apply_explain_plan_wrapper.py b/web/pgadmin/tools/sqleditor/utils/apply_explain_plan_wrapper.py index 84e478de..c32ed00b 100644 --- a/web/pgadmin/tools/sqleditor/utils/apply_explain_plan_wrapper.py +++ b/web/pgadmin/tools/sqleditor/utils/apply_explain_plan_wrapper.py @@ -18,7 +18,12 @@ def apply_explain_plan_wrapper_if_needed(manager, sql): explain_plan = sql['explain_plan'] ver = manager.version server_type = manager.server_type - template_path = compile_template_name('sqleditor/sql', 'explain_plan.sql', server_type, ver) + template_path = compile_template_name( + 'sqleditor/sql', + 'explain_plan.sql', + server_type, + ver + ) return render_template(template_path, sql=sql['sql'], **explain_plan) else: return sql['sql'] diff --git a/web/pgadmin/tools/sqleditor/utils/start_running_query.py b/web/pgadmin/tools/sqleditor/utils/start_running_query.py index f5e1feae..11b946b5 100644 --- a/web/pgadmin/tools/sqleditor/utils/start_running_query.py +++ b/web/pgadmin/tools/sqleditor/utils/start_running_query.py @@ -16,11 +16,13 @@ from flask import Response from flask_babel import gettext from config import PG_DEFAULT_DRIVER -from pgadmin.tools.sqleditor.utils.apply_explain_plan_wrapper import apply_explain_plan_wrapper_if_needed -from pgadmin.tools.sqleditor.utils.update_session_grid_transaction import update_session_grid_transaction +from pgadmin.tools.sqleditor.utils.apply_explain_plan_wrapper import \ + apply_explain_plan_wrapper_if_needed +from pgadmin.tools.sqleditor.utils.constant_definition import TX_STATUS_IDLE, \ + TX_STATUS_INERROR from pgadmin.tools.sqleditor.utils.is_begin_required import is_begin_required -from pgadmin.tools.sqleditor.utils.constant_definition import TX_STATUS_IDLE, TX_STATUS_INERROR - +from pgadmin.tools.sqleditor.utils.update_session_grid_transaction import \ + update_session_grid_transaction from pgadmin.utils.ajax import make_json_response, internal_server_error from pgadmin.utils.driver import get_driver from pgadmin.utils.exception import ConnectionLost @@ -35,7 +37,10 @@ class StartRunningQuery: self.logger = logger def execute(self, sql, trans_id, http_session): - session_obj = StartRunningQuery.retrieve_session_information(http_session, trans_id) + session_obj = StartRunningQuery.retrieve_session_information( + http_session, + trans_id + ) if type(session_obj) is Response: return session_obj @@ -49,8 +54,10 @@ class StartRunningQuery: try: manager = get_driver( - PG_DEFAULT_DRIVER).connection_manager(transaction_object.sid) - conn = manager.connection(did=transaction_object.did, conn_id=self.connection_id, + PG_DEFAULT_DRIVER).connection_manager( + transaction_object.sid) + conn = manager.connection(did=transaction_object.did, + conn_id=self.connection_id, auto_reconnect=False, use_binary_placeholder=True, array_to_string=True) @@ -67,7 +74,8 @@ class StartRunningQuery: self.logger.error(msg) return internal_server_error(errormsg=str(msg)) - effective_sql_statement = apply_explain_plan_wrapper_if_needed(manager, sql) + effective_sql_statement = apply_explain_plan_wrapper_if_needed( + manager, sql) result, status = self.__execute_query( conn, @@ -88,7 +96,8 @@ class StartRunningQuery: data={ 'status': status, 'result': result, 'can_edit': can_edit, 'can_filter': can_filter, - 'info_notifier_timeout': self.blueprint_object.info_notifier_timeout.get() + 'info_notifier_timeout': + self.blueprint_object.info_notifier_timeout.get() } ) @@ -104,13 +113,15 @@ class StartRunningQuery: # transaction object trans_obj.set_connection_id(self.connection_id) - StartRunningQuery.save_transaction_in_session(session_obj, trans_id, trans_obj) + StartRunningQuery.save_transaction_in_session(session_obj, + trans_id, trans_obj) # If auto commit is False and transaction status is Idle # then call is_begin_not_required() function to check BEGIN # is required or not. - if StartRunningQuery.is_begin_required_for_sql_query(trans_obj, conn, sql): + if StartRunningQuery.is_begin_required_for_sql_query(trans_obj, + conn, sql): conn.execute_void("BEGIN;") # Execute sql asynchronously with params is None @@ -122,7 +133,8 @@ class StartRunningQuery: # If the transaction aborted for some reason and # Auto RollBack is True then issue a rollback to cleanup. - if StartRunningQuery.is_rollback_statement_required(trans_obj, conn): + if StartRunningQuery.is_rollback_statement_required(trans_obj, + conn): conn.execute_void("ROLLBACK;") else: status = False @@ -133,13 +145,17 @@ class StartRunningQuery: @staticmethod def is_begin_required_for_sql_query(trans_obj, conn, sql): - return not trans_obj.auto_commit \ - and conn.transaction_status() == TX_STATUS_IDLE \ - and is_begin_required(sql) + return (not trans_obj.auto_commit and + conn.transaction_status() == TX_STATUS_IDLE and + is_begin_required(sql) + ) @staticmethod def is_rollback_statement_required(trans_obj, conn): - return conn.transaction_status() == TX_STATUS_INERROR and trans_obj.auto_rollback + return ( + conn.transaction_status() == TX_STATUS_INERROR and + trans_obj.auto_rollback + ) @staticmethod def save_transaction_in_session(session, transaction_id, transaction): @@ -168,5 +184,3 @@ class StartRunningQuery: # Fetch the object for the specified transaction id. # Use pickle.loads function to get the command object return grid_data[str(transaction_id)] - - diff --git a/web/pgadmin/tools/sqleditor/utils/tests/test_apply_explain_plan_wrapper.py b/web/pgadmin/tools/sqleditor/utils/tests/test_apply_explain_plan_wrapper.py index 6cf320eb..6a96220f 100644 --- a/web/pgadmin/tools/sqleditor/utils/tests/test_apply_explain_plan_wrapper.py +++ b/web/pgadmin/tools/sqleditor/utils/tests/test_apply_explain_plan_wrapper.py @@ -21,7 +21,8 @@ else: class StartRunningQueryTest(BaseTestGenerator): """ - Check that the apply_explain_plan_weapper_if_needed method works as intended + Check that the StartRunningQueryTest method works as + intended """ scenarios = [ ('When explain_plan is none, it should return unaltered SQL', dict( @@ -37,85 +38,98 @@ class StartRunningQueryTest(BaseTestGenerator): expected_return_value='some sql' )), - ('When explain_plan is not present, it should return unaltered SQL', dict( - function_input_parameters={ - 'manager': MagicMock(), - 'sql': { - 'sql': 'some sql' - } - }, + ('When explain_plan is not present, it should return unaltered SQL', + dict( + function_input_parameters={ + 'manager': MagicMock(), + 'sql': { + 'sql': 'some sql' + } + }, - expect_render_template_mock_parameters=None, + expect_render_template_mock_parameters=None, - expected_return_value='some sql' - )), - ('When explain_plan is present for a Postgres server version 10, it should return SQL with explain plan', dict( - function_input_parameters={ - 'manager': MagicMock(version=10, server_type='pg'), - 'sql': { - 'sql': 'some sql', - 'explain_plan': { - 'format': 'json', - 'analyze': False, - 'verbose': True, - 'buffers': False, - 'timing': True - } - } - }, + expected_return_value='some sql' + )), + ('When explain_plan is present for a Postgres server version 10, ' + 'it should return SQL with explain plan', + dict( + function_input_parameters={ + 'manager': MagicMock(version=10, server_type='pg'), + 'sql': { + 'sql': 'some sql', + 'explain_plan': { + 'format': 'json', + 'analyze': False, + 'verbose': True, + 'buffers': False, + 'timing': True + } + } + }, - expect_render_template_mock_parameters=dict( - template_name_or_list='sqleditor/sql/#10#/explain_plan.sql', - named_parameters=dict( - format='json', - analyze=False, - verbose=True, - buffers=False, - timing=True - )), + expect_render_template_mock_parameters=dict( + template_name_or_list='sqleditor/sql/#10#/explain_plan.sql', + named_parameters=dict( + format='json', + analyze=False, + verbose=True, + buffers=False, + timing=True + )), - expected_return_value='EXPLAIN (FORMAT JSON, ANALYZE FALSE, VERBOSE TRUE, COSTS FALSE, BUFFERS FALSE, ' - 'TIMING TRUE) some sql' - )), - ('When explain_plan is present for a GreenPlum server version 5, it should return SQL with explain plan', dict( - function_input_parameters={ - 'manager': MagicMock(version=80323, server_type='gpdb'), - 'sql': { - 'sql': 'some sql', - 'explain_plan': { - 'format': 'json', - 'analyze': False, - 'verbose': True, - 'buffers': False, - 'timing': True - } - } - }, + expected_return_value='EXPLAIN (FORMAT JSON, ANALYZE FALSE, ' + 'VERBOSE TRUE, COSTS FALSE, BUFFERS FALSE, ' + 'TIMING TRUE) some sql' + )), + ('When explain_plan is present for a GreenPlum server version 5, ' + 'it should return SQL with explain plan', + dict( + function_input_parameters={ + 'manager': MagicMock(version=80323, server_type='gpdb'), + 'sql': { + 'sql': 'some sql', + 'explain_plan': { + 'format': 'json', + 'analyze': False, + 'verbose': True, + 'buffers': False, + 'timing': True + } + } + }, - expect_render_template_mock_parameters=dict( - template_name_or_list='sqleditor/sql/#gpdb#80323#/explain_plan.sql', - named_parameters=dict( - format='json', - analyze=False, - verbose=True, - buffers=False, - timing=True - )), + expect_render_template_mock_parameters=dict( + template_name_or_list='sqleditor/sql/#gpdb#80323#/' + 'explain_plan.sql', + named_parameters=dict( + format='json', + analyze=False, + verbose=True, + buffers=False, + timing=True + )), - expected_return_value='EXPLAIN some sql' - )) + expected_return_value='EXPLAIN some sql' + )) ] def runTest(self): - with patch('pgadmin.tools.sqleditor.utils.apply_explain_plan_wrapper.render_template') as render_template_mock: + with patch( + 'pgadmin.tools.sqleditor.utils.apply_explain_plan_wrapper' + '.render_template' + ) as render_template_mock: render_template_mock.return_value = self.expected_return_value - result = apply_explain_plan_wrapper_if_needed(**self.function_input_parameters) + result = apply_explain_plan_wrapper_if_needed( + **self.function_input_parameters) self.assertEquals(result, self.expected_return_value) if self.expect_render_template_mock_parameters: render_template_mock.assert_called_with( - self.expect_render_template_mock_parameters['template_name_or_list'], + self.expect_render_template_mock_parameters[ + 'template_name_or_list'], sql=self.function_input_parameters['sql']['sql'], - **self.expect_render_template_mock_parameters['named_parameters'] + **self.expect_render_template_mock_parameters[ + 'named_parameters'] ) else: render_template_mock.assert_not_called() diff --git a/web/pgadmin/tools/sqleditor/utils/tests/test_start_running_query.py b/web/pgadmin/tools/sqleditor/utils/tests/test_start_running_query.py index d53c0248..f095f48e 100644 --- a/web/pgadmin/tools/sqleditor/utils/tests/test_start_running_query.py +++ b/web/pgadmin/tools/sqleditor/utils/tests/test_start_running_query.py @@ -29,353 +29,405 @@ class StartRunningQueryTest(BaseTestGenerator): """ scenarios = [ - ('When gridData is not present in the session, it returns an error', dict( - function_parameters=dict( - sql=dict(sql='some sql', explain_plan=None), - trans_id=123, - http_session=dict() - ), - pickle_load_return=None, - get_driver_exception=False, - manager_connection_exception=None, - - is_connected_to_server=False, - connection_connect_return=None, - execute_async_return_value=None, - is_begin_required=False, - is_rollback_required=False, - apply_explain_plan_wrapper_if_needed_return_value='some sql', - - expect_make_json_response_to_have_been_called_with=dict( - success=0, - errormsg='Transaction ID not found in the session.', - info='DATAGRID_TRANSACTION_REQUIRED', - status=404, - ), - expect_internal_server_error_to_have_been_called_with=None, - expected_logger_error=None, - expect_execute_void_called_with='some sql', - )), - ('When transactionId is not present in the gridData, it returns an error', dict( - function_parameters=dict( - sql=dict(sql='some sql', explain_plan=None), - trans_id=123, - http_session=dict(gridData=dict()) - ), - pickle_load_return=None, - get_driver_exception=False, - manager_connection_exception=None, - - is_connected_to_server=False, - connection_connect_return=None, - execute_async_return_value=None, - is_begin_required=False, - is_rollback_required=False, - apply_explain_plan_wrapper_if_needed_return_value='some sql', - - expect_make_json_response_to_have_been_called_with=dict( - success=0, - errormsg='Transaction ID not found in the session.', - info='DATAGRID_TRANSACTION_REQUIRED', - status=404, - ), - expect_internal_server_error_to_have_been_called_with=None, - expected_logger_error=None, - expect_execute_void_called_with='some sql', - )), - ('When the command information for the transaction cannot be retrieved, it returns an error', dict( - function_parameters=dict( - sql=dict(sql='some sql', explain_plan=None), - trans_id=123, - http_session=dict(gridData={'123': dict(command_obj='')}) - ), - pickle_load_return=None, - get_driver_exception=False, - manager_connection_exception=None, - - is_connected_to_server=False, - connection_connect_return=None, - execute_async_return_value=None, - is_begin_required=False, - is_rollback_required=False, - apply_explain_plan_wrapper_if_needed_return_value='some sql', - - expect_make_json_response_to_have_been_called_with=dict( - data=dict( - status=False, - result='Either transaction object or session object not found.', - can_edit=False, - can_filter=False, - info_notifier_timeout=5 - ) - ), - expect_internal_server_error_to_have_been_called_with=None, - expected_logger_error=None, - expect_execute_void_called_with='some sql', - )), - ('When exception happens while retrieving the database driver, it returns an error', dict( - function_parameters=dict( - sql=dict(sql='some sql', explain_plan=None), - trans_id=123, - http_session=dict(gridData={'123': dict(command_obj='')}) - ), - pickle_load_return=MagicMock(conn_id=1, update_fetched_row_cnt=MagicMock()), - get_driver_exception=True, - manager_connection_exception=None, - - is_connected_to_server=False, - connection_connect_return=None, - execute_async_return_value=None, - is_begin_required=False, - is_rollback_required=False, - apply_explain_plan_wrapper_if_needed_return_value='some sql', - - expect_make_json_response_to_have_been_called_with=None, - expect_internal_server_error_to_have_been_called_with=dict( - errormsg='get_driver exception' - ), - expected_logger_error=get_driver_exception, - expect_execute_void_called_with='some sql', - )), - ('When ConnectionLost happens while retrieving the database connection, it returns an error', dict( - function_parameters=dict( - sql=dict(sql='some sql', explain_plan=None), - trans_id=123, - http_session=dict(gridData={'123': dict(command_obj='')}) - ), - pickle_load_return=MagicMock(conn_id=1, update_fetched_row_cnt=MagicMock()), - get_driver_exception=False, - manager_connection_exception=ConnectionLost('1', '2', '3'), - - is_connected_to_server=False, - connection_connect_return=None, - execute_async_return_value=None, - is_begin_required=False, - is_rollback_required=False, - apply_explain_plan_wrapper_if_needed_return_value='some sql', - - expect_make_json_response_to_have_been_called_with=None, - expect_internal_server_error_to_have_been_called_with=None, - expected_logger_error=None, - expect_execute_void_called_with='some sql', - )), - ('When is not connected to the server and fails to connect, it returns an error', dict( - function_parameters=dict( - sql=dict(sql='some sql', explain_plan=None), - trans_id=123, - http_session=dict(gridData={'123': dict(command_obj='')}) - ), - pickle_load_return=MagicMock(conn_id=1, update_fetched_row_cnt=MagicMock()), - get_driver_exception=False, - manager_connection_exception=None, - - is_connected_to_server=False, - connection_connect_return=[False, 'Unable to connect to server'], - execute_async_return_value=None, - is_begin_required=False, - is_rollback_required=False, - apply_explain_plan_wrapper_if_needed_return_value='some sql', - - expect_make_json_response_to_have_been_called_with=None, - expect_internal_server_error_to_have_been_called_with=dict( - errormsg='Unable to connect to server' - ), - expected_logger_error='Unable to connect to server', - expect_execute_void_called_with='some sql', - )), - ('When server is connected and start query async request, it returns an success message', dict( - function_parameters=dict( - sql=dict(sql='some sql', explain_plan=None), - trans_id=123, - http_session=dict(gridData={'123': dict(command_obj='')}) - ), - pickle_load_return=MagicMock( - conn_id=1, - update_fetched_row_cnt=MagicMock(), - set_connection_id=MagicMock(), - auto_commit=True, - auto_rollback=False, - can_edit=lambda: True, - can_filter=lambda: True - ), - get_driver_exception=False, - manager_connection_exception=None, - - is_connected_to_server=True, - connection_connect_return=None, - execute_async_return_value=[True, 'async function result output'], - is_begin_required=False, - is_rollback_required=False, - apply_explain_plan_wrapper_if_needed_return_value='some sql', - - expect_make_json_response_to_have_been_called_with=dict( - data=dict( - status=True, - result='async function result output', - can_edit=True, - can_filter=True, - info_notifier_timeout=5 - ) - ), - expect_internal_server_error_to_have_been_called_with=None, - expected_logger_error=None, - expect_execute_void_called_with='some sql', - )), - ('When server is connected and start query async request and begin is required, ' - 'it returns an success message', dict( - function_parameters=dict( - sql=dict(sql='some sql', explain_plan=None), - trans_id=123, - http_session=dict(gridData={'123': dict(command_obj='')}) - ), - pickle_load_return=MagicMock( - conn_id=1, - update_fetched_row_cnt=MagicMock(), - set_connection_id=MagicMock(), - auto_commit=True, - auto_rollback=False, - can_edit=lambda: True, - can_filter=lambda: True - ), - get_driver_exception=False, - manager_connection_exception=None, - - is_connected_to_server=True, - connection_connect_return=None, - execute_async_return_value=[True, 'async function result output'], - is_begin_required=True, - is_rollback_required=False, - apply_explain_plan_wrapper_if_needed_return_value='some sql', - - expect_make_json_response_to_have_been_called_with=dict( - data=dict( - status=True, - result='async function result output', - can_edit=True, - can_filter=True, - info_notifier_timeout=5 - ) - ), - expect_internal_server_error_to_have_been_called_with=None, - expected_logger_error=None, - expect_execute_void_called_with='some sql', - )), - ('When server is connected and start query async request and rollback is required, ' - 'it returns an success message', dict( - function_parameters=dict( - sql=dict(sql='some sql', explain_plan=None), - trans_id=123, - http_session=dict(gridData={'123': dict(command_obj='')}) - ), - pickle_load_return=MagicMock( - conn_id=1, - update_fetched_row_cnt=MagicMock(), - set_connection_id=MagicMock(), - auto_commit=True, - auto_rollback=False, - can_edit=lambda: True, - can_filter=lambda: True - ), - get_driver_exception=False, - manager_connection_exception=None, - - is_connected_to_server=True, - connection_connect_return=None, - execute_async_return_value=[True, 'async function result output'], - is_begin_required=False, - is_rollback_required=True, - apply_explain_plan_wrapper_if_needed_return_value='some sql', - - expect_make_json_response_to_have_been_called_with=dict( - data=dict( - status=True, - result='async function result output', - can_edit=True, - can_filter=True, - info_notifier_timeout=5 - ) - ), - expect_internal_server_error_to_have_been_called_with=None, - expected_logger_error=None, - expect_execute_void_called_with='some sql', - )), - ('When server is connected and start query async request with explain plan wrapper, ' - 'it returns an success message', dict( - function_parameters=dict( - sql=dict(sql='some sql', explain_plan=None), - trans_id=123, - http_session=dict(gridData={'123': dict(command_obj='')}) - ), - pickle_load_return=MagicMock( - conn_id=1, - update_fetched_row_cnt=MagicMock(), - set_connection_id=MagicMock(), - auto_commit=True, - auto_rollback=False, - can_edit=lambda: True, - can_filter=lambda: True - ), - get_driver_exception=False, - manager_connection_exception=None, - - is_connected_to_server=True, - connection_connect_return=None, - execute_async_return_value=[True, 'async function result output'], - is_begin_required=False, - is_rollback_required=True, - apply_explain_plan_wrapper_if_needed_return_value='EXPLAIN PLAN some sql', - - expect_make_json_response_to_have_been_called_with=dict( - data=dict( - status=True, - result='async function result output', - can_edit=True, - can_filter=True, - info_notifier_timeout=5 - ) - ), - expect_internal_server_error_to_have_been_called_with=None, - expected_logger_error=None, - expect_execute_void_called_with='EXPLAIN PLAN some sql', - )), + ('When gridData is not present in the session, it returns an error', + dict( + function_parameters=dict( + sql=dict(sql='some sql', explain_plan=None), + trans_id=123, + http_session=dict() + ), + pickle_load_return=None, + get_driver_exception=False, + manager_connection_exception=None, + + is_connected_to_server=False, + connection_connect_return=None, + execute_async_return_value=None, + is_begin_required=False, + is_rollback_required=False, + apply_explain_plan_wrapper_if_needed_return_value='some sql', + + expect_make_json_response_to_have_been_called_with=dict( + success=0, + errormsg='Transaction ID not found in the session.', + info='DATAGRID_TRANSACTION_REQUIRED', + status=404, + ), + expect_internal_server_error_called_with=None, + expected_logger_error=None, + expect_execute_void_called_with='some sql', + )), + ('When transactionId is not present in the gridData, ' + 'it returns an error', + dict( + function_parameters=dict( + sql=dict(sql='some sql', explain_plan=None), + trans_id=123, + http_session=dict(gridData=dict()) + ), + pickle_load_return=None, + get_driver_exception=False, + manager_connection_exception=None, + + is_connected_to_server=False, + connection_connect_return=None, + execute_async_return_value=None, + is_begin_required=False, + is_rollback_required=False, + apply_explain_plan_wrapper_if_needed_return_value='some sql', + + expect_make_json_response_to_have_been_called_with=dict( + success=0, + errormsg='Transaction ID not found in the session.', + info='DATAGRID_TRANSACTION_REQUIRED', + status=404, + ), + expect_internal_server_error_called_with=None, + expected_logger_error=None, + expect_execute_void_called_with='some sql', + )), + ('When the command information for the transaction ' + 'cannot be retrieved, ' + 'it returns an error', + dict( + function_parameters=dict( + sql=dict(sql='some sql', explain_plan=None), + trans_id=123, + http_session=dict(gridData={'123': dict(command_obj='')}) + ), + pickle_load_return=None, + get_driver_exception=False, + manager_connection_exception=None, + + is_connected_to_server=False, + connection_connect_return=None, + execute_async_return_value=None, + is_begin_required=False, + is_rollback_required=False, + apply_explain_plan_wrapper_if_needed_return_value='some sql', + + expect_make_json_response_to_have_been_called_with=dict( + data=dict( + status=False, + result='Either transaction object or session object ' + 'not found.', + can_edit=False, + can_filter=False, + info_notifier_timeout=5 + ) + ), + expect_internal_server_error_called_with=None, + expected_logger_error=None, + expect_execute_void_called_with='some sql', + )), + ('When exception happens while retrieving the database driver, ' + 'it returns an error', + dict( + function_parameters=dict( + sql=dict(sql='some sql', explain_plan=None), + trans_id=123, + http_session=dict(gridData={'123': dict(command_obj='')}) + ), + pickle_load_return=MagicMock(conn_id=1, + update_fetched_row_cnt=MagicMock()), + get_driver_exception=True, + manager_connection_exception=None, + + is_connected_to_server=False, + connection_connect_return=None, + execute_async_return_value=None, + is_begin_required=False, + is_rollback_required=False, + apply_explain_plan_wrapper_if_needed_return_value='some sql', + + expect_make_json_response_to_have_been_called_with=None, + expect_internal_server_error_called_with=dict( + errormsg='get_driver exception' + ), + expected_logger_error=get_driver_exception, + expect_execute_void_called_with='some sql', + )), + ('When ConnectionLost happens while retrieving the ' + 'database connection, ' + 'it returns an error', + dict( + function_parameters=dict( + sql=dict(sql='some sql', explain_plan=None), + trans_id=123, + http_session=dict(gridData={'123': dict(command_obj='')}) + ), + pickle_load_return=MagicMock( + conn_id=1, + update_fetched_row_cnt=MagicMock() + ), + get_driver_exception=False, + manager_connection_exception=ConnectionLost('1', '2', '3'), + + is_connected_to_server=False, + connection_connect_return=None, + execute_async_return_value=None, + is_begin_required=False, + is_rollback_required=False, + apply_explain_plan_wrapper_if_needed_return_value='some sql', + + expect_make_json_response_to_have_been_called_with=None, + expect_internal_server_error_called_with=None, + expected_logger_error=None, + expect_execute_void_called_with='some sql', + )), + ('When is not connected to the server and fails to connect, ' + 'it returns an error', + dict( + function_parameters=dict( + sql=dict(sql='some sql', explain_plan=None), + trans_id=123, + http_session=dict(gridData={'123': dict(command_obj='')}) + ), + pickle_load_return=MagicMock( + conn_id=1, + update_fetched_row_cnt=MagicMock() + ), + get_driver_exception=False, + manager_connection_exception=None, + + is_connected_to_server=False, + connection_connect_return=[False, + 'Unable to connect to server'], + execute_async_return_value=None, + is_begin_required=False, + is_rollback_required=False, + apply_explain_plan_wrapper_if_needed_return_value='some sql', + + expect_make_json_response_to_have_been_called_with=None, + expect_internal_server_error_called_with=dict( + errormsg='Unable to connect to server' + ), + expected_logger_error='Unable to connect to server', + expect_execute_void_called_with='some sql', + )), + ('When server is connected and start query async request, ' + 'it returns an success message', + dict( + function_parameters=dict( + sql=dict(sql='some sql', explain_plan=None), + trans_id=123, + http_session=dict(gridData={'123': dict(command_obj='')}) + ), + pickle_load_return=MagicMock( + conn_id=1, + update_fetched_row_cnt=MagicMock(), + set_connection_id=MagicMock(), + auto_commit=True, + auto_rollback=False, + can_edit=lambda: True, + can_filter=lambda: True + ), + get_driver_exception=False, + manager_connection_exception=None, + + is_connected_to_server=True, + connection_connect_return=None, + execute_async_return_value=[True, + 'async function result output'], + is_begin_required=False, + is_rollback_required=False, + apply_explain_plan_wrapper_if_needed_return_value='some sql', + + expect_make_json_response_to_have_been_called_with=dict( + data=dict( + status=True, + result='async function result output', + can_edit=True, + can_filter=True, + info_notifier_timeout=5 + ) + ), + expect_internal_server_error_called_with=None, + expected_logger_error=None, + expect_execute_void_called_with='some sql', + )), + ('When server is connected and start query async request and ' + 'begin is required, ' + 'it returns an success message', + dict( + function_parameters=dict( + sql=dict(sql='some sql', explain_plan=None), + trans_id=123, + http_session=dict(gridData={'123': dict(command_obj='')}) + ), + pickle_load_return=MagicMock( + conn_id=1, + update_fetched_row_cnt=MagicMock(), + set_connection_id=MagicMock(), + auto_commit=True, + auto_rollback=False, + can_edit=lambda: True, + can_filter=lambda: True + ), + get_driver_exception=False, + manager_connection_exception=None, + + is_connected_to_server=True, + connection_connect_return=None, + execute_async_return_value=[True, + 'async function result output'], + is_begin_required=True, + is_rollback_required=False, + apply_explain_plan_wrapper_if_needed_return_value='some sql', + + expect_make_json_response_to_have_been_called_with=dict( + data=dict( + status=True, + result='async function result output', + can_edit=True, + can_filter=True, + info_notifier_timeout=5 + ) + ), + expect_internal_server_error_called_with=None, + expected_logger_error=None, + expect_execute_void_called_with='some sql', + )), + ('When server is connected and start query async request and ' + 'rollback is required, ' + 'it returns an success message', + dict( + function_parameters=dict( + sql=dict(sql='some sql', explain_plan=None), + trans_id=123, + http_session=dict(gridData={'123': dict(command_obj='')}) + ), + pickle_load_return=MagicMock( + conn_id=1, + update_fetched_row_cnt=MagicMock(), + set_connection_id=MagicMock(), + auto_commit=True, + auto_rollback=False, + can_edit=lambda: True, + can_filter=lambda: True + ), + get_driver_exception=False, + manager_connection_exception=None, + + is_connected_to_server=True, + connection_connect_return=None, + execute_async_return_value=[True, + 'async function result output'], + is_begin_required=False, + is_rollback_required=True, + apply_explain_plan_wrapper_if_needed_return_value='some sql', + + expect_make_json_response_to_have_been_called_with=dict( + data=dict( + status=True, + result='async function result output', + can_edit=True, + can_filter=True, + info_notifier_timeout=5 + ) + ), + expect_internal_server_error_called_with=None, + expected_logger_error=None, + expect_execute_void_called_with='some sql', + )), + ('When server is connected and start query async request with ' + 'explain plan wrapper, ' + 'it returns an success message', + dict( + function_parameters=dict( + sql=dict(sql='some sql', explain_plan=None), + trans_id=123, + http_session=dict(gridData={'123': dict(command_obj='')}) + ), + pickle_load_return=MagicMock( + conn_id=1, + update_fetched_row_cnt=MagicMock(), + set_connection_id=MagicMock(), + auto_commit=True, + auto_rollback=False, + can_edit=lambda: True, + can_filter=lambda: True + ), + get_driver_exception=False, + manager_connection_exception=None, + + is_connected_to_server=True, + connection_connect_return=None, + execute_async_return_value=[True, + 'async function result output'], + is_begin_required=False, + is_rollback_required=True, + apply_explain_plan_wrapper_if_needed_return_value='EXPLAIN ' + 'PLAN some sql', + + expect_make_json_response_to_have_been_called_with=dict( + data=dict( + status=True, + result='async function result output', + can_edit=True, + can_filter=True, + info_notifier_timeout=5 + ) + ), + expect_internal_server_error_called_with=None, + expected_logger_error=None, + expect_execute_void_called_with='EXPLAIN PLAN some sql', + )), ] - @patch('pgadmin.tools.sqleditor.utils.start_running_query.apply_explain_plan_wrapper_if_needed') - @patch('pgadmin.tools.sqleditor.utils.start_running_query.make_json_response') + @patch('pgadmin.tools.sqleditor.utils.start_running_query' + '.apply_explain_plan_wrapper_if_needed') + @patch('pgadmin.tools.sqleditor.utils.start_running_query' + '.make_json_response') @patch('pgadmin.tools.sqleditor.utils.start_running_query.pickle') @patch('pgadmin.tools.sqleditor.utils.start_running_query.get_driver') - @patch('pgadmin.tools.sqleditor.utils.start_running_query.internal_server_error') - @patch('pgadmin.tools.sqleditor.utils.start_running_query.update_session_grid_transaction') + @patch('pgadmin.tools.sqleditor.utils.start_running_query' + '.internal_server_error') + @patch('pgadmin.tools.sqleditor.utils.start_running_query' + '.update_session_grid_transaction') def runTest(self, update_session_grid_transaction_mock, internal_server_error_mock, get_driver_mock, pickle_mock, - make_json_response_mock, apply_explain_plan_wrapper_if_needed_mock): + make_json_response_mock, + apply_explain_plan_wrapper_if_needed_mock): """Check correct function is called to handle to run query.""" self.connection = None self.loggerMock = MagicMock(error=MagicMock()) - expected_response = Response(response=json.dumps({'errormsg': 'some value'})) + expected_response = Response( + response=json.dumps({'errormsg': 'some value'})) make_json_response_mock.return_value = expected_response - if self.expect_internal_server_error_to_have_been_called_with is not None: + if self.expect_internal_server_error_called_with is not None: internal_server_error_mock.return_value = expected_response pickle_mock.loads.return_value = self.pickle_load_return - blueprint_mock = MagicMock(info_notifier_timeout=MagicMock(get=lambda: 5)) + blueprint_mock = MagicMock( + info_notifier_timeout=MagicMock(get=lambda: 5)) if self.is_begin_required: - StartRunningQuery.is_begin_required_for_sql_query = MagicMock(return_value=True) + StartRunningQuery.is_begin_required_for_sql_query = MagicMock( + return_value=True + ) else: - StartRunningQuery.is_begin_required_for_sql_query = MagicMock(return_value=False) + StartRunningQuery.is_begin_required_for_sql_query = MagicMock( + return_value=False + ) if self.is_rollback_required: - StartRunningQuery.is_rollback_statement_required = MagicMock(return_value=True) + StartRunningQuery.is_rollback_statement_required = MagicMock( + return_value=True + ) else: - StartRunningQuery.is_rollback_statement_required = MagicMock(return_value=False) + StartRunningQuery.is_rollback_statement_required = MagicMock( + return_value=False + ) - apply_explain_plan_wrapper_if_needed_mock.return_value = self.apply_explain_plan_wrapper_if_needed_return_value + apply_explain_plan_wrapper_if_needed_mock.return_value = \ + self.apply_explain_plan_wrapper_if_needed_return_value manager = self.__create_manager() if self.get_driver_exception: get_driver_mock.side_effect = get_driver_exception else: - get_driver_mock.return_value = MagicMock(connection_manager=lambda session_id: manager) + get_driver_mock.return_value = MagicMock( + connection_manager=lambda session_id: manager) try: result = StartRunningQuery( @@ -385,7 +437,12 @@ class StartRunningQueryTest(BaseTestGenerator): **self.function_parameters ) if self.manager_connection_exception is not None: - self.fail('Exception: "' + str(self.manager_connection_exception) + '" excepted but not raised') + self.fail( + 'Exception: "' + str( + self.manager_connection_exception + ) + + '" excepted but not raised' + ) self.assertEquals(result, expected_response) @@ -394,9 +451,11 @@ class StartRunningQueryTest(BaseTestGenerator): except Exception as exception: self.assertEquals(self.manager_connection_exception, exception) - self.__mock_assertions(internal_server_error_mock, make_json_response_mock) + self.__mock_assertions(internal_server_error_mock, + make_json_response_mock) if self.is_connected_to_server: - apply_explain_plan_wrapper_if_needed_mock.assert_called_with(manager, self.function_parameters['sql']) + apply_explain_plan_wrapper_if_needed_mock.assert_called_with( + manager, self.function_parameters['sql']) def __create_manager(self): self.connection = MagicMock( @@ -406,32 +465,50 @@ class StartRunningQueryTest(BaseTestGenerator): execute_void=MagicMock(), ) self.connection.connect.return_value = self.connection_connect_return - self.connection.execute_async.return_value = self.execute_async_return_value + self.connection.execute_async.return_value = \ + self.execute_async_return_value if self.manager_connection_exception is None: + def connection_function( + did, + conn_id, + use_binary_placeholder, + array_to_string, + auto_reconnect + ): + return self.connection + manager = MagicMock( - connection=lambda did, conn_id, use_binary_placeholder, array_to_string, auto_reconnect: self.connection + connection=connection_function ) + else: manager = MagicMock() manager.connection.side_effect = self.manager_connection_exception + return manager - def __mock_assertions(self, internal_server_error_mock, make_json_response_mock): + + def __mock_assertions(self, internal_server_error_mock, + make_json_response_mock): if self.expect_make_json_response_to_have_been_called_with is not None: - make_json_response_mock.assert_called_with(**self.expect_make_json_response_to_have_been_called_with) + make_json_response_mock.assert_called_with( + **self.expect_make_json_response_to_have_been_called_with) else: make_json_response_mock.assert_not_called() - if self.expect_internal_server_error_to_have_been_called_with is not None: - internal_server_error_mock.assert_called_with(**self.expect_internal_server_error_to_have_been_called_with) + if self.expect_internal_server_error_called_with is not None: + internal_server_error_mock.assert_called_with( + **self.expect_internal_server_error_called_with) else: internal_server_error_mock.assert_not_called() if self.execute_async_return_value is not None: - self.connection.execute_async.assert_called_with(self.expect_execute_void_called_with) + self.connection.execute_async.assert_called_with( + self.expect_execute_void_called_with) else: self.connection.execute_async.assert_not_called() if self.expected_logger_error is not None: - self.loggerMock.error.assert_called_with(self.expected_logger_error) + self.loggerMock.error.assert_called_with( + self.expected_logger_error) else: self.loggerMock.error.assert_not_called()