From 0c0a96213f7ceeaacc542bf6dbc0d12f6cf11178 Mon Sep 17 00:00:00 2001 From: Kevin Veen-Birkenbach Date: Tue, 5 Sep 2023 02:31:01 +0200 Subject: [PATCH] Refactored code --- matrix_builder.py | 143 ++++++++++++++++++++++------------------------ 1 file changed, 68 insertions(+), 75 deletions(-) diff --git a/matrix_builder.py b/matrix_builder.py index d980dfc..46fa7ec 100644 --- a/matrix_builder.py +++ b/matrix_builder.py @@ -1,84 +1,77 @@ from data_processor import DataProcessor + class MatrixBuilder: def __init__(self, data_processor, verbose=False): self.data_processor = data_processor self.verbose = verbose + def build_multitable_matrix(self, tables_data): + matrix = {} + for table_name, table_rows in tables_data.items(): + self.print_verbose_message(f"Building matrix for table: {table_name}") + matrix[table_name] = self._build_matrix_for_table(tables_data, table_name, table_rows.copy()) + return matrix + + def _build_matrix_for_table(self, tables_data, table_name, table_rows, reference_map={}): + self.print_verbose_message(f"Starting matrix build for table: {table_name}") + matrix = {table_name: table_rows} + reference_map = reference_map.copy() + self._process_link_fields(table_name, tables_data, reference_map) + self._populate_matrix_with_related_content(tables_data, matrix, table_name, table_rows, reference_map) + return matrix[table_name] + + def _populate_matrix_with_related_content(self, tables_data, matrix, table_name, table_rows, reference_map): + for table_row in table_rows: + for column_name, cell_content in table_row.items(): + if column_name in reference_map: + self.print_verbose_message(f"Handling linked content for column: {column_name}") + self._handle_linked_content(tables_data, matrix, table_row, column_name, cell_content, reference_map) + + def _handle_linked_content(self, tables_data, matrix, table_row, column_name, cell_content, reference_map): + link_table_id = reference_map[column_name]["link_row_table_id"] + link_field_id = reference_map[column_name]["link_row_related_field_id"] + + if not link_field_id: + raise Exception("link_row_related_field_id has to be a positive number") + + self.print_verbose_message(f"Fetching related content for table ID: {link_table_id} and field ID: {link_field_id}") + new_content = self._fetch_related_content(tables_data, matrix, cell_content, link_table_id, link_field_id, reference_map) + table_row[column_name] = new_content + + def _fetch_related_content(self, tables_data, matrix, cell_content, link_table_id, link_field_id, reference_map): + new_content = [] + for entry in cell_content: + related_cell_id = self._generate_related_cell_identifier(link_table_id, link_field_id, entry["id"]) + self.print_verbose_message(f"Generated related cell identifier: {related_cell_id}") + if related_cell_id not in reference_map.get("embeded", []): + reference_map.setdefault("embeded", []).append(related_cell_id) + matrix[link_table_id] = self._build_matrix_for_table(tables_data, link_table_id, tables_data[link_table_id].copy(), reference_map) + new_content.append(entry) + return new_content + + def _generate_related_cell_identifier(self, table_id, column_id, row_id): + return f"table_{table_id}_field_{column_id}_row_{row_id}" + + def _process_link_fields(self, table_name, tables_data, reference_map): + link_fields = self.data_processor.get_link_fields_for_table(table_name) + for link_field in link_fields: + self.print_verbose_message(f"Processing link fields for table: {table_name}") + self._load_table_data_if_missing(link_field, tables_data) + self._update_reference_map(link_field, reference_map) + + def _load_table_data_if_missing(self, link_field, tables_data): + link_table_id = link_field["link_row_table_id"] + if link_table_id not in tables_data: + self.print_verbose_message(f"Loading data for missing table ID: {link_table_id}") + tables_data[link_table_id] = self.data_processor.get_all_rows_from_table(link_table_id) + + def _update_reference_map(self, link_field, reference_map): + field_name = f"field_{link_field['id']}" + if field_name not in reference_map: + self.print_verbose_message(f"Updating reference map for field: {field_name}") + reference_map[field_name] = link_field + reference_map[field_name]["embeded"] = [] + def print_verbose_message(self, message): if self.verbose: print(message) - - def build_multitable_matrix(self, tables_data): - original_keys = list(tables_data.keys()) - matrix = {} - for table_name, table_rows in tables_data.items(): - matrix[table_name] = self.build_matrix(tables_data, table_name, table_rows.copy()) - return matrix - - def build_matrix(self, tables_data, table_name, table_rows, reference_map={}): - """Build a matrix with linked rows filled recursively.""" - matrix = {table_name: table_rows} - reference_map_child = reference_map.copy() - self.process_link_fields(table_name, tables_data, reference_map_child) - self.fill_cells_with_related_content(tables_data, matrix, table_name, table_rows, reference_map_child) - return matrix[table_name] - - def fill_cells_with_related_content(self, tables_data, matrix, table_name, table_rows, reference_map_child): - self.print_verbose_message(f"table_name: {table_name}") - for table_row in table_rows: - self.print_verbose_message(f"table_row: {table_row}") - for table_column_name, table_cell_content in table_row.items(): - self.print_verbose_message(f"table_cell_content {table_cell_content}") - if table_column_name in reference_map_child: - link_row_table_id = reference_map_child[table_column_name]["link_row_table_id"] - self.print_verbose_message(f"link_row_table_id: {link_row_table_id}") - - link_row_related_field_id = reference_map_child[table_column_name]["link_row_related_field_id"] - self.print_verbose_message(f"link_row_related_field_id: {link_row_related_field_id}") - - if not link_row_related_field_id: - raise Exception("link_row_related_field_id has to be a positive number") - new_content = [] - - for entry in table_cell_content: - self.print_verbose_message(f"entry: {entry}") - related_cell_identifier = self.generate_related_cell_identifier(link_row_table_id, link_row_related_field_id, entry["id"]) - self.print_verbose_message(f"related_cell_identifier: {related_cell_identifier}") - - if related_cell_identifier not in reference_map_child[table_column_name].get("embeded", []): - reference_map_child[table_column_name].setdefault("embeded", []).append(related_cell_identifier) - matrix[link_row_table_id] = self.build_matrix(tables_data, link_row_table_id, tables_data[link_row_table_id].copy(), reference_map_child) - new_content.append(entry) # Append the original content or modify as needed - table_row[table_column_name] = new_content - - def generate_related_cell_identifier(self, table_id, table_column_id, table_row_id): - return self.generate_cell_identifier(table_id, "field_" + str(table_column_id), table_row_id); - - def generate_cell_identifier(self, table_name, table_column_name, table_row_id): - table_name=str(table_name) - table_column_name=str(table_column_name) - table_row_id=str(table_row_id) - return "table_" + table_name + "_" + table_column_name + "_row_" + table_row_id - - def process_link_fields(self, table_name, tables_data, reference_map_child): - """Process link fields for a given table.""" - link_fields = self.data_processor.get_link_fields_for_table(table_name) - - for link_field in link_fields: - self.load_table_data_if_not_present(link_field, tables_data) - self.update_reference_map(link_field, reference_map_child) - - def load_table_data_if_not_present(self, link_field, tables_data): - """Load table data if it's not already loaded.""" - link_row_table_id = link_field["link_row_table_id"] - - if link_row_table_id not in tables_data: - tables_data[link_row_table_id] = self.data_processor.get_all_rows_from_table(link_row_table_id) - - def update_reference_map(self, link_field, reference_map_child): - """Update the reference map with the link field data.""" - link_field_name = "field_" + str(link_field["id"]) - - if link_field_name not in reference_map_child: - reference_map_child[link_field_name] = link_field - reference_map_child[link_field_name]["embeded"] = [] \ No newline at end of file