Source code for ingot.pagination

"""Keyset and offset pagination helpers."""

from __future__ import annotations

from typing import TYPE_CHECKING, Any

from sqlalchemy import func

if TYPE_CHECKING:
    from sqlalchemy import Select


[docs] def apply_keyset_pagination( stmt: Select, model: type, cursor: Any, cursor_field: str, page_size: int, max_page_size: int, ) -> tuple[Select, int]: """Apply keyset (cursor-based) pagination to a SELECT. Adds a ``WHERE cursor_field > cursor`` clause when a cursor is provided, clamps *page_size*, and adds ``LIMIT page_size + 1`` (the extra row detects whether more results exist). Args: stmt: The SQLAlchemy SELECT statement. model: The SQLAlchemy model class providing columns. cursor: The cursor value (already cast to the correct type), or ``None``. cursor_field: Name of the cursor column. page_size: Requested page size. max_page_size: Maximum allowed page size. Returns: ``(paginated_stmt, effective_page_size)`` tuple. The caller is responsible for executing *paginated_stmt*. """ effective_page_size = min(page_size, max_page_size) if cursor is not None: cursor_col = getattr(model, cursor_field) stmt = stmt.where(cursor_col > cursor) return stmt.limit(effective_page_size + 1), effective_page_size
[docs] def apply_offset_pagination( stmt: Select, offset: int, limit: int, max_page_size: int, ) -> tuple[Select, Select, int]: """Apply offset pagination to a SELECT. Clamps *limit* to *max_page_size*, applies ``OFFSET`` / ``LIMIT``, and builds a companion ``COUNT(*)`` statement so the caller can fetch the total alongside the page. Args: stmt: The SQLAlchemy SELECT statement (without offset/limit applied). offset: Number of rows to skip. limit: Requested page size. max_page_size: Hard ceiling on *limit*. Returns: ``(paginated_stmt, count_stmt, effective_limit)`` tuple. The caller is responsible for executing both statements. """ effective_limit = min(limit, max_page_size) paginated_stmt = stmt.offset(offset).limit(effective_limit) count_stmt = stmt.with_only_columns(func.count()) return paginated_stmt, count_stmt, effective_limit