Add check for DELETE/UPDATE without WHERE in editor

Check the current query in the editor widget before executing for
DELETE/UPDATE without WHERE and warn the user. Make the warning
configurable.
This commit is contained in:
Lea Laux 2021-02-22 13:31:42 +01:00 committed by KDV Admin
parent e53ccdd62c
commit 2d626792b7

View File

@ -271,15 +271,17 @@ class EditorWidget(QWidget, SearchReplaceParent, metaclass=MetaEditor):
# Get the query for executing.
query_to_execute = self.get_query_in_input_editor()
# If the query is not None for an error or abort during the check process, continue.
if query_to_execute is not None:
# Define the query to execute as database query of the executor.
self.database_query_executor.database_query = query_to_execute
# Submit and execute the query with the given parameters.
self.database_query_executor.submit_and_execute_query()
def get_query_in_input_editor(self):
def get_query_in_input_editor(self, check=True):
"""
Get the current query out of the input editor. If there is a selected part of the text in the editor, then use
only the selected text as query.
only the selected text as query. Set the check to True as default, so the query is preprocessed.
"""
# If the selected text contains an empty string, there is not any selected text.
@ -287,11 +289,57 @@ class EditorWidget(QWidget, SearchReplaceParent, metaclass=MetaEditor):
# The query to execute is the whole text in the input editor.
query_to_execute = self.query_input_editor.text()
# Use the current selection in the editor.
else:
query_to_execute = self.query_input_editor.selectedText()
# If the check parameter is True, check the query.
if check is True:
# If the check returns a problem, set the query to None.
if self.check_current_query_for_single_update_delete(query_to_execute) is False:
query_to_execute = None
return query_to_execute
def check_current_query_for_single_update_delete(self, query):
"""
Check the given query for a single UPDATE or DELETE without any WHERE. This would execute the DELETE or UPDATE
for every row in the table. So this function is for warning the user in case they would like to execute such a
query.
"""
# Check the global app configurator, if the user has set the configuration to False, so they does not want any
# warnings. In this case, stop the check with a return.
if global_app_configurator.get_single_configuration("check_where") is False:
return
# Set the whole query to lower case, so it is easier to check, if there is an UPDATE or DELETE without a WHERE.
query = query.lower()
# Check the query: If the query contains a delete or an update, there could be a problem. If the query does not
# contain a where, there is a problem.
if ("delete" in query or "update" in query) and "where" not in query:
# Ask the user how to proceed.
question_message_box = QMessageBox.question(self, "Query without WHERE", "Your query contains an UPDATE"
" or a DELETE without a WHERE."
"Proceed anyway? (Ignore for "
"ignoring those warnings in "
"the future)",
QMessageBox.Yes | QMessageBox.No | QMessageBox.Ignore)
# Proceed normally for a yes.
if question_message_box == QMessageBox.Yes:
return True
# Stop the process for a no.
elif question_message_box == QMessageBox.No:
return False
# Proceed with setting the configuration and normally for an ignore.
elif question_message_box == QMessageBox.Ignore:
global_app_configurator.set_single_configuration("check_where", False)
global_app_configurator.save_configuration_data()
return True
def refresh_table_model(self, result_data_list, save_command=True):
"""
Refresh the table model with the given result data list. As default, the used command is saved.
@ -990,7 +1038,9 @@ class EditorWidget(QWidget, SearchReplaceParent, metaclass=MetaEditor):
"""
# Define a dictionary with the relevant command data. The command itself is the query text in the input editor.
command_dictionary = {"Command": self.get_query_in_input_editor(),
# The check is set to False for preventing preprocessing the query and finding problems, because they are
# currently not relevant.
command_dictionary = {"Command": self.get_query_in_input_editor(check=False),
# Get the current date and time. The date is used and the current time with hours, minutes
# and seconds.
"Time": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
@ -1072,4 +1122,3 @@ class EditorWidget(QWidget, SearchReplaceParent, metaclass=MetaEditor):
global_file_manager.commit_current_files_to_yaml()
self.close()