byceps/byceps

View on GitHub
byceps/services/board/board_category_query_service.py

Summary

Maintainability
A
0 mins
Test Coverage
B
89%
"""
byceps.services.board.board_category_query_service
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:Copyright: 2014-2024 Jochen Kupperschmidt
:License: Revised BSD (see `LICENSE` file for details)
"""

from sqlalchemy import select

from byceps.database import db

from .dbmodels.category import DbBoardCategory
from .models import (
    BoardCategory,
    BoardCategoryID,
    BoardCategoryWithLastUpdate,
    BoardID,
)


def count_categories_for_board(board_id: BoardID) -> int:
    """Return the number of categories for that board."""
    return (
        db.session.scalar(
            select(db.func.count(DbBoardCategory.id)).filter_by(
                board_id=board_id
            )
        )
        or 0
    )


def find_category_by_id(
    category_id: BoardCategoryID,
) -> BoardCategory | None:
    """Return the category with that id, or `None` if not found."""
    db_category = db.session.get(DbBoardCategory, category_id)

    if db_category is None:
        return None

    return _db_entity_to_category(db_category)


def find_category_by_slug(board_id: BoardID, slug: str) -> BoardCategory | None:
    """Return the category for that board and slug, or `None` if not found."""
    db_category = db.session.scalars(
        select(DbBoardCategory)
        .filter_by(board_id=board_id)
        .filter_by(slug=slug)
    ).first()

    if db_category is None:
        return None

    return _db_entity_to_category(db_category)


def get_categories(board_id: BoardID) -> list[BoardCategory]:
    """Return all categories for that board, ordered by position."""
    db_categories = db.session.scalars(
        select(DbBoardCategory)
        .filter_by(board_id=board_id)
        .order_by(DbBoardCategory.position)
    ).all()

    return [
        _db_entity_to_category(db_category) for db_category in db_categories
    ]


def get_categories_excluding(
    board_id: BoardID, category_id: BoardCategoryID
) -> list[BoardCategory]:
    """Return all categories for that board except for the specified one."""
    db_categories = db.session.scalars(
        select(DbBoardCategory)
        .filter_by(board_id=board_id)
        .filter(DbBoardCategory.id != category_id)
        .order_by(DbBoardCategory.position)
    ).all()

    return [
        _db_entity_to_category(db_category) for db_category in db_categories
    ]


def get_categories_with_last_updates(
    board_id: BoardID,
) -> list[BoardCategoryWithLastUpdate]:
    """Return the categories for that board.

    Include the creator of the last posting in each category.
    """
    db_categories_with_last_update = (
        db.session.scalars(
            select(DbBoardCategory)
            .filter_by(board_id=board_id)
            .filter_by(hidden=False)
            .options(
                db.joinedload(DbBoardCategory.last_posting_updated_by),
            )
        )
        .unique()
        .all()
    )

    return [
        _db_entity_to_category_with_last_update(db_category)
        for db_category in db_categories_with_last_update
    ]


def _db_entity_to_category(db_category: DbBoardCategory) -> BoardCategory:
    return BoardCategory(
        id=db_category.id,
        board_id=db_category.board_id,
        position=db_category.position,
        slug=db_category.slug,
        title=db_category.title,
        description=db_category.description,
        topic_count=db_category.topic_count,
        posting_count=db_category.posting_count,
        hidden=db_category.hidden,
    )


def _db_entity_to_category_with_last_update(
    db_category: DbBoardCategory,
) -> BoardCategoryWithLastUpdate:
    return BoardCategoryWithLastUpdate(
        id=db_category.id,
        board_id=db_category.board_id,
        position=db_category.position,
        slug=db_category.slug,
        title=db_category.title,
        description=db_category.description,
        topic_count=db_category.topic_count,
        posting_count=db_category.posting_count,
        hidden=db_category.hidden,
        last_posting_updated_at=db_category.last_posting_updated_at,
        last_posting_updated_by=db_category.last_posting_updated_by,
    )