Merge pull request #2898 from BrandonKowalski/feature/updated-after-query-param

[ROMM-2874] Feature/updated-after-query-param
This commit is contained in:
Georges-Antoine Assi
2026-01-16 17:24:11 -05:00
committed by GitHub
5 changed files with 60 additions and 3 deletions

View File

@@ -0,0 +1,31 @@
"""Add indexes on updated_at for roms and platforms tables
Revision ID: 0064_add_updated_at_indexes
Revises: 0063_roms_metadata_player_count
Create Date: 2026-01-12
"""
from alembic import op
# revision identifiers, used by Alembic.
revision = "0064_add_updated_at_indexes"
down_revision = "0063_roms_metadata_player_count"
branch_labels = None
depends_on = None
def upgrade():
with op.batch_alter_table("roms", schema=None) as batch_op:
batch_op.create_index("ix_roms_updated_at", ["updated_at"], unique=False)
with op.batch_alter_table("platforms", schema=None) as batch_op:
batch_op.create_index("ix_platforms_updated_at", ["updated_at"], unique=False)
def downgrade():
with op.batch_alter_table("roms", schema=None) as batch_op:
batch_op.drop_index("ix_roms_updated_at")
with op.batch_alter_table("platforms", schema=None) as batch_op:
batch_op.drop_index("ix_platforms_updated_at")

View File

@@ -1,8 +1,9 @@
from datetime import datetime
from typing import Annotated
from fastapi import Body
from fastapi import Path as PathVar
from fastapi import Request, status
from fastapi import Query, Request, status
from decorators.auth import protected_route
from endpoints.responses.platform import PlatformSchema
@@ -48,11 +49,20 @@ async def add_platform(
@protected_route(router.get, "", [Scope.PLATFORMS_READ])
def get_platforms(request: Request) -> list[PlatformSchema]:
def get_platforms(
request: Request,
updated_after: Annotated[
datetime | None,
Query(
description="Filter platforms updated after this datetime (ISO 8601 format with timezone information)."
),
] = None,
) -> list[PlatformSchema]:
"""Retrieve platforms."""
return [
PlatformSchema.model_validate(p) for p in db_platform_handler.get_platforms()
PlatformSchema.model_validate(p)
for p in db_platform_handler.get_platforms(updated_after=updated_after)
]

View File

@@ -405,6 +405,12 @@ def get_roms(
str,
Query(description="Order direction, either 'asc' or 'desc'."),
] = "asc",
updated_after: Annotated[
datetime | None,
Query(
description="Filter roms updated after this datetime (ISO 8601 format with timezone information)."
),
] = None,
) -> CustomLimitOffsetPage[SimpleRomSchema]:
"""Retrieve roms."""
query, order_by_attr = db_rom_handler.get_roms_query(
@@ -450,6 +456,7 @@ def get_roms(
statuses_logic=statuses_logic,
player_counts_logic=player_counts_logic,
group_by_meta_id=group_by_meta_id,
updated_after=updated_after,
)
# Get the char index for the roms

View File

@@ -1,5 +1,6 @@
import functools
from collections.abc import Sequence
from datetime import datetime
from sqlalchemy import delete, or_, select, update
from sqlalchemy.orm import Query, Session, selectinload
@@ -65,9 +66,12 @@ class DBPlatformsHandler(DBBaseHandler):
@with_firmware
def get_platforms(
self,
updated_after: datetime | None = None,
query: Query = None, # type: ignore
session: Session = None, # type: ignore
) -> Sequence[Platform]:
if updated_after:
query = query.filter(Platform.updated_at > updated_after)
return session.scalars(query.order_by(Platform.name.asc())).unique().all()
@begin_session

View File

@@ -1,5 +1,6 @@
import functools
from collections.abc import Iterable, Sequence
from datetime import datetime
from typing import Any
from sqlalchemy import (
@@ -510,6 +511,7 @@ class DBRomsHandler(DBBaseHandler):
statuses_logic: str = "any",
player_counts_logic: str = "any",
user_id: int | None = None,
updated_after: datetime | None = None,
session: Session = None, # type: ignore
) -> Query[Rom]:
from handler.scan_handler import MetadataSource
@@ -563,6 +565,9 @@ class DBRomsHandler(DBBaseHandler):
if verified:
query = self.filter_by_verified(query)
if updated_after:
query = query.filter(Rom.updated_at > updated_after)
# BEWARE YE WHO ENTERS HERE 💀
if group_by_meta_id:
# Convert NULL is_main_sibling to 0 (false) so it sorts after true values