Add support for materializied views

Show materializied views of a database in an own dialog, available
through the context menu for database nodes.
This commit is contained in:
Lea Laux 2020-12-15 15:59:19 +01:00 committed by KDV Admin
parent 171b60f197
commit 4369650972
2 changed files with 139 additions and 0 deletions

View File

@ -0,0 +1,126 @@
import logging
from PyQt5.QtWidgets import QDialog, QGridLayout, QLabel, QTableView, QMessageBox
from pygadmin.connectionfactory import global_connection_factory
from pygadmin.database_query_executor import DatabaseQueryExecutor
from pygadmin.models.tablemodel import TableModel
from pygadmin.models.treemodel import DatabaseNode
class MaterializedViewInformationDialog(QDialog):
"""
Create a dialog for showing information about the materialized views of a database node.
"""
def __init__(self, selected_database_node):
super().__init__()
self.setModal(True)
# Continue with the normal initialization of the dialog, if the instance is correct.
if isinstance(selected_database_node, DatabaseNode):
self.selected_node = selected_database_node
self.init_ui()
self.init_grid()
# Show an error in the log and the UI.
else:
logging.error("The given node {} is not a Table, View or Database node. As a consequence, the specific "
"actions for checking permissions are not available.".format(selected_database_node))
self.init_error_ui()
def init_ui(self):
"""
Initialize a user interface.
"""
# Create a table model and table view for showing the resulting data.
self.table_model = TableModel([])
self.table_view = QTableView()
self.table_view.setModel(self.table_model)
# Prepare the database connection parameters for further usage in the database query executor.
database_connection_parameters = self.selected_node.database_connection_parameters
self.database_connection = global_connection_factory.get_database_connection(
database_connection_parameters["host"],
database_connection_parameters["user"],
database_connection_parameters["database"],
database_connection_parameters["port"],
database_connection_parameters["timeout"])
# Create the database query executor for getting the materialized views by a query.
self.database_query_executor = DatabaseQueryExecutor()
# Connect the signal for the result with displaying the result data.
self.database_query_executor.result_data.connect(self.process_result_data)
# Connect the signal for an error with displaying information about an error.
self.database_query_executor.error.connect(self.process_error_message)
# Get the materialized views.
self.get_materialized_views()
# Adjust the size of the dialog.
self.setMaximumSize(720, 300)
self.showMaximized()
self.setWindowTitle("Materialized views for {}".format(self.selected_node.name))
self.show()
def init_grid(self):
"""
Initialize the grid layout.
"""
grid_layout = QGridLayout(self)
grid_layout.addWidget(self.table_view)
grid_layout.setSpacing(10)
self.setLayout(grid_layout)
def init_error_ui(self):
"""
Use a small UI for the error case of a wrong node instance as input parameter.
"""
# Get the layout as grid layout.
grid_layout = QGridLayout(self)
# Add a label with an error.
grid_layout.addWidget(QLabel("The given node is not a Database node, so materialized views cannot be "
"shown."), 0, 0)
self.setLayout(grid_layout)
self.setMaximumSize(10, 100)
self.showMaximized()
# Set the title to an error title.
self.setWindowTitle("Node Input Error")
self.show()
def get_materialized_views(self):
"""
Get the materialized views of a database node based on a query.
"""
# Define the query: Get the information of pg_matviews.
database_query = "SELECT * FROM pg_matviews;"
# Set the relevant parameters of the query executor.
self.database_query_executor.database_connection = self.database_connection
self.database_query_executor.database_query = database_query
# Execute!
self.database_query_executor.submit_and_execute_query()
def process_result_data(self, data_list):
"""
Process the result data: Show the data list in the table model.
"""
self.table_model.refresh_data_list(data_list)
self.table_view.resizeColumnsToContents()
def process_error_message(self, error_message):
"""
Process the error message with a log entry and an error message box.
"""
logging.error("During the query execution, an error occurred: {}".format(error_message))
QMessageBox.critical(self, "Information Query Error", "The query for getting the information could not"
" be executed with the error {}".format(error_message))

View File

@ -10,6 +10,7 @@ from pygadmin.configurator import global_app_configurator
from pygadmin.connectionstore import global_connection_store
from pygadmin.models.treemodel import ServerNode, TablesNode, ViewsNode, SchemaNode, AbstractBaseNode, DatabaseNode, \
TableNode, ViewNode
from pygadmin.widgets.materialized_view_information import MaterializedViewInformationDialog
from pygadmin.widgets.node_create_information import NodeCreateInformationDialog
from pygadmin.widgets.permission_information import PermissionInformationDialog
from pygadmin.widgets.table_edit import TableEditDialog
@ -258,6 +259,8 @@ class TreeWidget(QWidget):
self.context_menu.addAction(show_drop_statement_action)
show_permission_information_action = QAction("Show Permissions", self)
self.context_menu.addAction(show_permission_information_action)
show_materialized_views_action = QAction("Show Materialized Views")
self.context_menu.addAction(show_materialized_views_action)
position_action = self.context_menu.exec_(self.tree_view.viewport().mapToGlobal(position))
@ -271,6 +274,9 @@ class TreeWidget(QWidget):
elif position_action == show_permission_information_action:
self.show_permission_dialog(current_selected_node)
elif position_action == show_materialized_views_action:
self.show_materialized_views_of_database_node(current_selected_node)
# Check for a view node.
if isinstance(current_selected_node, ViewNode):
show_create_statement_action = QAction("Show Create Statement", self)
@ -965,3 +971,10 @@ class TreeWidget(QWidget):
# the given drop statement.
self.parent().parent().load_editor_with_connection_and_query(parameters_current_node,
optional_close_and_drop_statement)
def show_materialized_views_of_database_node(self, current_node):
"""
Show a dialog with the materialized views of the given node.
"""
self.materialized_view_information_dialog = MaterializedViewInformationDialog(current_node)