mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Fix a number of broken connection detection scenarios.
This commit is contained in:
@@ -298,8 +298,10 @@ def start_query_tool(trans_id):
|
||||
request.data, request.args, request.form
|
||||
)
|
||||
|
||||
connect = 'connect' in request.args and request.args['connect'] == '1'
|
||||
|
||||
return StartRunningQuery(blueprint, current_app).execute(
|
||||
sql, trans_id, session
|
||||
sql, trans_id, session, connect
|
||||
)
|
||||
|
||||
|
||||
|
@@ -1847,13 +1847,21 @@ define('tools.querytool', [
|
||||
},
|
||||
|
||||
handle_connection_lost: function(create_transaction, xhr) {
|
||||
var self= this;
|
||||
if (xhr.responseJSON.data && !xhr.responseJSON.data.conn_id) {
|
||||
/* If responseJSON is undefined then it could be object of
|
||||
* axios(Promise HTTP) response, so we should check accordingly.
|
||||
*/
|
||||
if (xhr.responseJSON !== undefined &&
|
||||
xhr.responseJSON.data && !xhr.responseJSON.data.conn_id) {
|
||||
// if conn_id is null then this is maintenance db.
|
||||
// so attempt connection connect without prompt.
|
||||
self.init_connection(create_transaction);
|
||||
this.init_connection(create_transaction);
|
||||
} else if (xhr.data !== undefined &&
|
||||
xhr.data.data && !xhr.data.data.conn_id) {
|
||||
// if conn_id is null then this is maintenance db.
|
||||
// so attempt connection connect without prompt.
|
||||
this.init_connection(create_transaction);
|
||||
} else {
|
||||
self.warn_before_continue();
|
||||
this.warn_before_continue();
|
||||
}
|
||||
},
|
||||
warn_before_continue: function() {
|
||||
@@ -3730,7 +3738,7 @@ define('tools.querytool', [
|
||||
|
||||
// This function will fetch the sql query from the text box
|
||||
// and execute the query.
|
||||
execute: function(explain_prefix) {
|
||||
execute: function(explain_prefix, shouldReconnect=false) {
|
||||
var self = this,
|
||||
sql = '';
|
||||
|
||||
@@ -3747,7 +3755,7 @@ define('tools.querytool', [
|
||||
sql = self.gridView.query_tool_obj.getValue();
|
||||
|
||||
const executeQuery = new ExecuteQuery.ExecuteQuery(this, pgAdmin.Browser.UserManagement);
|
||||
executeQuery.execute(sql, explain_prefix);
|
||||
executeQuery.execute(sql, explain_prefix, shouldReconnect);
|
||||
},
|
||||
|
||||
/* This function is used to highlight the error line and
|
||||
|
@@ -42,6 +42,6 @@ class StartQueryTool(BaseTestGenerator):
|
||||
self.assertEquals(response.status, '200 OK')
|
||||
self.assertEquals(response.data, b'some result')
|
||||
StartRunningQuery_execute_mock \
|
||||
.assert_called_with('transformed sql', 1234, ANY)
|
||||
.assert_called_with('transformed sql', 1234, ANY, False)
|
||||
extract_sql_from_network_parameters_mock \
|
||||
.assert_called_with(b'"some sql statement"', ANY, ANY)
|
||||
|
@@ -36,7 +36,7 @@ class StartRunningQuery:
|
||||
self.connection_id = str(random.randint(1, 9999999))
|
||||
self.logger = logger
|
||||
|
||||
def execute(self, sql, trans_id, http_session):
|
||||
def execute(self, sql, trans_id, http_session, connect=False):
|
||||
session_obj = StartRunningQuery.retrieve_session_information(
|
||||
http_session,
|
||||
trans_id
|
||||
@@ -68,7 +68,7 @@ class StartRunningQuery:
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
# Connect to the Server if not connected.
|
||||
if not conn.connected():
|
||||
if connect and not conn.connected():
|
||||
status, msg = conn.connect()
|
||||
if not status:
|
||||
self.logger.error(msg)
|
||||
@@ -108,39 +108,34 @@ class StartRunningQuery:
|
||||
self.connection_id = conn_id
|
||||
|
||||
def __execute_query(self, conn, session_obj, sql, trans_id, trans_obj):
|
||||
if conn.connected():
|
||||
# on successful connection set the connection id to the
|
||||
# transaction object
|
||||
trans_obj.set_connection_id(self.connection_id)
|
||||
# on successful connection set the connection id to the
|
||||
# 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 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):
|
||||
conn.execute_void("BEGIN;")
|
||||
if StartRunningQuery.is_begin_required_for_sql_query(trans_obj,
|
||||
conn, sql):
|
||||
conn.execute_void("BEGIN;")
|
||||
|
||||
# Execute sql asynchronously with params is None
|
||||
# and formatted_error is True.
|
||||
try:
|
||||
status, result = conn.execute_async(sql)
|
||||
except ConnectionLost:
|
||||
raise
|
||||
# Execute sql asynchronously with params is None
|
||||
# and formatted_error is True.
|
||||
try:
|
||||
status, result = conn.execute_async(sql)
|
||||
except ConnectionLost:
|
||||
raise
|
||||
|
||||
# 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):
|
||||
conn.execute_void("ROLLBACK;")
|
||||
|
||||
# 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):
|
||||
conn.execute_void("ROLLBACK;")
|
||||
else:
|
||||
status = False
|
||||
result = gettext(
|
||||
'Not connected to server or connection with the server has '
|
||||
'been closed.')
|
||||
return result, status
|
||||
|
||||
@staticmethod
|
||||
|
@@ -21,6 +21,7 @@ else:
|
||||
from unittest.mock import patch, MagicMock
|
||||
|
||||
get_driver_exception = Exception('get_driver exception')
|
||||
get_connection_lost_exception = Exception('Unable to connect to server')
|
||||
|
||||
|
||||
class StartRunningQueryTest(BaseTestGenerator):
|
||||
@@ -38,6 +39,7 @@ class StartRunningQueryTest(BaseTestGenerator):
|
||||
),
|
||||
pickle_load_return=None,
|
||||
get_driver_exception=False,
|
||||
get_connection_lost_exception=False,
|
||||
manager_connection_exception=None,
|
||||
|
||||
is_connected_to_server=False,
|
||||
@@ -67,6 +69,7 @@ class StartRunningQueryTest(BaseTestGenerator):
|
||||
),
|
||||
pickle_load_return=None,
|
||||
get_driver_exception=False,
|
||||
get_connection_lost_exception=False,
|
||||
manager_connection_exception=None,
|
||||
|
||||
is_connected_to_server=False,
|
||||
@@ -97,6 +100,7 @@ class StartRunningQueryTest(BaseTestGenerator):
|
||||
),
|
||||
pickle_load_return=None,
|
||||
get_driver_exception=False,
|
||||
get_connection_lost_exception=False,
|
||||
manager_connection_exception=None,
|
||||
|
||||
is_connected_to_server=False,
|
||||
@@ -131,6 +135,7 @@ class StartRunningQueryTest(BaseTestGenerator):
|
||||
pickle_load_return=MagicMock(conn_id=1,
|
||||
update_fetched_row_cnt=MagicMock()),
|
||||
get_driver_exception=True,
|
||||
get_connection_lost_exception=False,
|
||||
manager_connection_exception=None,
|
||||
|
||||
is_connected_to_server=False,
|
||||
@@ -161,6 +166,7 @@ class StartRunningQueryTest(BaseTestGenerator):
|
||||
update_fetched_row_cnt=MagicMock()
|
||||
),
|
||||
get_driver_exception=False,
|
||||
get_connection_lost_exception=False,
|
||||
manager_connection_exception=ConnectionLost('1', '2', '3'),
|
||||
|
||||
is_connected_to_server=False,
|
||||
@@ -188,6 +194,7 @@ class StartRunningQueryTest(BaseTestGenerator):
|
||||
update_fetched_row_cnt=MagicMock()
|
||||
),
|
||||
get_driver_exception=False,
|
||||
get_connection_lost_exception=True,
|
||||
manager_connection_exception=None,
|
||||
|
||||
is_connected_to_server=False,
|
||||
@@ -202,7 +209,7 @@ class StartRunningQueryTest(BaseTestGenerator):
|
||||
expect_internal_server_error_called_with=dict(
|
||||
errormsg='Unable to connect to server'
|
||||
),
|
||||
expected_logger_error='Unable to connect to server',
|
||||
expected_logger_error=get_connection_lost_exception,
|
||||
expect_execute_void_called_with='some sql',
|
||||
)),
|
||||
('When server is connected and start query async request, '
|
||||
@@ -223,6 +230,7 @@ class StartRunningQueryTest(BaseTestGenerator):
|
||||
can_filter=lambda: True
|
||||
),
|
||||
get_driver_exception=False,
|
||||
get_connection_lost_exception=False,
|
||||
manager_connection_exception=None,
|
||||
|
||||
is_connected_to_server=True,
|
||||
@@ -265,6 +273,7 @@ class StartRunningQueryTest(BaseTestGenerator):
|
||||
can_filter=lambda: True
|
||||
),
|
||||
get_driver_exception=False,
|
||||
get_connection_lost_exception=False,
|
||||
manager_connection_exception=None,
|
||||
|
||||
is_connected_to_server=True,
|
||||
@@ -307,6 +316,7 @@ class StartRunningQueryTest(BaseTestGenerator):
|
||||
can_filter=lambda: True
|
||||
),
|
||||
get_driver_exception=False,
|
||||
get_connection_lost_exception=False,
|
||||
manager_connection_exception=None,
|
||||
|
||||
is_connected_to_server=True,
|
||||
@@ -349,6 +359,7 @@ class StartRunningQueryTest(BaseTestGenerator):
|
||||
can_filter=lambda: True
|
||||
),
|
||||
get_driver_exception=False,
|
||||
get_connection_lost_exception=False,
|
||||
manager_connection_exception=None,
|
||||
|
||||
is_connected_to_server=True,
|
||||
@@ -431,6 +442,8 @@ class StartRunningQueryTest(BaseTestGenerator):
|
||||
manager = self.__create_manager()
|
||||
if self.get_driver_exception:
|
||||
get_driver_mock.side_effect = get_driver_exception
|
||||
elif self.get_connection_lost_exception:
|
||||
get_driver_mock.side_effect = get_connection_lost_exception
|
||||
else:
|
||||
get_driver_mock.return_value = MagicMock(
|
||||
connection_manager=lambda session_id: manager)
|
||||
|
@@ -130,9 +130,18 @@ define([
|
||||
},
|
||||
|
||||
is_pga_login_required(xhr) {
|
||||
return xhr.status == 401 && xhr.responseJSON &&
|
||||
/* If responseJSON is undefined then it could be object of
|
||||
* axios(Promise HTTP) response, so we should check accordingly.
|
||||
*/
|
||||
if (xhr.responseJSON === undefined && xhr.data !== undefined) {
|
||||
return xhr.status === 401 && xhr.data &&
|
||||
xhr.data.info &&
|
||||
xhr.data.info === 'PGADMIN_LOGIN_REQUIRED';
|
||||
}
|
||||
|
||||
return xhr.status === 401 && xhr.responseJSON &&
|
||||
xhr.responseJSON.info &&
|
||||
xhr.responseJSON.info == 'PGADMIN_LOGIN_REQUIRED';
|
||||
xhr.responseJSON.info === 'PGADMIN_LOGIN_REQUIRED';
|
||||
},
|
||||
|
||||
// Callback to draw pgAdmin4 login dialog.
|
||||
|
Reference in New Issue
Block a user