update models to use string type for id fields

This commit is contained in:
Thomas Peetz
2025-05-02 11:21:57 +02:00
parent 7ff2bf912d
commit c77adb0e04
31 changed files with 397 additions and 233 deletions
+6 -7
View File
@@ -1,11 +1,10 @@
from uuid import UUID from typing import List, AnyStr
from typing import List
from fastapi import APIRouter, HTTPException, status from fastapi import APIRouter, HTTPException, status
from sqlalchemy import select
from src.apis.utils import SessionDep from src.apis.utils import SessionDep
from src.db.repository.comic import get_artist_details, list_comics
from src.schema.comics.comic import ComicResponse, ComicDetailsResponse, get_comic_details, get_short_info from src.schema.comics.comic import ComicResponse, ComicDetailsResponse, get_comic_details, get_short_info
from src.schema.comics.artist import ArtistCreation, ArtistDetailResponse, ArtistResponse, get_artist_details from src.schema.comics.artist import ArtistCreation, ArtistDetailResponse, ArtistResponse
from src.db.models.comic import Comic, Artist from src.db.models.comic import Comic, Artist
router = APIRouter( router = APIRouter(
@@ -18,14 +17,14 @@ router = APIRouter(
@router.get("/comics") @router.get("/comics")
def get_all_comics(db: SessionDep) -> List[ComicResponse]: def get_all_comics(db: SessionDep) -> List[ComicResponse]:
results: List[ComicResponse] = [] results: List[ComicResponse] = []
comics = db.scalars(select(Comic)).all() comics = list_comics(db)
for comic in comics: for comic in comics:
response = get_short_info(comic) response = get_short_info(comic)
results.append(response) results.append(response)
return results return results
@router.get("/comics/{comic_id}", response_model=ComicDetailsResponse) @router.get("/comics/{comic_id}", response_model=ComicDetailsResponse)
def get_comic(comic_id: UUID, db: SessionDep) -> ComicDetailsResponse: def get_comic(comic_id: AnyStr, db: SessionDep) -> ComicDetailsResponse:
comic = db.get(Comic, comic_id) comic = db.get(Comic, comic_id)
if comic is None: if comic is None:
raise HTTPException(status_code=404, detail="Comic could not be found") raise HTTPException(status_code=404, detail="Comic could not be found")
@@ -41,7 +40,7 @@ def get_all_artists(db: SessionDep) -> List[ArtistResponse]:
return results return results
@router.get("/artists/{artist_id}", response_model=ArtistDetailResponse) @router.get("/artists/{artist_id}", response_model=ArtistDetailResponse)
def get_artist(artist_id: UUID, db: SessionDep) -> ArtistDetailResponse: def get_artist(artist_id: AnyStr, db: SessionDep) -> ArtistDetailResponse:
artist = db.get(Artist, artist_id) artist = db.get(Artist, artist_id)
if artist is None: if artist is None:
raise HTTPException(status_code=404, detail="Artist could not be found") raise HTTPException(status_code=404, detail="Artist could not be found")
+3 -3
View File
@@ -1,4 +1,4 @@
from typing import List from typing import List, AnyStr
from uuid import UUID from uuid import UUID
from fastapi import APIRouter, status, HTTPException from fastapi import APIRouter, status, HTTPException
@@ -42,7 +42,7 @@ def get_all_files(db: SessionDep, review: bool = False, download: bool = False)
return results return results
@router.get("/files/{file_id}", response_model=MediaFileResponse) @router.get("/files/{file_id}", response_model=MediaFileResponse)
def get_file(file_id: UUID, db: SessionDep) -> MediaFileResponse: def get_file(file_id: AnyStr, db: SessionDep) -> MediaFileResponse:
mediafile = db.get(MediaFile, file_id) mediafile = db.get(MediaFile, file_id)
if not mediafile: if not mediafile:
raise HTTPException(status_code=404, detail="MediaFile could not be found") raise HTTPException(status_code=404, detail="MediaFile could not be found")
@@ -50,7 +50,7 @@ def get_file(file_id: UUID, db: SessionDep) -> MediaFileResponse:
return response return response
@router.put("/files/{file_id}", response_model=MediaFileResponse) @router.put("/files/{file_id}", response_model=MediaFileResponse)
def update_file(file_id: UUID, db: SessionDep, info: MediaFileResponse) -> MediaFileResponse: def update_file(file_id: AnyStr, db: SessionDep, info: MediaFileResponse) -> MediaFileResponse:
mediaFile = db.get(MediaFile, file_id) mediaFile = db.get(MediaFile, file_id)
if not mediaFile: if not mediaFile:
raise HTTPException(status_code=404, detail="MediaFile could not be found") raise HTTPException(status_code=404, detail="MediaFile could not be found")
+14 -14
View File
@@ -8,11 +8,11 @@ from src.db.models.base import Base, BaseMixin
class Profile(Base, BaseMixin): class Profile(Base, BaseMixin):
__tablename__ = 'profile' __tablename__ = 'profile'
first_name = Column(String(255)) first_name = Column(String)
last_name = Column(String(255)) last_name = Column(String)
user_name = Column(String(255), nullable=False) user_name = Column(String, nullable=False)
email = Column(String(255)) email = Column(String)
password = Column(String(255)) password = Column(String)
enabled = Column(Boolean) enabled = Column(Boolean)
assignments = relationship("Assignment") assignments = relationship("Assignment")
tokens = relationship("Token") tokens = relationship("Token")
@@ -30,17 +30,17 @@ class Profile(Base, BaseMixin):
class Token(Base, BaseMixin): class Token(Base, BaseMixin):
__tablename__ = "token" __tablename__ = "token"
token = Column(String(255), nullable=False, unique=True) token = Column(String, nullable=False, unique=True)
name = Column(String(255)) name = Column(String)
last_used_date: Mapped[datetime] = mapped_column() last_used_date: Mapped[datetime] = mapped_column()
enabled = Column(Boolean) enabled = Column(Boolean)
profile_id = Column(String(255), ForeignKey("profile.id"), nullable=False) profile_id = Column(String, ForeignKey("profile.id"), nullable=False)
profile = relationship("Profile", back_populates="tokens") profile = relationship("Profile", back_populates="tokens")
class Permission(Base, BaseMixin): class Permission(Base, BaseMixin):
__tablename__ = "permission" __tablename__ = "permission"
name = Column(String(255), nullable=False) name = Column(String, nullable=False)
assignments = relationship("Assignment") assignments = relationship("Assignment")
@@ -54,17 +54,17 @@ class Assignment(Base, BaseMixin):
class ModuleData(Base, BaseMixin): class ModuleData(Base, BaseMixin):
__tablename__ = "module_data" __tablename__ = "module_data"
module_name = Column(String(255), nullable=False) module_name = Column(String, nullable=False)
import_data = Column(Boolean) import_data = Column(Boolean)
class MailAccount(Base, BaseMixin): class MailAccount(Base, BaseMixin):
__tablename__ = "mail_account" __tablename__ = "mail_account"
host = Column(String(255)) host = Column(String)
port = Column(Integer) port = Column(Integer)
protocol = Column(String(255)) protocol = Column(String)
user_name = Column(String(255)) user_name = Column(String)
password = Column(String(255)) password = Column(String)
start_tls = Column(Boolean) start_tls = Column(Boolean)
+7 -7
View File
@@ -10,8 +10,8 @@ class Base(DeclarativeBase):
class BaseMixin: class BaseMixin:
id = Column(String(255), primary_key=True, default=uuid.uuid4()) #id = Column(String(255), primary_key=True, default=uuid.uuid4)
# id: Mapped[str] = mapped_column(primary_key=True, default=uuid.uuid4()) id: Mapped[str] = mapped_column(primary_key=True, default=uuid.uuid4)
# created_date = Column(DateTime) # created_date = Column(DateTime)
created_date: Mapped[datetime] = mapped_column(default=func.now()) created_date: Mapped[datetime] = mapped_column(default=func.now())
# last_modified_date = Column(DateTime) # last_modified_date = Column(DateTime)
@@ -21,10 +21,10 @@ class BaseMixin:
class BaseVideoMixin: class BaseVideoMixin:
cloud_link = Column(String(255)) cloud_link = Column(String)
file_name = Column(String(255)) file_name = Column(String)
path = Column(String(255)) path = Column(String)
review = Column(Boolean) review = Column(Boolean)
title = Column(String(255)) title = Column(String)
url = Column(String(255), unique=True) url = Column(String, unique=True)
should_download = Column(Boolean) should_download = Column(Boolean)
+8 -8
View File
@@ -8,7 +8,7 @@ from src.db.models.base import Base, BaseMixin
class Publisher(Base, BaseMixin): class Publisher(Base, BaseMixin):
__tablename__ = "publisher" __tablename__ = "publisher"
name = Column(String(length=255), unique=True) name = Column(String, unique=True)
comics = relationship("Comic") comics = relationship("Comic")
def __repr__(self): def __repr__(self):
@@ -20,7 +20,7 @@ class Publisher(Base, BaseMixin):
class Comic(Base, BaseMixin): class Comic(Base, BaseMixin):
__tablename__ = 'comic' __tablename__ = 'comic'
title = Column(String(length=255), unique=True) title = Column(String, unique=True)
publisher_id = Column(String, ForeignKey('publisher.id'), nullable=False) publisher_id = Column(String, ForeignKey('publisher.id'), nullable=False)
publisher = relationship("Publisher", back_populates="comics") publisher = relationship("Publisher", back_populates="comics")
current_order = Column(Boolean) current_order = Column(Boolean)
@@ -55,7 +55,7 @@ class Comic(Base, BaseMixin):
class Volume(Base, BaseMixin): class Volume(Base, BaseMixin):
__tablename__ = "volume" __tablename__ = "volume"
name = Column(String(length=255), nullable=False) name = Column(String, nullable=False)
comic_id = Column(String, ForeignKey("comic.id"), nullable=False) comic_id = Column(String, ForeignKey("comic.id"), nullable=False)
comic = relationship("Comic", back_populates="volumes") comic = relationship("Comic", back_populates="volumes")
issues = relationship("Issue") issues = relationship("Issue")
@@ -63,7 +63,7 @@ class Volume(Base, BaseMixin):
class TradePaperback(Base, BaseMixin): class TradePaperback(Base, BaseMixin):
__tablename__ = "trade_paperback" __tablename__ = "trade_paperback"
name = Column(String(length=255), nullable=False) name = Column(String, nullable=False)
issue_start = Column(Integer) issue_start = Column(Integer)
issue_end = Column(Integer) issue_end = Column(Integer)
comic_id = Column(String, ForeignKey("comic.id"), nullable=False) comic_id = Column(String, ForeignKey("comic.id"), nullable=False)
@@ -72,14 +72,14 @@ class TradePaperback(Base, BaseMixin):
class StoryArc(Base, BaseMixin): class StoryArc(Base, BaseMixin):
__tablename__ = "story_arc" __tablename__ = "story_arc"
name = Column(String(length=255), nullable=False) name = Column(String, nullable=False)
comic_id = Column(String, ForeignKey("comic.id"), nullable=False) comic_id = Column(String, ForeignKey("comic.id"), nullable=False)
comic = relationship("Comic", back_populates="story_arcs") comic = relationship("Comic", back_populates="story_arcs")
class Issue(Base, BaseMixin): class Issue(Base, BaseMixin):
__tablename__ = "issue" __tablename__ = "issue"
issue_number = Column(String(255)) issue_number = Column(String)
in_stock = Column(Boolean) in_stock = Column(Boolean)
is_read = Column(Boolean) is_read = Column(Boolean)
comic_id = Column(String, ForeignKey("comic.id"), nullable=False) comic_id = Column(String, ForeignKey("comic.id"), nullable=False)
@@ -90,7 +90,7 @@ class Issue(Base, BaseMixin):
class Artist(Base, BaseMixin): class Artist(Base, BaseMixin):
__tablename__ = "artist" __tablename__ = "artist"
name = Column(String(length=255), nullable=False) name = Column(String, nullable=False)
comic_works = relationship("ComicWork") comic_works = relationship("ComicWork")
def get_comics(self) -> Dict[str, List[str]]: def get_comics(self) -> Dict[str, List[str]]:
@@ -107,7 +107,7 @@ class Artist(Base, BaseMixin):
class WorkType(Base, BaseMixin): class WorkType(Base, BaseMixin):
__tablename__ = "worktype" __tablename__ = "worktype"
name = Column(String(length=255), nullable=False, unique=True) name = Column(String, nullable=False, unique=True)
comic_works = relationship("ComicWork") comic_works = relationship("ComicWork")
def __repr__(self): def __repr__(self):
+10 -10
View File
@@ -70,31 +70,31 @@ class MediaFile(Base, BaseMixin, BaseVideoMixin):
class MediaActor(Base, BaseMixin): class MediaActor(Base, BaseMixin):
__tablename__ = 'media_actor' __tablename__ = 'media_actor'
name = Column(String(255)) name = Column(String)
media_actor_files = relationship("MediaActorFile") media_actor_files = relationship("MediaActorFile")
class MediaActorFile(Base, BaseMixin): class MediaActorFile(Base, BaseMixin):
__tablename__ = 'media_actor_file' __tablename__ = 'media_actor_file'
media_actor_id = Column(String(255), ForeignKey("media_actor.id"), nullable=False) media_actor_id = Column(String, ForeignKey("media_actor.id"), nullable=False)
media_actor = relationship("MediaActor", back_populates="media_actor_files") media_actor = relationship("MediaActor", back_populates="media_actor_files")
media_file_id = Column(String(255), ForeignKey("media_file.id"), nullable=True) media_file_id = Column(String, ForeignKey("media_file.id"), nullable=True)
media_file = relationship("MediaFile", back_populates="media_actor_files") media_file = relationship("MediaFile", back_populates="media_actor_files")
class MediaArticle(Base, BaseMixin): class MediaArticle(Base, BaseMixin):
__tablename__ = 'media_article' __tablename__ = 'media_article'
review = Column(Boolean) review = Column(Boolean)
title = Column(String(255)) title = Column(String)
url = Column(String(255), unique=True) url = Column(String, unique=True)
class MediaVideo(Base, BaseMixin): class MediaVideo(Base, BaseMixin):
__tablename__ = 'media_video' __tablename__ = 'media_video'
cloud_link = Column(String(255)) cloud_link = Column(String)
file_name = Column(String(255)) file_name = Column(String)
path = Column(String(255)) path = Column(String)
review = Column(Boolean) review = Column(Boolean)
title = Column(String(255)) title = Column(String)
url = Column(String(255), unique=True) url = Column(String, unique=True)
should_download = Column(Boolean) should_download = Column(Boolean)
+7 -7
View File
@@ -6,7 +6,7 @@ from src.db.models.base import Base, BaseMixin
class MetaDataTable(Base, BaseMixin): class MetaDataTable(Base, BaseMixin):
__tablename__ = 'meta_data_table' __tablename__ = 'meta_data_table'
table_name = Column(String(255), unique=True) table_name = Column(String, unique=True)
table_columns = relationship("MetaDataColumn") table_columns = relationship("MetaDataColumn")
def __repr__(self): def __repr__(self):
@@ -18,15 +18,15 @@ class MetaDataTable(Base, BaseMixin):
class MetaDataColumn(Base, BaseMixin): class MetaDataColumn(Base, BaseMixin):
__tablename__ = 'meta_data_column' __tablename__ = 'meta_data_column'
column_name = Column(String(255), nullable=False) column_name = Column(String, nullable=False)
column_sync_name = Column(String(255)) column_sync_name = Column(String)
column_type = Column(String(255)) column_type = Column(String)
column_modifier = Column(String(255), nullable=True) column_modifier = Column(String, nullable=True)
column_order = Column(Integer) column_order = Column(Integer)
table_id = Column(String, ForeignKey('meta_data_table.id')) table_id = Column(String, ForeignKey('meta_data_table.id'))
table = relationship("MetaDataTable", back_populates="table_columns") table = relationship("MetaDataTable", back_populates="table_columns")
column_label = Column(String(255)) column_label = Column(String)
filter_label = Column(String(255)) filter_label = Column(String)
is_shown = Column(Boolean) is_shown = Column(Boolean)
show_filter = Column(Boolean) show_filter = Column(Boolean)
ref_column = Column(String, nullable=True) ref_column = Column(String, nullable=True)
+9 -9
View File
@@ -9,15 +9,15 @@ class Sport(Base, BaseMixin):
__table_args__ = ( __table_args__ = (
UniqueConstraint("name"), UniqueConstraint("name"),
) )
name = Column(String(255), nullable=False, index=True, unique=True) name = Column(String, nullable=False, index=True, unique=True)
teams = relationship("Team") teams = relationship("Team")
positions = relationship("FieldPosition") positions = relationship("FieldPosition")
class Team(Base, BaseMixin): class Team(Base, BaseMixin):
__tablename__ = "team" __tablename__ = "team"
name = Column(String(255), nullable=False, index=True, unique=True) name = Column(String, nullable=False, index=True, unique=True)
short_name = Column(String(255), nullable=False, ) short_name = Column(String, nullable=False, )
sport_id = Column(String, ForeignKey("sport.id"), nullable=False) sport_id = Column(String, ForeignKey("sport.id"), nullable=False)
sport = relationship("Sport", back_populates="teams") sport = relationship("Sport", back_populates="teams")
roosters = relationship("Rooster") roosters = relationship("Rooster")
@@ -29,8 +29,8 @@ class FieldPosition(Base, BaseMixin):
UniqueConstraint("name", "sport_id"), UniqueConstraint("name", "sport_id"),
UniqueConstraint("short_name", "sport_id"), UniqueConstraint("short_name", "sport_id"),
) )
name = Column(String(255), nullable=False, index=True) name = Column(String, nullable=False, index=True)
short_name = Column(String(255), nullable=False) short_name = Column(String, nullable=False)
sport_id = Column(String, ForeignKey("sport.id"), nullable=False, index=True) sport_id = Column(String, ForeignKey("sport.id"), nullable=False, index=True)
sport = relationship("Sport", back_populates="positions") sport = relationship("Sport", back_populates="positions")
roosters = relationship("Rooster") roosters = relationship("Rooster")
@@ -41,8 +41,8 @@ class Player(Base, BaseMixin):
__table_args__ = ( __table_args__ = (
UniqueConstraint("first_name", "last_name"), UniqueConstraint("first_name", "last_name"),
) )
first_name = Column(String(255), nullable=False, index=True) first_name = Column(String, nullable=False, index=True)
last_name = Column(String(255), nullable=False, index=True) last_name = Column(String, nullable=False, index=True)
roosters = relationship("Rooster") roosters = relationship("Rooster")
def get_full_name(self) -> str: def get_full_name(self) -> str:
@@ -66,7 +66,7 @@ class Rooster(Base, BaseMixin):
class Vendor(Base, BaseMixin): class Vendor(Base, BaseMixin):
__tablename__ = "vendor" __tablename__ = "vendor"
name = Column(String(255), nullable=False, unique=True, index=True) name = Column(String, nullable=False, unique=True, index=True)
card_sets = relationship("CardSet") card_sets = relationship("CardSet")
cards = relationship("Card") cards = relationship("Card")
@@ -76,7 +76,7 @@ class CardSet(Base, BaseMixin):
__table_args__ = ( __table_args__ = (
UniqueConstraint("name", "vendor_id"), UniqueConstraint("name", "vendor_id"),
) )
name = Column(String(255), index=True) name = Column(String, index=True)
parallel_set = Column(Boolean) parallel_set = Column(Boolean)
insert_set = Column(Boolean) insert_set = Column(Boolean)
vendor_id = Column(String, ForeignKey("vendor.id"), nullable=False, index=True) vendor_id = Column(String, ForeignKey("vendor.id"), nullable=False, index=True)
+27
View File
@@ -0,0 +1,27 @@
from typing import List, Type
from sqlalchemy.orm import Session
from src.db.models.comic import Artist, Comic
from src.schema.comics.artist import ArtistDetailResponse
def get_artist_details(artist: Artist) -> ArtistDetailResponse:
works = {}
for work in artist.comic_works:
work_type = work.work_type.name
comic_title = work.comic.title
if work_type in works:
works[work_type].append(comic_title)
else:
works[work_type] = [comic_title]
response = ArtistDetailResponse(
id=artist.id,
name=artist.name,
works=works
)
return response
def list_comics(db: Session) -> List[Type[Comic]]:
comics = db.query(Comic).all()
return comics
+2 -2
View File
@@ -1,7 +1,7 @@
from typing import Generator, Annotated from typing import Generator
from sqlalchemy import create_engine from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, Session from sqlalchemy.orm import sessionmaker
from src.core.config import settings from src.core.config import settings
+7 -1
View File
@@ -1,3 +1,5 @@
import logging
from fastapi import FastAPI from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
@@ -7,6 +9,10 @@ from src.webapps.base import api_router as web_app_router
from src.core.config import settings from src.core.config import settings
from src.db.models.base import Base from src.db.models.base import Base
logging.basicConfig(level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[logging.StreamHandler()]) # Logs to console
def include_router(app: FastAPI): def include_router(app: FastAPI):
app.include_router(api_router) app.include_router(api_router)
app.include_router(web_app_router) app.include_router(web_app_router)
@@ -18,6 +24,7 @@ def create_tables():
Base.metadata.create_all(bind=engine) Base.metadata.create_all(bind=engine)
def start_application(): def start_application():
logging.info(f"using database: {settings.DATABASE_URL}")
app = FastAPI(title=settings.PROJECT_NAME, version=settings.PROJECT_VERSION) app = FastAPI(title=settings.PROJECT_NAME, version=settings.PROJECT_VERSION)
include_router(app) include_router(app)
configure_static(app) configure_static(app)
@@ -26,4 +33,3 @@ def start_application():
kontor = start_application() kontor = start_application()
+3 -19
View File
@@ -7,30 +7,14 @@ from src.db.models.comic import Artist
class ArtistCreation(BaseModel): class ArtistCreation(BaseModel):
id: str
name: str name: str
class ArtistResponse(BaseModel): class ArtistResponse(BaseModel):
id: UUID id: str
name: str name: str
class ArtistDetailResponse(BaseModel): class ArtistDetailResponse(BaseModel):
id: UUID id: str
name: str name: str
works: Dict[str, List[str]] works: Dict[str, List[str]]
def get_artist_details(artist: Artist) -> ArtistDetailResponse:
works = {}
for work in artist.comic_works:
work_type = work.work_type.name
comic_title = work.comic.title
if work_type in works:
works[work_type].append(comic_title)
else:
works[work_type] = [comic_title]
response = ArtistDetailResponse(
id=artist.id,
name=artist.name,
works=works
)
return response
+2 -2
View File
@@ -7,12 +7,12 @@ from src.db.models.comic import Comic
class ComicResponse(BaseModel): class ComicResponse(BaseModel):
id: UUID id: str
title: str title: str
completed: bool completed: bool
class ComicDetailsResponse(BaseModel): class ComicDetailsResponse(BaseModel):
id: UUID id: str
created: str created: str
title: str title: str
completed : bool completed : bool
+5 -7
View File
@@ -1,10 +1,8 @@
from uuid import UUID
from fastapi import APIRouter, Request from fastapi import APIRouter, Request
from fastapi.templating import Jinja2Templates from fastapi.templating import Jinja2Templates
from src.apis.utils import SessionDep from src.apis.utils import SessionDep
from src.db.models.comic import Comic, Artist, Publisher from src.db.models.comic import Comic, Artist, Publisher
from typing import AnyStr
templates = Jinja2Templates(directory="src/templates") templates = Jinja2Templates(directory="src/templates")
router = APIRouter(include_in_schema=False, prefix="/comic") router = APIRouter(include_in_schema=False, prefix="/comic")
@@ -15,7 +13,7 @@ def get_comics(db: SessionDep, request: Request, msg: str = None):
return templates.TemplateResponse("comic/comics.html", {"request": request, "msg": msg, "comics": comics}) return templates.TemplateResponse("comic/comics.html", {"request": request, "msg": msg, "comics": comics})
@router.get("/comics/{comic_id}") @router.get("/comics/{comic_id}")
def comic_details(comic_id: UUID, request: Request, db: SessionDep): def comic_details(comic_id: AnyStr, request: Request, db: SessionDep):
comic = db.get(Comic, comic_id) comic = db.get(Comic, comic_id)
return templates.TemplateResponse("comic/comic_detail.html", {"request": request, "comic":comic}) return templates.TemplateResponse("comic/comic_detail.html", {"request": request, "comic":comic})
@@ -25,8 +23,8 @@ def get_artists(db: SessionDep, request: Request, msg: str = None):
return templates.TemplateResponse("comic/artists.html", {"request": request, "msg": msg, "artists": artists}) return templates.TemplateResponse("comic/artists.html", {"request": request, "msg": msg, "artists": artists})
@router.get("/artists/{artist_id}") @router.get("/artists/{artist_id}")
def artist_detail(artist_id: UUID, request: Request, db: SessionDep): def artist_detail(artist_id: AnyStr, request: Request, db: SessionDep):
artist = db.get(Artist, artist_id) artist = db.get(Artist, str(artist_id))
return templates.TemplateResponse("comic/artist_detail.html", {"request": request, "artist": artist}) return templates.TemplateResponse("comic/artist_detail.html", {"request": request, "artist": artist})
@router.get("/publishers") @router.get("/publishers")
@@ -35,7 +33,7 @@ def get_publishers(db: SessionDep, request: Request, msg: str = None):
return templates.TemplateResponse("comic/publishers.html", {"request": request, "publishers": publishers}) return templates.TemplateResponse("comic/publishers.html", {"request": request, "publishers": publishers})
@router.get("/publishers/{publisher_id}") @router.get("/publishers/{publisher_id}")
def publisher_details(publisher_id: UUID, request: Request, db: SessionDep, msg: str = None): def publisher_details(publisher_id: AnyStr, request: Request, db: SessionDep, msg: str = None):
publisher = db.get(Publisher, publisher_id) publisher = db.get(Publisher, publisher_id)
if publisher is None: if publisher is None:
msg = "Could not find Publisher" msg = "Could not find Publisher"
+100 -6
View File
@@ -3,6 +3,8 @@ copy data from JSON to Postgres
""" """
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
from pathlib import Path from pathlib import Path
from typing import Dict, List
from config import get_logger, get_database_cursors from config import get_logger, get_database_cursors
import json import json
import psycopg2 import psycopg2
@@ -29,7 +31,10 @@ def copy_data(postgres_conn, data_file: Path, log):
# result[table] = import_table(table, json_load[table]) # result[table] = import_table(table, json_load[table])
truncate_statement = 'TRUNCATE {} CASCADE'.format(table) truncate_statement = 'TRUNCATE {} CASCADE'.format(table)
#log.info(f"truncate: {truncate_statement}") #log.info(f"truncate: {truncate_statement}")
postgres_cursor.execute(truncate_statement) try:
postgres_cursor.execute(truncate_statement)
except:
log.info(f"statement: {insert_statement} FAILED")
items = json_load[table] items = json_load[table]
for item in items: for item in items:
#log.info(f"item: {item}") #log.info(f"item: {item}")
@@ -39,21 +44,110 @@ def copy_data(postgres_conn, data_file: Path, log):
columns.append(key) columns.append(key)
values.append(value) values.append(value)
row = tuple(values) row = tuple(values)
log.info(f"values: {row}") #log.info(f"values: {row}")
insert_statement = 'INSERT INTO {}({}) VALUES({})'.format(table, ', '.join(columns), ', '.join(['%s']*len(columns))) insert_statement = 'INSERT INTO {}({}) VALUES({})'.format(table, ', '.join(columns), ', '.join(['%s']*len(columns)))
#log.info(f"statement: {insert_statement}") #log.info(f"statement: {insert_statement}")
postgres_cursor.execute(SQL(insert_statement), row)
try: try:
postgres_cursor.execute(SQL(insert_statement), row)
postgres_conn.commit() postgres_conn.commit()
except psycopg2.Error as error: except:
log.info('insert failed with %s', error) log.info(f'insert failed with {insert_statement}')
postgres_cursor.execute("SET session_replication_role='origin'") postgres_cursor.execute("SET session_replication_role='origin'")
def load_json(data_file, log) -> dict:
import_file = Path(data_file)
if not import_file.exists():
log.info(f"File {data_file} does not exist. Do nothing.")
return
log.info("read json file")
with open(data_file, 'r') as json_file:
json_load = json.load(json_file)
return json_load
def insert_data(postgres_conn, data: dict, log):
postgres_cursor = postgres_conn.cursor()
log.info("insert data")
table_list = []
#table_list = ['worktype', 'artist', 'publisher', 'volume', 'comic', 'issue', 'story_arc', 'trade_paperback', 'comic_work']
#table_list.extend(['sport', 'team', 'field_position', 'vendor', 'player', 'rooster', 'card_set', 'card'])
#table_list.extend(['card'])
#table_list.extend(['media_file', 'media_video', 'media_actor', 'media_actor_file', 'media_article'])
#table_list.extend(['media_actor_file'])
#table_list.extend(['profile', 'permission', 'token', 'assignment'])
#table_list.extend(['mail', 'mail_account', 'module_data', 'meta_data_table', 'meta_data_column'])
table_list.extend(['meta_data_column'])
#table_list.extend(['book', 'author', 'article', 'bookshelf_publisher', 'book_author', 'article_author'])
#if len(table_list) != 37:
# log.info(f"number of tables incorrect: {len(table_list)}")
# return
for table in table_list:
log.info(f"{table}: {len(data[table])}")
truncate_statement = 'DELETE FROM {}'.format(table)
log.info(f"truncate: {truncate_statement}")
try:
postgres_cursor.execute(truncate_statement)
postgres_conn.commit()
except:
log.info(f"statement: {truncate_statement} FAILED")
items = data[table]
for item in items:
# log.info(f"item: {item}")
values = []
columns = []
for (key, value) in item.items():
columns.append(key)
values.append(value)
row = tuple(values)
# log.info(f"values: {row}")
insert_statement = 'INSERT INTO {}({}) VALUES({})'.format(table, ', '.join(columns),
', '.join(['%s'] * len(columns)))
# log.info(f"statement: {insert_statement}")
try:
postgres_cursor.execute(SQL(insert_statement), row)
postgres_conn.commit()
except:
log.info(f'insert failed with {insert_statement}')
def parse_table_order(data: dict, log):
log.info("parse_table_order")
table_refs: Dict[str, List[str]] = {}
for table in data:
log.info(f"{table}: {len(data[table])}")
items = data[table]
table_refs[table] = []
if len(items) == 0:
continue
item = items[0]
for key, _ in item.items():
if key.endswith('_id'):
ref = key[0:-3]
log.info(f"table {table} has reference to {ref}")
if table in table_refs:
table_refs[table].append(ref)
else:
table_refs[table] = [ref]
log.info(f"parsed refs: {table_refs}")
table_order = []
for table in table_refs:
if len(table_refs[table]) == 0:
log.info(f"insert {table} at beginning")
table_order.insert(0, table)
else:
log.info(f"insert {table} at end")
table_order.append(table)
log.info(f"table_list: {len(table_order)}: {table_order}")
if __name__ == '__main__': if __name__ == '__main__':
logger = get_logger(args.verbose, args.config) logger = get_logger(args.verbose, args.config)
logger.info('kontor.json_to_postgres started') logger.info('kontor.json_to_postgres started')
_, _, p_conn = get_database_cursors(logger, args.config) _, _, p_conn = get_database_cursors(logger, args.config)
copy_data(p_conn, args.file, logger) data = load_json(args.file, logger)
#parse_table_order(data, logger)
insert_data(p_conn, data, logger)
#copy_data(p_conn, args.file, logger)
p_conn.close() p_conn.close()
logger.info('kontor.json_to_postgres finished') logger.info('kontor.json_to_postgres finished')
+6 -6
View File
@@ -40,7 +40,7 @@ class Token(Base, BaseMixin):
class Permission(Base, BaseMixin): class Permission(Base, BaseMixin):
__tablename__ = "permission" __tablename__ = "permission"
name = Column(String(255), nullable=False) name = Column(String, nullable=False)
assignments = relationship("Assignment") assignments = relationship("Assignment")
@@ -54,17 +54,17 @@ class Assignment(Base, BaseMixin):
class ModuleData(Base, BaseMixin): class ModuleData(Base, BaseMixin):
__tablename__ = "module_data" __tablename__ = "module_data"
module_name = Column(String(255), nullable=False) module_name = Column(String, nullable=False)
import_data = Column(Boolean) import_data = Column(Boolean)
class MailAccount(Base, BaseMixin): class MailAccount(Base, BaseMixin):
__tablename__ = "mail_account" __tablename__ = "mail_account"
host = Column(String(255)) host = Column(String)
port = Column(Integer) port = Column(Integer)
protocol = Column(String(255)) protocol = Column(String)
user_name = Column(String(255)) user_name = Column(String)
password = Column(String(255)) password = Column(String)
start_tls = Column(Boolean) start_tls = Column(Boolean)
+7 -7
View File
@@ -10,8 +10,8 @@ class Base(DeclarativeBase):
class BaseMixin: class BaseMixin:
id = Column(String(255), primary_key=True, default=uuid.uuid4()) #id = Column(String, primary_key=True, default=uuid.uuid4)
# id: Mapped[str] = mapped_column(primary_key=True, default=uuid.uuid4()) id: Mapped[str] = mapped_column(primary_key=True, default=uuid.uuid4)
# created_date = Column(DateTime) # created_date = Column(DateTime)
created_date: Mapped[datetime] = mapped_column(default=func.now()) created_date: Mapped[datetime] = mapped_column(default=func.now())
# last_modified_date = Column(DateTime) # last_modified_date = Column(DateTime)
@@ -21,10 +21,10 @@ class BaseMixin:
class BaseVideoMixin: class BaseVideoMixin:
cloud_link = Column(String(255)) cloud_link = Column(String)
file_name = Column(String(255)) file_name = Column(String)
path = Column(String(255)) path = Column(String)
review = Column(Boolean) review = Column(Boolean)
title = Column(String(255)) title = Column(String)
url = Column(String(255), unique=True) url = Column(String, unique=True)
should_download = Column(Boolean) should_download = Column(Boolean)
+6 -6
View File
@@ -6,28 +6,28 @@ from .base import Base, BaseMixin
class Article(Base, BaseMixin): class Article(Base, BaseMixin):
__tablename__ = 'article' __tablename__ = 'article'
title = Column(String(length=255), unique=True) title = Column(String, unique=True)
article_authors = relationship("ArticleAuthor") article_authors = relationship("ArticleAuthor")
class Author(Base, BaseMixin): class Author(Base, BaseMixin):
__tablename__ = 'author' __tablename__ = 'author'
first_name = Column(String(255)) first_name = Column(String)
last_name = Column(String(255)) last_name = Column(String)
article_authors = relationship("ArticleAuthor") article_authors = relationship("ArticleAuthor")
book_authors = relationship("BookAuthor") book_authors = relationship("BookAuthor")
class BookshelfPublisher(Base, BaseMixin): class BookshelfPublisher(Base, BaseMixin):
__tablename__ = 'bookshelf_publisher' __tablename__ = 'bookshelf_publisher'
name = Column(String(length=255), unique=True) name = Column(String, unique=True)
books = relationship("Book") books = relationship("Book")
class Book(Base, BaseMixin): class Book(Base, BaseMixin):
__tablename__ = 'book' __tablename__ = 'book'
isbn = Column(String(255), unique=True) isbn = Column(String, unique=True)
title = Column(String(255)) title = Column(String)
year = Column(Integer, nullable=False) year = Column(Integer, nullable=False)
publisher_id = Column(String, ForeignKey('bookshelf_publisher.id'), nullable=False) publisher_id = Column(String, ForeignKey('bookshelf_publisher.id'), nullable=False)
publisher = relationship('BookshelfPublisher', back_populates="books") publisher = relationship('BookshelfPublisher', back_populates="books")
+8 -8
View File
@@ -6,7 +6,7 @@ from .base import Base, BaseMixin
class Publisher(Base, BaseMixin): class Publisher(Base, BaseMixin):
__tablename__ = "publisher" __tablename__ = "publisher"
name = Column(String(length=255), unique=True) name = Column(String, unique=True)
comics = relationship("Comic") comics = relationship("Comic")
def __repr__(self): def __repr__(self):
@@ -18,7 +18,7 @@ class Publisher(Base, BaseMixin):
class Comic(Base, BaseMixin): class Comic(Base, BaseMixin):
__tablename__ = 'comic' __tablename__ = 'comic'
title = Column(String(length=255), unique=True) title = Column(String, unique=True)
publisher_id = Column(String, ForeignKey('publisher.id'), nullable=False) publisher_id = Column(String, ForeignKey('publisher.id'), nullable=False)
publisher = relationship("Publisher", back_populates="comics") publisher = relationship("Publisher", back_populates="comics")
current_order = Column(Boolean) current_order = Column(Boolean)
@@ -38,7 +38,7 @@ class Comic(Base, BaseMixin):
class Volume(Base, BaseMixin): class Volume(Base, BaseMixin):
__tablename__ = "volume" __tablename__ = "volume"
name = Column(String(length=255), nullable=False) name = Column(String, nullable=False)
comic_id = Column(String, ForeignKey("comic.id"), nullable=False) comic_id = Column(String, ForeignKey("comic.id"), nullable=False)
comic = relationship("Comic", back_populates="volumes") comic = relationship("Comic", back_populates="volumes")
issues = relationship("Issue") issues = relationship("Issue")
@@ -46,7 +46,7 @@ class Volume(Base, BaseMixin):
class TradePaperback(Base, BaseMixin): class TradePaperback(Base, BaseMixin):
__tablename__ = "trade_paperback" __tablename__ = "trade_paperback"
name = Column(String(length=255), nullable=False) name = Column(String, nullable=False)
issue_start = Column(Integer) issue_start = Column(Integer)
issue_end = Column(Integer) issue_end = Column(Integer)
comic_id = Column(String, ForeignKey("comic.id"), nullable=False) comic_id = Column(String, ForeignKey("comic.id"), nullable=False)
@@ -55,14 +55,14 @@ class TradePaperback(Base, BaseMixin):
class StoryArc(Base, BaseMixin): class StoryArc(Base, BaseMixin):
__tablename__ = "story_arc" __tablename__ = "story_arc"
name = Column(String(length=255), nullable=False) name = Column(String, nullable=False)
comic_id = Column(String, ForeignKey("comic.id"), nullable=False) comic_id = Column(String, ForeignKey("comic.id"), nullable=False)
comic = relationship("Comic", back_populates="story_arcs") comic = relationship("Comic", back_populates="story_arcs")
class Issue(Base, BaseMixin): class Issue(Base, BaseMixin):
__tablename__ = "issue" __tablename__ = "issue"
issue_number = Column(String(255)) issue_number = Column(String)
in_stock = Column(Boolean) in_stock = Column(Boolean)
is_read = Column(Boolean) is_read = Column(Boolean)
comic_id = Column(String, ForeignKey("comic.id"), nullable=False) comic_id = Column(String, ForeignKey("comic.id"), nullable=False)
@@ -73,13 +73,13 @@ class Issue(Base, BaseMixin):
class Artist(Base, BaseMixin): class Artist(Base, BaseMixin):
__tablename__ = "artist" __tablename__ = "artist"
name = Column(String(length=255), nullable=False) name = Column(String, nullable=False)
comic_works = relationship("ComicWork") comic_works = relationship("ComicWork")
class WorkType(Base, BaseMixin): class WorkType(Base, BaseMixin):
__tablename__ = "worktype" __tablename__ = "worktype"
name = Column(String(length=255), nullable=False, unique=True) name = Column(String, nullable=False, unique=True)
comic_works = relationship("ComicWork") comic_works = relationship("ComicWork")
def __repr__(self): def __repr__(self):
+10 -10
View File
@@ -69,31 +69,31 @@ class MediaFile(Base, BaseMixin, BaseVideoMixin):
class MediaActor(Base, BaseMixin): class MediaActor(Base, BaseMixin):
__tablename__ = 'media_actor' __tablename__ = 'media_actor'
name = Column(String(255)) name = Column(String)
media_actor_files = relationship("MediaActorFile") media_actor_files = relationship("MediaActorFile")
class MediaActorFile(Base, BaseMixin): class MediaActorFile(Base, BaseMixin):
__tablename__ = 'media_actor_file' __tablename__ = 'media_actor_file'
media_actor_id = Column(String(255), ForeignKey("media_actor.id"), nullable=False) media_actor_id = Column(String, ForeignKey("media_actor.id"), nullable=False)
media_actor = relationship("MediaActor", back_populates="media_actor_files") media_actor = relationship("MediaActor", back_populates="media_actor_files")
media_file_id = Column(String(255), ForeignKey("media_file.id"), nullable=True) media_file_id = Column(String, ForeignKey("media_file.id"), nullable=True)
media_file = relationship("MediaFile", back_populates="media_actor_files") media_file = relationship("MediaFile", back_populates="media_actor_files")
class MediaArticle(Base, BaseMixin): class MediaArticle(Base, BaseMixin):
__tablename__ = 'media_article' __tablename__ = 'media_article'
review = Column(Boolean) review = Column(Boolean)
title = Column(String(255)) title = Column(String)
url = Column(String(255), unique=True) url = Column(String, unique=True)
class MediaVideo(Base, BaseMixin): class MediaVideo(Base, BaseMixin):
__tablename__ = 'media_video' __tablename__ = 'media_video'
cloud_link = Column(String(255)) cloud_link = Column(String)
file_name = Column(String(255)) file_name = Column(String)
path = Column(String(255)) path = Column(String)
review = Column(Boolean) review = Column(Boolean)
title = Column(String(255)) title = Column(String)
url = Column(String(255), unique=True) url = Column(String, unique=True)
should_download = Column(Boolean) should_download = Column(Boolean)
+7 -7
View File
@@ -6,7 +6,7 @@ from .base import Base, BaseMixin
class MetaDataTable(Base, BaseMixin): class MetaDataTable(Base, BaseMixin):
__tablename__ = 'meta_data_table' __tablename__ = 'meta_data_table'
table_name = Column(String(255), unique=True) table_name = Column(String, unique=True)
table_columns = relationship("MetaDataColumn") table_columns = relationship("MetaDataColumn")
def __repr__(self): def __repr__(self):
@@ -18,15 +18,15 @@ class MetaDataTable(Base, BaseMixin):
class MetaDataColumn(Base, BaseMixin): class MetaDataColumn(Base, BaseMixin):
__tablename__ = 'meta_data_column' __tablename__ = 'meta_data_column'
column_name = Column(String(255), nullable=False) column_name = Column(String, nullable=False)
column_sync_name = Column(String(255)) column_sync_name = Column(String)
column_type = Column(String(255)) column_type = Column(String)
column_modifier = Column(String(255), nullable=True) column_modifier = Column(String, nullable=True)
column_order = Column(Integer) column_order = Column(Integer)
table_id = Column(String, ForeignKey('meta_data_table.id')) table_id = Column(String, ForeignKey('meta_data_table.id'))
table = relationship("MetaDataTable", back_populates="table_columns") table = relationship("MetaDataTable", back_populates="table_columns")
column_label = Column(String(255)) column_label = Column(String)
filter_label = Column(String(255)) filter_label = Column(String)
is_shown = Column(Boolean) is_shown = Column(Boolean)
show_filter = Column(Boolean) show_filter = Column(Boolean)
ref_column = Column(String, nullable=True) ref_column = Column(String, nullable=True)
+9 -9
View File
@@ -9,15 +9,15 @@ class Sport(Base, BaseMixin):
__table_args__ = ( __table_args__ = (
UniqueConstraint("name"), UniqueConstraint("name"),
) )
name = Column(String(255), nullable=False, index=True, unique=True) name = Column(String, nullable=False, index=True, unique=True)
teams = relationship("Team") teams = relationship("Team")
positions = relationship("FieldPosition") positions = relationship("FieldPosition")
class Team(Base, BaseMixin): class Team(Base, BaseMixin):
__tablename__ = "team" __tablename__ = "team"
name = Column(String(255), nullable=False, index=True, unique=True) name = Column(String, nullable=False, index=True, unique=True)
short_name = Column(String(255), nullable=False, ) short_name = Column(String, nullable=False, )
sport_id = Column(String, ForeignKey("sport.id"), nullable=False) sport_id = Column(String, ForeignKey("sport.id"), nullable=False)
sport = relationship("Sport", back_populates="teams") sport = relationship("Sport", back_populates="teams")
roosters = relationship("Rooster") roosters = relationship("Rooster")
@@ -29,8 +29,8 @@ class FieldPosition(Base, BaseMixin):
UniqueConstraint("name", "sport_id"), UniqueConstraint("name", "sport_id"),
UniqueConstraint("short_name", "sport_id"), UniqueConstraint("short_name", "sport_id"),
) )
name = Column(String(255), nullable=False, index=True) name = Column(String, nullable=False, index=True)
short_name = Column(String(255), nullable=False) short_name = Column(String, nullable=False)
sport_id = Column(String, ForeignKey("sport.id"), nullable=False, index=True) sport_id = Column(String, ForeignKey("sport.id"), nullable=False, index=True)
sport = relationship("Sport", back_populates="positions") sport = relationship("Sport", back_populates="positions")
roosters = relationship("Rooster") roosters = relationship("Rooster")
@@ -41,8 +41,8 @@ class Player(Base, BaseMixin):
__table_args__ = ( __table_args__ = (
UniqueConstraint("first_name", "last_name"), UniqueConstraint("first_name", "last_name"),
) )
first_name = Column(String(255), nullable=False, index=True) first_name = Column(String, nullable=False, index=True)
last_name = Column(String(255), nullable=False, index=True) last_name = Column(String, nullable=False, index=True)
roosters = relationship("Rooster") roosters = relationship("Rooster")
def get_full_name(self) -> str: def get_full_name(self) -> str:
@@ -66,7 +66,7 @@ class Rooster(Base, BaseMixin):
class Vendor(Base, BaseMixin): class Vendor(Base, BaseMixin):
__tablename__ = "vendor" __tablename__ = "vendor"
name = Column(String(255), nullable=False, unique=True, index=True) name = Column(String, nullable=False, unique=True, index=True)
card_sets = relationship("CardSet") card_sets = relationship("CardSet")
cards = relationship("Card") cards = relationship("Card")
@@ -76,7 +76,7 @@ class CardSet(Base, BaseMixin):
__table_args__ = ( __table_args__ = (
UniqueConstraint("name", "vendor_id"), UniqueConstraint("name", "vendor_id"),
) )
name = Column(String(255), index=True) name = Column(String, index=True)
parallel_set = Column(Boolean) parallel_set = Column(Boolean)
insert_set = Column(Boolean) insert_set = Column(Boolean)
vendor_id = Column(String, ForeignKey("vendor.id"), nullable=False, index=True) vendor_id = Column(String, ForeignKey("vendor.id"), nullable=False, index=True)
@@ -66,4 +66,9 @@ public class MetaDataColumn extends AbstractEntity {
} }
return "no changes for " + this.getId() + "\n"; return "no changes for " + this.getId() + "\n";
} }
@Override
public String toString() {
return "MetaDataColumn{id=" + getId() + ", columnName=" + columnName + ", table=" + table.getTableName() +'}';
}
} }
@@ -12,6 +12,8 @@ public interface MetaDataColumnRepository extends JpaRepository<MetaDataColumn,
List<MetaDataColumn> findByTable(MetaDataTable table); List<MetaDataColumn> findByTable(MetaDataTable table);
List<MetaDataColumn> findByTableAndColumnName(MetaDataTable table, String column_name);
@Query("select m from MetaDataColumn m " + @Query("select m from MetaDataColumn m " +
"where lower(m.columnName) like lower(concat('%', :searchTerm, '%')) or lower(m.columnLabel) like lower(concat('%', :searchTerm, '%'))") "where lower(m.columnName) like lower(concat('%', :searchTerm, '%')) or lower(m.columnLabel) like lower(concat('%', :searchTerm, '%'))")
List<MetaDataColumn> search(@Param("searchTerm") String searchTerm); List<MetaDataColumn> search(@Param("searchTerm") String searchTerm);
@@ -67,61 +67,73 @@ public class MetaDataService {
this.getColumn(table, columnName, columnSyncName, columnType, columnModifier, columnOrder, isShown, columnLabel, showFilter, filterLabel, null); this.getColumn(table, columnName, columnSyncName, columnType, columnModifier, columnOrder, isShown, columnLabel, showFilter, filterLabel, null);
} }
public void checkColumnValues(MetaDataTable table, MetaDataColumn column, String columnName, String columnSyncName, String columnType, String columnModifier, Integer columnOrder, Boolean isShown, String columnLabel, Boolean showFilter, String filterLabel, String refColumn) {
log.debug("Column {} with name {} of table {} found, check Values", columnOrder, columnName, table.getTableName());
if (!column.getColumnName().equals(columnName)) {
log.debug("columnName has to be changed to {}", columnName);
column.setColumnName(columnName);
}
if (!column.getColumnSyncName().equals(columnSyncName)) {
log.debug("columnSyncName has to be changed to {}", columnSyncName);
column.setColumnSyncName(columnSyncName);
}
if (!column.getColumnType().equals(columnType)) {
log.debug("columnType has to be changed to {}", columnType);
column.setColumnType(columnType);
}
if (columnModifier != null && !columnModifier.equals(column.getColumnModifier())) {
log.debug("columnModifier has to be changed to {}", columnModifier);
column.setColumnModifier(columnModifier);
}
if (isShown != null && !isShown.equals(column.getIsShown())) {
log.debug("isShown has to be change to {}}", isShown);
column.setIsShown(isShown);
}
if (columnLabel != null && !columnLabel.equals(column.getColumnLabel())) {
log.debug("columnLabel has to be change to {}}", columnLabel);
column.setColumnLabel(columnLabel);
}
if (showFilter != null &&!showFilter.equals(column.getShowFilter())) {
log.debug("showFilter has to be change to {}}", showFilter);
column.setShowFilter(showFilter);
}
if (filterLabel != null && !filterLabel.equals(column.getFilterLabel())) {
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);
}
saveMetaDataColumn(column);
}
public void getColumn(MetaDataTable table, String columnName, String columnSyncName, String columnType, String columnModifier, Integer columnOrder, Boolean isShown, String columnLabel, Boolean showFilter, String filterLabel, String refColumn) { public void getColumn(MetaDataTable table, String columnName, String columnSyncName, String columnType, String columnModifier, Integer columnOrder, Boolean isShown, String columnLabel, Boolean showFilter, String filterLabel, String refColumn) {
if (table.getTableColumns().stream().anyMatch(column -> column.getColumnName().equals(columnName))) { log.info("check if column {} of table {} exists", columnName, table.getTableName());
log.debug("Column {} with name {} of table {} found, check Values", columnOrder, columnName, table.getTableName()); boolean columnNameExists = table.getTableColumns().stream().anyMatch(column -> column.getColumnName().equals(columnName));
MetaDataColumn column = table.getTableColumns().get(columnOrder.intValue()-1); boolean columnOrderExists = table.getTableColumns().get(columnOrder-1) != null;
if (!column.getColumnName().equals(columnName)) { List<MetaDataColumn> metaDataColumns = metaDataColumnRepository.findByTableAndColumnName(table, columnName);
log.debug("columnName has to be changed to {}", columnName); log.debug("column found: name: {}, order: {}: table.columns: {}", columnNameExists, columnOrderExists, metaDataColumns);
column.setColumnName(columnName); if (columnOrderExists) {
} MetaDataColumn column = table.getTableColumns().get(columnOrder-1);
if (!column.getColumnSyncName().equals(columnSyncName)) { checkColumnValues(table, column, columnName, columnSyncName, columnType, columnModifier, columnOrder, isShown, columnLabel, showFilter, filterLabel, refColumn);
log.debug("columnSyncName has to be changed to {}", columnSyncName);
column.setColumnSyncName(columnSyncName);
}
if (!column.getColumnType().equals(columnType)) {
log.debug("columnType has to be changed to {}", columnType);
column.setColumnType(columnType);
}
if (columnModifier != null && !columnModifier.equals(column.getColumnModifier())) {
log.debug("columnModifier has to be changed to {}", columnModifier);
column.setColumnModifier(columnModifier);
}
if (isShown != null && !isShown.equals(column.getIsShown())) {
log.debug("isShown has to be change to {}}", isShown);
column.setIsShown(isShown);
}
if (columnLabel != null && !columnLabel.equals(column.getColumnLabel())) {
log.debug("columnLabel has to be change to {}}", columnLabel);
column.setColumnLabel(columnLabel);
}
if (showFilter != null &&!showFilter.equals(column.getShowFilter())) {
log.debug("showFilter has to be change to {}}", showFilter);
column.setShowFilter(showFilter);
}
if (filterLabel != null && !filterLabel.equals(column.getFilterLabel())) {
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 { } else {
log.info("Column {} of table {} not found, will create it", columnName, table.getTableName()); log.info("Column {} of table {} not found, will create it", columnName, table.getTableName());
MetaDataColumn column = new MetaDataColumn(); //addColumn(table,columnName,columnSyncName,columnType,columnModifier,columnOrder,isShown);
column.setTable(table);
column.setColumnName(columnName);
column.setColumnSyncName(columnSyncName);
column.setColumnType(columnType);
column.setColumnModifier(columnModifier);
column.setColumnOrder(columnOrder);
column.setIsShown(Boolean.FALSE);
metaDataColumnRepository.save(column);
} }
} }
private void addColumn(MetaDataTable table, String columnName, String columnSyncName, String columnType, String columnModifier, Integer columnOrder, Boolean isShown) {
MetaDataColumn column = new MetaDataColumn();
column.setTable(table);
column.setColumnName(columnName);
column.setColumnSyncName(columnSyncName);
column.setColumnType(columnType);
column.setColumnModifier(columnModifier);
column.setColumnOrder(columnOrder);
column.setIsShown(isShown);
saveMetaDataColumn(column);
}
public List<MetaDataColumn> findAllMetaDataColumns(String stringFilter) { public List<MetaDataColumn> findAllMetaDataColumns(String stringFilter) {
if (stringFilter == null || stringFilter.isEmpty()) { if (stringFilter == null || stringFilter.isEmpty()) {
@@ -118,7 +118,7 @@ public class IssueView extends VerticalLayout {
menuButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY); menuButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
ColumnToggleContextMenu<Issue> columnToggleContextMenu = new ColumnToggleContextMenu<>(menuButton); ColumnToggleContextMenu<Issue> columnToggleContextMenu = new ColumnToggleContextMenu<>(menuButton);
columnToggleContextMenu.addColumnToggleItem(idColumn); columnToggleContextMenu.addColumnToggleItem(idColumn);
columnToggleContextMenu.addColumnToggleItem(createdColumn); columnToggleContextMenu.addColumnToggleItem(createdColumn);
columnToggleContextMenu.addColumnToggleItem(modifiedColumn); columnToggleContextMenu.addColumnToggleItem(modifiedColumn);
columnToggleContextMenu.addColumnToggleItem(versionColumn); columnToggleContextMenu.addColumnToggleItem(versionColumn);
columnToggleContextMenu.addColumnToggleItem(titleColumn); columnToggleContextMenu.addColumnToggleItem(titleColumn);
@@ -38,4 +38,8 @@ public class CardSet extends AbstractEntity {
private boolean parallelSet = false; private boolean parallelSet = false;
private boolean insertSet = false; private boolean insertSet = false;
public String getVendorName() {
return vendor.getName();
}
} }
@@ -21,7 +21,6 @@ import lombok.ToString;
*/ */
@Getter @Getter
@Setter @Setter
@ToString
@EqualsAndHashCode(callSuper=false) @EqualsAndHashCode(callSuper=false)
@Entity @Entity
@Table(indexes = {@Index(columnList = "name")}, @Table(indexes = {@Index(columnList = "name")},
@@ -35,4 +34,9 @@ public class Vendor extends AbstractEntity {
@OneToMany(fetch = FetchType.EAGER, mappedBy = "vendor") @OneToMany(fetch = FetchType.EAGER, mappedBy = "vendor")
@Nullable @Nullable
private List<CardSet> cardSets; private List<CardSet> cardSets;
@Override
public String toString() {
return "Vendor{id=" + this.getId() + ", name=" + name + '}';
}
} }
@@ -1,9 +1,12 @@
package de.thpeetz.kontor.tysc.views; package de.thpeetz.kontor.tysc.views;
import com.vaadin.flow.component.button.*;
import de.thpeetz.kontor.comics.data.*;
import de.thpeetz.kontor.common.views.*;
import lombok.*;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import com.vaadin.flow.component.Component; import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.grid.Grid; import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout; import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout; import com.vaadin.flow.component.orderedlayout.VerticalLayout;
@@ -13,12 +16,13 @@ import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route; import com.vaadin.flow.router.Route;
import com.vaadin.flow.spring.annotation.SpringComponent; import com.vaadin.flow.spring.annotation.SpringComponent;
import de.thpeetz.kontor.common.views.MainLayout;
import de.thpeetz.kontor.tysc.TyscConstants; import de.thpeetz.kontor.tysc.TyscConstants;
import de.thpeetz.kontor.tysc.data.CardSet; import de.thpeetz.kontor.tysc.data.CardSet;
import de.thpeetz.kontor.tysc.services.CardService; import de.thpeetz.kontor.tysc.services.CardService;
import jakarta.annotation.security.PermitAll; import jakarta.annotation.security.PermitAll;
import java.util.*;
@SpringComponent @SpringComponent
@Scope("prototype") @Scope("prototype")
@PermitAll @PermitAll
@@ -26,8 +30,26 @@ import jakarta.annotation.security.PermitAll;
@PageTitle("CardSet | Tysc | Kontor") @PageTitle("CardSet | Tysc | Kontor")
public class CardSetView extends VerticalLayout { public class CardSetView extends VerticalLayout {
Grid<CardSet> grid = new Grid<>(CardSet.class); @Getter
Grid<CardSet> grid = new Grid<>(CardSet.class, false);
Grid.Column<CardSet> idColumn = grid.addColumn(CardSet::getId)
.setHeader("ID").setResizable(true).setSortable(true);
Grid.Column<CardSet> createdColumn = grid.addColumn(CardSet::getCreatedDate)
.setHeader("Erstellt").setResizable(true).setSortable(true);
Grid.Column<CardSet> modifiedColumn = grid.addColumn(CardSet::getLastModifiedDate)
.setHeader("Geändert").setResizable(true).setSortable(true);
Grid.Column<CardSet> versionColumn = grid.addColumn(CardSet::getVersion)
.setHeader("Version").setResizable(true).setSortable(true);
Grid.Column<CardSet> nameColumn = grid.addColumn(CardSet::getName)
.setHeader("Comic").setResizable(true).setSortable(true);
Grid.Column<CardSet> vendorNameColumn = grid.addColumn(CardSet::getVendorName)
.setHeader("Hersteller").setResizable(true).setSortable(true);
Grid.Column<CardSet> parallelSetColumn = grid.addComponentColumn(parallelSet -> StatusIcon.create(parallelSet.isParallelSet()))
.setHeader("Parallelset?").setWidth("6rem").setSortable(true);
Grid.Column<CardSet> insertSetColumn = grid.addComponentColumn(insertSet -> StatusIcon.create(insertSet.isInsertSet()))
.setHeader("Parallelset?").setWidth("6rem").setSortable(true);
TextField filterText = new TextField(); TextField filterText = new TextField();
@Getter
CardSetForm form; CardSetForm form;
CardService service; CardService service;
@@ -42,22 +64,18 @@ public class CardSetView extends VerticalLayout {
updateList(); updateList();
} }
public Grid<CardSet> getGrid() {
return grid;
}
private void configureGrid() { private void configureGrid() {
grid.addClassName("cardSet-grid"); grid.addClassName("cardSet-grid");
grid.setSizeFull(); grid.setSizeFull();
grid.setColumns("name", "vendor.name", "parallelSet", "insertSet"); //grid.setColumns("name", "vendor.name", "parallelSet", "insertSet");
grid.getColumns().forEach(col -> col.setAutoWidth(true)); grid.getColumns().forEach(col -> col.setAutoWidth(true));
idColumn.setVisible(false);
createdColumn.setVisible(false);
modifiedColumn.setVisible(false);
versionColumn.setVisible(false);
grid.asSingleSelect().addValueChangeListener(event -> editCardSet(event.getValue())); grid.asSingleSelect().addValueChangeListener(event -> editCardSet(event.getValue()));
} }
public CardSetForm getForm() {
return form;
}
private void configureForm() { private void configureForm() {
form = new CardSetForm(); form = new CardSetForm();
form.setWidth("25em"); form.setWidth("25em");
@@ -67,18 +85,6 @@ public class CardSetView extends VerticalLayout {
form.addCloseListener(e -> closeEditor()); form.addCloseListener(e -> closeEditor());
} }
private void saveCardSet(CardSetForm.SaveEvent event) {
service.saveCardSet(event.getCardSet());
updateList();
closeEditor();
}
private void deleteCardSet(CardSetForm.DeleteEvent event) {
service.deleteCardSet(event.getCardSet());
updateList();
closeEditor();
}
private Component getContent() { private Component getContent() {
HorizontalLayout content = new HorizontalLayout(grid, form); HorizontalLayout content = new HorizontalLayout(grid, form);
content.setFlexGrow(2, grid); content.setFlexGrow(2, grid);
@@ -97,11 +103,34 @@ public class CardSetView extends VerticalLayout {
Button addCardSetButton = new Button("Add cardSet"); Button addCardSetButton = new Button("Add cardSet");
addCardSetButton.addClickListener(click -> addCardSet()); addCardSetButton.addClickListener(click -> addCardSet());
HorizontalLayout toolbar = new HorizontalLayout(filterText, addCardSetButton); Button menuButton = new Button("Show/Hide Columns");
menuButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
ColumnToggleContextMenu<CardSet> columnToggleContextMenu = new ColumnToggleContextMenu<>(menuButton);
columnToggleContextMenu.addColumnToggleItem(idColumn);
columnToggleContextMenu.addColumnToggleItem(createdColumn);
columnToggleContextMenu.addColumnToggleItem(modifiedColumn);
columnToggleContextMenu.addColumnToggleItem(versionColumn);
columnToggleContextMenu.addColumnToggleItem(nameColumn);
columnToggleContextMenu.addColumnToggleItem(vendorNameColumn);
columnToggleContextMenu.addColumnToggleItem(parallelSetColumn);
columnToggleContextMenu.addColumnToggleItem(insertSetColumn);
HorizontalLayout toolbar = new HorizontalLayout(filterText, addCardSetButton, menuButton);
toolbar.addClassName("toolbar"); toolbar.addClassName("toolbar");
return toolbar; return toolbar;
} }
private void saveCardSet(CardSetForm.SaveEvent event) {
service.saveCardSet(event.getCardSet());
updateList();
closeEditor();
}
private void deleteCardSet(CardSetForm.DeleteEvent event) {
service.deleteCardSet(event.getCardSet());
updateList();
closeEditor();
}
public void editCardSet(CardSet cardSet) { public void editCardSet(CardSet cardSet) {
if (cardSet == null) { if (cardSet == null) {
closeEditor(); closeEditor();
@@ -51,7 +51,6 @@ public class CardView extends VerticalLayout {
.setHeader("Inserts").setWidth("6rem").setSortable(true); .setHeader("Inserts").setWidth("6rem").setSortable(true);
Grid.Column<Card> parallelSetColumn = grid.addComponentColumn(card -> StatusIcon.create(card.getCardSet().isParallelSet())) Grid.Column<Card> parallelSetColumn = grid.addComponentColumn(card -> StatusIcon.create(card.getCardSet().isParallelSet()))
.setHeader("Parallels").setWidth("6rem").setSortable(true); .setHeader("Parallels").setWidth("6rem").setSortable(true);
Grid.Column<Card> playerColumn = grid.addColumn(Card::getPlayerName).setHeader("Spieler").setResizable(true).setSortable(true); Grid.Column<Card> playerColumn = grid.addColumn(Card::getPlayerName).setHeader("Spieler").setResizable(true).setSortable(true);
TextField filterText = new TextField(); TextField filterText = new TextField();
@Getter @Getter
@@ -128,9 +127,10 @@ public class CardView extends VerticalLayout {
columnToggleContextMenu.addColumnToggleItem(yearColumn); columnToggleContextMenu.addColumnToggleItem(yearColumn);
columnToggleContextMenu.addColumnToggleItem(vendorColumn); columnToggleContextMenu.addColumnToggleItem(vendorColumn);
columnToggleContextMenu.addColumnToggleItem(cardSetColumn); columnToggleContextMenu.addColumnToggleItem(cardSetColumn);
columnToggleContextMenu.addColumnToggleItem(insertSetColumn);
columnToggleContextMenu.addColumnToggleItem(parallelSetColumn);
columnToggleContextMenu.addColumnToggleItem(playerColumn); columnToggleContextMenu.addColumnToggleItem(playerColumn);
HorizontalLayout toolbar = new HorizontalLayout(filterText, addCardButton, menuButton); HorizontalLayout toolbar = new HorizontalLayout(filterText, addCardButton, menuButton);
toolbar.addClassName("toolbar"); toolbar.addClassName("toolbar");
return toolbar; return toolbar;
} }