Skip to content

Commit

Permalink
Rename manga info to alt title
Browse files Browse the repository at this point in the history
  • Loading branch information
ThirVondukr committed Feb 23, 2024
1 parent eb1f56f commit f1cb20b
Show file tree
Hide file tree
Showing 10 changed files with 181 additions and 61 deletions.
9 changes: 6 additions & 3 deletions src/app/adapters/cli/seed.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
import random

from sqlalchemy import delete
from tests.factories import MangaFactory, MangaTagFactory
from tests.factories import MangaAltTitleFactory, MangaFactory, MangaTagFactory

from app.db import async_session_factory
from app.db.models import Manga, MangaTag
from app.db.models import AltTitle, Manga, MangaTag


async def main() -> None:
async with async_session_factory.begin() as session:
for model in [MangaTag, Manga]:
for model in [MangaTag, Manga, AltTitle]:
await session.execute(delete(model))

async with async_session_factory.begin() as session:
Expand All @@ -22,6 +22,9 @@ async def main() -> None:
tags,
k=random.randint(1, 5), # noqa: S311
)
manga.alt_titles = MangaAltTitleFactory.build_batch(
size=random.randint(1, 3), # noqa: S311
)

session.add_all(mangas)
await session.flush()
Expand Down
18 changes: 6 additions & 12 deletions src/app/adapters/graphql/apps/manga/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from app.adapters.graphql.types import LanguageGQL
from app.core.domain.manga.loaders import MangaTagLoader
from app.db.models import Manga
from app.db.models._manga import MangaInfo, MangaTag
from app.db.models._manga import AltTitle, MangaTag


@strawberry.federation.type(name="MangaTag")
Expand All @@ -28,20 +28,18 @@ def from_dto(cls, model: MangaTag) -> Self:
)


@strawberry.type(name="MangaInfo")
class MangaInfoGQL(DTOMixin[MangaInfo]):
@strawberry.type(name="AltTitle")
class AltTitleGQL(DTOMixin[AltTitle]):
id: strawberry.ID
language: LanguageGQL
title: str
description: str

@classmethod
def from_dto(cls, model: MangaInfo) -> Self:
def from_dto(cls, model: AltTitle) -> Self:
return cls(
id=strawberry.ID(str(model.id)),
language=LanguageGQL(model.language.value),
title=model.title,
description=model.description,
)


Expand Down Expand Up @@ -77,11 +75,7 @@ async def tags(
return MangaTagGQL.from_dto_list(tags)

# @strawberry.field
# async def infos(
# self,
# info: Info,
# preferred_languages: list[LanguageGQL] | None = None,
# ) -> list[MangaInfoGQL]:
# async def infos(self, info: Info) -> Sequence[AltTitleGQL]:
# preferred_languages = preferred_languages or []
# preferred_languages = [Language[lang.value] for lang in preferred_languages]
# infos = await info.context.loaders.manga_info_by_manga_id.load(self.id)
Expand All @@ -94,7 +88,7 @@ async def tags(
# )
# infos = preferred_infos or infos
#
# return MangaInfoGQL.from_orm_list(infos)
# return AltTitleGQL.from_orm_list(infos)

#
# @strawberry.field
Expand Down
7 changes: 6 additions & 1 deletion src/app/core/di/_modules/manga.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
from aioinject import Scoped

from app.core.domain.manga.commands import MangaCreateCommand
from app.core.domain.manga.loaders import MangaLoader, MangaTagLoader
from app.core.domain.manga.loaders import (
MangaInfoLoader,
MangaLoader,
MangaTagLoader,
)
from app.core.domain.manga.queries import MangaSearchQuery
from app.core.domain.manga.repositories import MangaRepository
from app.core.domain.manga.services import MangaService
Expand All @@ -14,4 +18,5 @@
Scoped(MangaLoader),
Scoped(MangaCreateCommand),
Scoped(MangaTagLoader),
Scoped(MangaInfoLoader),
]
68 changes: 42 additions & 26 deletions src/app/core/domain/manga/loaders.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
from sqlalchemy import Select, select
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import QueryableAttribute
from sqlalchemy.sql.elements import SQLCoreOperations

from app.db.models import Manga, MangaTag
from app.db.models import AltTitle, Manga, MangaTag
from app.db.models._manga import manga_manga_tag_secondary_table
from lib.loaders import LoaderProtocol

Expand All @@ -33,35 +34,50 @@ async def execute(self, keys: Sequence[K]) -> Sequence[V | None]:
return [models.get(key) for key in keys]


class SQLAListLoader(LoaderProtocol[K, Sequence[V]], Protocol):
column: SQLCoreOperations[K]
stmt: Select[tuple[K, V]]

_session: AsyncSession

def __init__(self, session: AsyncSession) -> None:
self._session = session

async def execute(self, keys: Sequence[K]) -> Sequence[Sequence[V]]:
stmt = self.stmt.where(self.__class__.column.in_(keys))
models = collections.defaultdict(list)
for key, model in await self._session.execute(stmt):
models[key].append(model)
return [models[key] for key in keys]


class MangaInfoLoader(SQLAListLoader[UUID, AltTitle]):
column = Manga.id
stmt = (
select(Manga.id, AltTitle)
.join(AltTitle.manga)
.order_by(AltTitle.language)
)


@final
class MangaLoader(SQLALoader[UUID, Manga]):
column = Manga.id
stmt = select(Manga)


class MangaTagLoader(LoaderProtocol[UUID, Sequence[MangaTag]]):
def __init__(self, session: AsyncSession) -> None:
self._session = session

async def execute(
self,
keys: Sequence[UUID],
) -> Sequence[Sequence[MangaTag]]:
stmt = (
select(
manga_manga_tag_secondary_table.c.manga_id,
MangaTag,
)
.join(
manga_manga_tag_secondary_table,
manga_manga_tag_secondary_table.c.tag_id == MangaTag.id,
)
.order_by(
MangaTag.name_slug,
)
class MangaTagLoader(SQLAListLoader[UUID, MangaTag]):
column = manga_manga_tag_secondary_table.c.manga_id
stmt = (
select(
manga_manga_tag_secondary_table.c.manga_id,
MangaTag,
)
tags = collections.defaultdict(list)
for manga_id, tag in await self._session.execute(stmt):
tags[manga_id].append(tag)

return [tags[key] for key in keys]
.join(
manga_manga_tag_secondary_table,
manga_manga_tag_secondary_table.c.tag_id == MangaTag.id,
)
.order_by(
MangaTag.name_slug,
)
)
10 changes: 5 additions & 5 deletions src/app/core/domain/manga/repositories.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import aliased

from app.db.models import Manga, MangaInfo, MangaTag
from app.db.models import AltTitle, Manga, MangaTag
from lib.pagination.pagination import (
PagePaginationParamsDTO,
PagePaginationResultDTO,
Expand Down Expand Up @@ -44,13 +44,13 @@ def _filter_stmt(self, filter: MangaFilter) -> Select[tuple[Manga]]:
if filter.search_term:
search_term = func.plainto_tsquery(filter.search_term)
stmt = (
stmt.join(Manga.info, isouter=True)
.group_by(MangaInfo.search_ts_vector)
.where(MangaInfo.search_ts_vector.op("@@")(search_term))
stmt.join(Manga.alt_titles, isouter=True)
.group_by(AltTitle.search_ts_vector)
.where(AltTitle.search_ts_vector.op("@@")(search_term))
.order_by(None)
.order_by(
func.ts_rank_cd(
MangaInfo.search_ts_vector,
AltTitle.search_ts_vector,
search_term,
).desc(),
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
"""
Remove descripton from manga info
Revision ID: 7f9bdf00c25c
Revises: cddc6a963387
Create Date: 2024-02-24 02:38:51.709703
"""

import sqlalchemy as sa
from alembic import op
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision = "7f9bdf00c25c"
down_revision: str | None = "cddc6a963387"
branch_labels: str | None = None
depends_on: str | None = None


def upgrade() -> None:

op.drop_column("manga_info", "search_ts_vector")
op.drop_column("manga_info", "description")
op.add_column(
"manga_info",
sa.Column(
"search_ts_vector",
postgresql.TSVECTOR(),
sa.Computed(
"to_tsvector(language_regconfig, coalesce(title, ''))",
persisted=True,
),
nullable=False,
),
)

op.rename_table("manga_info", "manga_alt_title")
op.drop_index("ix_manga_info_manga_id", table_name="manga_alt_title")
op.create_index(
op.f("ix_manga_alt_title_manga_id"),
"manga_alt_title",
["manga_id"],
unique=False,
)
op.create_index(
"ix_manga_info_search_ts_vector",
"manga_alt_title",
["search_ts_vector"],
unique=False,
postgresql_using="gin",
)


def downgrade() -> None:
op.drop_index(
"ix_manga_info_search_ts_vector",
table_name="manga_alt_title",
postgresql_using="gin",
)
op.drop_index(
op.f("ix_manga_alt_title_manga_id"),
table_name="manga_alt_title",
)
op.create_index(
"ix_manga_info_manga_id",
"manga_alt_title",
["manga_id"],
unique=False,
)
op.rename_table("manga_alt_title", "manga_info")
op.add_column(
"manga_info",
sa.Column(
"description",
sa.VARCHAR(length=1000),
autoincrement=False,
nullable=False,
server_default="",
),
)
op.alter_column("manga_info", "description", server_default=None)
op.drop_column("manga_info", "search_ts_vector")
op.add_column(
"manga_info",
sa.Column(
"search_ts_vector",
postgresql.TSVECTOR(),
sa.Computed(
"setweight(to_tsvector(language_regconfig, coalesce(title, '')), 'A') || setweight(to_tsvector(language_regconfig, coalesce(description, '')), 'D')",
persisted=True,
),
nullable=False,
),
)
4 changes: 2 additions & 2 deletions src/app/db/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from ._manga import (
AltTitle,
Manga,
MangaBranch,
MangaChapter,
MangaInfo,
MangaPage,
MangaTag,
)
Expand All @@ -12,7 +12,7 @@
"Manga",
"MangaBranch",
"MangaChapter",
"MangaInfo",
"AltTitle",
"MangaPage",
"MangaTag",
"User",
Expand Down
19 changes: 11 additions & 8 deletions src/app/db/models/_manga.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class Manga(
back_populates="manga",
default_factory=list,
)
info: Mapped[list[MangaInfo]] = relationship(
alt_titles: Mapped[list[AltTitle]] = relationship(
back_populates="manga",
default_factory=list,
)
Expand Down Expand Up @@ -140,17 +140,19 @@ class MangaPage(PkUUID, MappedAsDataclass, Base, kw_only=True):


def _regconfig_default(ctx: DefaultExecutionContext) -> str:
return RegConfigLanguage[ctx.current_parameters["language"].value].value # type: ignore[index]
return RegConfigLanguage[
ctx.current_parameters["language"].value # type: ignore[index]
].value


class MangaInfo(
class AltTitle(
PkUUID,
HasTimestamps,
MappedAsDataclass,
Base,
kw_only=True,
):
__tablename__ = "manga_info"
__tablename__ = "manga_alt_title"
__table_args__ = (
Index(
"ix_manga_info_search_ts_vector",
Expand All @@ -164,20 +166,21 @@ class MangaInfo(
index=True,
default=None,
)
manga: Mapped[Manga] = relationship(back_populates="info", default=None)
manga: Mapped[Manga] = relationship(
back_populates="alt_titles",
default=None,
)
language: Mapped[Language]
language_regconfig: Mapped[str] = mapped_column(
REGCONFIG,
insert_default=_regconfig_default,
init=False,
)
title: Mapped[str] = mapped_column(String(250))
description: Mapped[str] = mapped_column(String(1000))
search_ts_vector: Mapped[str] = mapped_column(
TSVECTOR,
Computed(
"setweight(to_tsvector(language_regconfig, coalesce(title, '')), 'A') || "
"setweight(to_tsvector(language_regconfig, coalesce(description, '')), 'D')",
"to_tsvector(language_regconfig, coalesce(title, '')",
persisted=True,
),
init=False,
Expand Down
Loading

0 comments on commit f1cb20b

Please sign in to comment.