From bf14c9a020c466987d67cbb680f52302bc703a2f Mon Sep 17 00:00:00 2001 From: Thomas Peetz Date: Sun, 12 Jan 2025 02:41:40 +0100 Subject: [PATCH] extend MetaDataColumn by adding column for name of column for referenced tables --- qt/database/__init__.py | 13 ++- qt/database/comic.py | 96 ++++++++++++++++++- qt/database/metadata.py | 1 + qt/database/tysc.py | 89 ++++++++++++++--- qt/gui/main_window.py | 4 + qt/gui/model_config.py | 2 +- .../kontor/admin/SetupModuleAdmin.java | 6 +- .../kontor/admin/data/MetaDataColumn.java | 2 + .../admin/services/MetaDataService.java | 9 ++ .../kontor/admin/views/MetaDataForm.java | 2 + .../kontor/admin/views/MetaDataView.java | 4 +- 11 files changed, 203 insertions(+), 25 deletions(-) diff --git a/qt/database/__init__.py b/qt/database/__init__.py index c6d21a1..c0191cc 100644 --- a/qt/database/__init__.py +++ b/qt/database/__init__.py @@ -43,7 +43,7 @@ class KontorDB: meta_data = {} order = 0 for (_, column) in self.session.query(MetaDataTable, MetaDataColumn).filter(MetaDataTable.id == MetaDataColumn.table_id).filter(MetaDataTable.table_name == table_name).filter(MetaDataColumn.is_shown == 1).all(): - meta_data[order] = {'column': column.column_name, 'label': column.column_label, 'order': column.column_order} + meta_data[order] = {'column': column.column_name, 'label': column.column_label, 'order': column.column_order, 'ref_column': column.ref_column} order += 1 return meta_data @@ -70,7 +70,7 @@ class KontorDB: # print(f"KontorDB.get_data: {row}") data.append(list(row)) cursor.close() - print(f"KontorDB.getData: return {len(data)}") + # print(f"KontorDB.getData: return {len(data)}") if table_name == 'comic' and len(where_clause) == 0: data.clear() comics = self.session.query(Comic).all() @@ -79,8 +79,13 @@ class KontorDB: row = [] for order in columns.keys(): column_name = columns[order]['column'] - if column_name == 'publisher_id': - row.append(item.publisher.name) + if str(column_name).endswith("_id"): + ref_table = column_name[:-3] + # print(f"{ref_table=}") + ref = getattr(item, ref_table) + value = getattr(ref, "name") + # print(f"{value=}") + row.append(value) else: row.append(getattr(item, column_name)) # print(repr(row)) diff --git a/qt/database/comic.py b/qt/database/comic.py index c17244e..dc4204f 100644 --- a/qt/database/comic.py +++ b/qt/database/comic.py @@ -11,7 +11,7 @@ class Publisher(Base): created_date = Column(DateTime) last_modified_date = Column(DateTime) version = Column(Integer) - name = Column(String(length=255)) + name = Column(String(length=255), unique=True) comics = relationship("Comic") def __repr__(self): @@ -27,14 +27,104 @@ class Comic(Base): created_date = Column(DateTime) last_modified_date = Column(DateTime) version = Column(Integer) - title = Column(String(length=255)) - publisher_id = Column(String, ForeignKey('publisher.id')) + title = Column(String(length=255), unique=True) + publisher_id = Column(String, ForeignKey('publisher.id'), nullable=False) publisher = relationship("Publisher", back_populates="comics") current_order = Column(BIT(1)) completed = Column(BIT(1)) + issues = relationship("Issue") + story_arcs = relationship("StoryArc") + trade_paperbacks = relationship("TradePaperback") + volumes = relationship("Volume") + comic_works = relationship("ComicWork") def __repr__(self): return f'Comic({self.id} {self.version} {self.title} {self.publisher.name})' def __str__(self): return f'{self.title}({self.id})' + + +class Volume(Base): + __tablename__ = "volume" + id = Column(String, primary_key=True) + created_date = Column(DateTime) + last_modified_date = Column(DateTime) + version = Column(Integer) + name = Column(String(length=255), nullable=False) + comic_id = Column(String, ForeignKey("comic.id"), nullable=False) + comic = relationship("Comic", back_populates="volumes") + issues = relationship("Issue") + + +class TradePaperback(Base): + __tablename__ = "trade_paperback" + id = Column(String, primary_key=True) + created_date = Column(DateTime) + last_modified_date = Column(DateTime) + version = Column(Integer) + name = Column(String(length=255), nullable=False) + issue_start = Column(Integer) + issue_end = Column(Integer) + comic_id = Column(String, ForeignKey("comic.id"), nullable=False) + comic = relationship("Comic", back_populates="trade_paperbacks") + + +class StoryArc(Base): + __tablename__ = "story_arc" + id = Column(String, primary_key=True) + created_date = Column(DateTime) + last_modified_date = Column(DateTime) + version = Column(Integer) + name = Column(String(length=255), nullable=False) + comic_id = Column(String, ForeignKey("comic.id"), nullable=False) + comic = relationship("Comic", back_populates="story_arcs") + + +class Issue(Base): + __tablename__ = "issue" + id = Column(String, primary_key=True) + created_date = Column(DateTime) + last_modified_date = Column(DateTime) + version = Column(Integer) + issue_number = Column(String(255)) + in_stock = Column(BIT(1)) + is_read = Column(BIT(1)) + comic_id = Column(String, ForeignKey("comic.id"), nullable=False) + comic = relationship("Comic", back_populates="issues") + volume_id = Column(String, ForeignKey("volume.id"), nullable=True) + volume = relationship("Volume", back_populates="issues") + + +class Artist(Base): + __tablename__ = "artist" + id = Column(String, primary_key=True) + created_date = Column(DateTime) + last_modified_date = Column(DateTime) + version = Column(Integer) + name = Column(String(length=255), nullable=False) + comic_works = relationship("ComicWork") + + +class Worktype(Base): + __tablename__ = "worktype" + id = Column(String, primary_key=True) + created_date = Column(DateTime) + last_modified_date = Column(DateTime) + version = Column(Integer) + name = Column(String(length=255), nullable=False, unique=True) + comic_works = relationship("ComicWork") + + +class ComicWork(Base): + __tablename__ = "comic_work" + id = Column(String, primary_key=True) + created_date = Column(DateTime) + last_modified_date = Column(DateTime) + version = Column(Integer) + comic_id = Column(String, ForeignKey("comic.id"), nullable=False) + comic = relationship("Comic", back_populates="comic_works") + artist_id = Column(String, ForeignKey("artist.id"), nullable=False) + artist = relationship("Artist", back_populates="comic_works") + worktype_id = Column(String, ForeignKey("worktype.id"), nullable=False) + worktype = relationship("Worktype", back_populates="comic_works") diff --git a/qt/database/metadata.py b/qt/database/metadata.py index e1b9084..46a6274 100644 --- a/qt/database/metadata.py +++ b/qt/database/metadata.py @@ -37,6 +37,7 @@ class MetaDataColumn(Base): filter_label = Column(String(255)) is_shown = Column(BIT(1)) show_filter = Column(BIT(1)) + ref_column = Column(String, nullable=True) def __repr__(self): if self.column_name is None: diff --git a/qt/database/tysc.py b/qt/database/tysc.py index e78ff17..9c94177 100644 --- a/qt/database/tysc.py +++ b/qt/database/tysc.py @@ -1,4 +1,4 @@ -from sqlalchemy import Boolean, Column, DateTime, Integer, String, ForeignKey +from sqlalchemy import Boolean, Column, DateTime, Integer, String, ForeignKey, UniqueConstraint from sqlalchemy.dialects.mysql import BIT from sqlalchemy.orm import relationship @@ -7,11 +7,14 @@ from database.base import Base class Sport(Base): __tablename__ = "sport" + __table_args__ = ( + UniqueConstraint("name"), + ) id = Column(String, primary_key=True) created_date = Column(DateTime) last_modified_date = Column(DateTime) version = Column(Integer) - name = Column(String(255)) + name = Column(String(255), nullable=False, index=True, unique=True) teams = relationship("Team") positions = relationship("FieldPosition") @@ -22,47 +25,107 @@ class Team(Base): created_date = Column(DateTime) last_modified_date = Column(DateTime) version = Column(Integer) - name = Column(String(255)) - short_name = Column(String(255)) - sport_id = Column(String, ForeignKey("sport.id")) + name = Column(String(255), nullable=False, index=True, unique=True) + short_name = Column(String(255), nullable=False, ) + sport_id = Column(String, ForeignKey("sport.id"), nullable=False) sport = relationship("Sport", back_populates="positions") roosters = relationship("Rooster") class FieldPosition(Base): __tablename__ = "field_position" + __table_args__ = ( + UniqueConstraint("name", "sport_id"), + UniqueConstraint("short_name", "sport_id"), + ) id = Column(String, primary_key=True) created_date = Column(DateTime) last_modified_date = Column(DateTime) version = Column(Integer) - name = Column(String(255)) - short_name = Column(String(255)) - sport_id = Column(String, ForeignKey("sport.id")) + name = Column(String(255), nullable=False, index=True) + short_name = Column(String(255), nullable=False) + sport_id = Column(String, ForeignKey("sport.id"), nullable=False, index=True) sport = relationship("Sport", back_populates="positions") roosters = relationship("Rooster") class Player(Base): __tablename__ = "player" + __table_args__ = ( + UniqueConstraint("first_name", "last_name"), + ) id = Column(String, primary_key=True) created_date = Column(DateTime) last_modified_date = Column(DateTime) version = Column(Integer) - first_name = Column(String(255)) - last_name = Column(String(255)) + first_name = Column(String(255), nullable=False, index=True) + last_name = Column(String(255), nullable=False, index=True) roosters = relationship("Rooster") + def get_full_name(self) -> str: + return f"{self.last_name}, {self.first_name}" + class Rooster(Base): __tablename__ = "rooster" + __table_args__ = ( + UniqueConstraint("year", "team_id", "player_id", "position_id"), + ) id = Column(String, primary_key=True) created_date = Column(DateTime) last_modified_date = Column(DateTime) version = Column(Integer) year = Column(Integer) - team_id = Column(String, ForeignKey("team.id")) + team_id = Column(String, ForeignKey("team.id"), nullable=False, index=True) team = relationship("Team", back_populates="roosters") - player_id = Column(String, ForeignKey("player.id")) + player_id = Column(String, ForeignKey("player.id"), nullable=False, index=True) player = relationship("Player", back_populates="roosters") - position_id = Column(String, ForeignKey("field_position.id")) + position_id = Column(String, ForeignKey("field_position.id"), nullable=False, index=True) position = relationship("roosters") + cards = relationship("Card") + +class Vendor(Base): + __tablename__ = "vendor" + id = Column(String, primary_key=True) + created_date = Column(DateTime) + last_modified_date = Column(DateTime) + version = Column(Integer) + name = Column(String(255), nullable=False, unique=True, index=True) + card_sets = relationship("CardSet") + cards = relationship("Card") + + +class CardSet(Base): + __tablename__ = "card_set" + __table_args__ = ( + UniqueConstraint("name", "vendor_id"), + ) + id = Column(String, primary_key=True) + created_date = Column(DateTime) + last_modified_date = Column(DateTime) + version = Column(Integer) + name = Column(String(255), index=True) + parallel_set = Column(BIT(1)) + insert_set = Column(BIT(1)) + vendor_id = Column(String, ForeignKey("vendor.id"), nullable=False, index=True) + vendor = relationship("Vendor", back_populates="card_sets") + cards = relationship("Card") + + +class Card(Base): + __tablename__ = "card" + __table_args__ = ( + UniqueConstraint("card_number", "year", "vendor_id", "card_set_id"), + ) + id = Column(String, primary_key=True) + created_date = Column(DateTime) + last_modified_date = Column(DateTime) + version = Column(Integer) + card_number = Column(Integer, index=True) + year = Column(Integer, index=True) + card_set_id = Column(String, ForeignKey("card_set.id"), nullable=False) + card_set = relationship("cards") + rooster_id = Column(String, ForeignKey("rooster.id"), nullable=False) + rooster = relationship("cards") + vendor_id = Column(String, ForeignKey("vendor.id"), nullable=False) + vendor = relationship("Vendor", back_populates="cards") diff --git a/qt/gui/main_window.py b/qt/gui/main_window.py index a652906..42b4383 100644 --- a/qt/gui/main_window.py +++ b/qt/gui/main_window.py @@ -68,9 +68,13 @@ class MainWindow(QMainWindow): menu_bar.addMenu(kontor_menu) kontor_menu.addAction(self.importAction) kontor_menu.addAction(self.exportAction) + comic_menu = QMenu("&Comic") + tysc_menu = QMenu("&TradeYourSportCards") media_file_menu = QMenu("&MediaFile") media_file_menu.addAction(self.updateTitleAction) media_file_menu.addAction(self.downloadAction) + kontor_menu.addMenu(comic_menu) + kontor_menu.addMenu(tysc_menu) kontor_menu.addMenu(media_file_menu) # Help menu help_menu = QMenu("&Hilfe") diff --git a/qt/gui/model_config.py b/qt/gui/model_config.py index 01d3805..c2644e9 100644 --- a/qt/gui/model_config.py +++ b/qt/gui/model_config.py @@ -43,7 +43,7 @@ class KontorModelConfig: def get_data(self) -> list: data = self.kontor_db.get_data(self._table, self.header, self.get_filter()) - print(f"KontorModelConfig.get_data: {len(data)}") + # print(f"KontorModelConfig.get_data: {len(data)}") # comics = self.kontor_db.session.query(Comic).all() # print(f'{len(comics)} Comics loaded') return data diff --git a/springboot/src/main/java/de/thpeetz/kontor/admin/SetupModuleAdmin.java b/springboot/src/main/java/de/thpeetz/kontor/admin/SetupModuleAdmin.java index 4ac89e0..b54f74e 100644 --- a/springboot/src/main/java/de/thpeetz/kontor/admin/SetupModuleAdmin.java +++ b/springboot/src/main/java/de/thpeetz/kontor/admin/SetupModuleAdmin.java @@ -179,7 +179,7 @@ public class SetupModuleAdmin implements ApplicationListener column.getColumnName().equals(columnName))) { log.debug("Column {} with name {} of table {} found, check Values", columnOrder, columnName, table.getTableName()); MetaDataColumn column = table.getTableColumns().get(columnOrder.intValue()-1); @@ -70,6 +74,10 @@ public class MetaDataService { log.debug("filterLabel has to be change to {}}", filterLabel); column.setFilterLabel(filterLabel); } + if (refColumn != null && !refColumn.equals(column.getRefColumn())) { + log.debug("refColumn has to be change to {}}", filterLabel); + column.setRefColumn(refColumn); + } metaDataColumnRepository.save(column); } else { log.info("Column {} of table {} not found, will create it", columnName, table.getTableName()); @@ -85,6 +93,7 @@ public class MetaDataService { } } + public List findAllMetaDataColumns(String stringFilter) { if (stringFilter == null || stringFilter.isEmpty()) { log.debug("Found " + metaDataColumnRepository.count()+ " entries"); diff --git a/springboot/src/main/java/de/thpeetz/kontor/admin/views/MetaDataForm.java b/springboot/src/main/java/de/thpeetz/kontor/admin/views/MetaDataForm.java index b65b099..481f237 100644 --- a/springboot/src/main/java/de/thpeetz/kontor/admin/views/MetaDataForm.java +++ b/springboot/src/main/java/de/thpeetz/kontor/admin/views/MetaDataForm.java @@ -29,6 +29,7 @@ public class MetaDataForm extends FormLayout { TextField columnLabel = new TextField("Column Label"); Checkbox showFilter = new Checkbox("Show Filter"); TextField filterLabel = new TextField("Filter Label"); + TextField refColumn = new TextField("Ref Column"); Button save = new com.vaadin.flow.component.button.Button("Save"); Button delete = new com.vaadin.flow.component.button.Button("Delete"); @@ -47,6 +48,7 @@ public class MetaDataForm extends FormLayout { isShown.addClickListener(click -> columnLabel.setEnabled(isShown.getValue())); add(showFilter, filterLabel); showFilter.addClickListener(click -> filterLabel.setEnabled(showFilter.getValue())); + add(refColumn); add(createButtonsLayout()); } diff --git a/springboot/src/main/java/de/thpeetz/kontor/admin/views/MetaDataView.java b/springboot/src/main/java/de/thpeetz/kontor/admin/views/MetaDataView.java index 780126a..a5f4cca 100644 --- a/springboot/src/main/java/de/thpeetz/kontor/admin/views/MetaDataView.java +++ b/springboot/src/main/java/de/thpeetz/kontor/admin/views/MetaDataView.java @@ -66,6 +66,8 @@ public class MetaDataView extends VerticalLayout { setHeader("Zeige Filter").setWidth("6rem").setSortable(true); Grid.Column filterLabelColumn = grid.addColumn(MetaDataColumn::getFilterLabel) .setHeader("Filter Name").setResizable(true).setSortable(true); + Grid.Column refColumnColumn = grid.addColumn(MetaDataColumn::getRefColumn) + .setHeader("Ref Column Name").setResizable(true).setSortable(true); TextField searchField = new TextField(); @Getter MetaDataForm form; @@ -186,7 +188,7 @@ public class MetaDataView extends VerticalLayout { columnToggleContextMenu.addColumnToggleItem(columnLabelColumn.getHeaderText(), columnLabelColumn); columnToggleContextMenu.addColumnToggleItem(showFilterColumn.getHeaderText(), showFilterColumn); columnToggleContextMenu.addColumnToggleItem(filterLabelColumn.getHeaderText(), filterLabelColumn); - + columnToggleContextMenu.addColumnToggleItem(refColumnColumn.getHeaderText(), refColumnColumn); HorizontalLayout toolbar = new HorizontalLayout(searchField, addMetaDataButton, menuButton); toolbar.addClassName("toolbar"); return toolbar;