"""Persistence operations for celestial resource metadata.""" from collections import defaultdict from typing import Any, Dict, List, Optional from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.database import AsyncSessionLocal from app.models.db import Resource class ResourceService: """Create, query, and delete celestial resource records.""" @staticmethod async def create_resource( resource_data: Dict[str, Any], session: Optional[AsyncSession] = None, ) -> Resource: async def create(active_session: AsyncSession) -> Resource: resource = Resource(**resource_data) active_session.add(resource) await active_session.commit() await active_session.refresh(resource) return resource if session is not None: return await create(session) async with AsyncSessionLocal() as active_session: return await create(active_session) @staticmethod async def get_resources_by_body( body_id: str, resource_type: Optional[str] = None, session: Optional[AsyncSession] = None, ) -> List[Resource]: async def query(active_session: AsyncSession) -> List[Resource]: statement = select(Resource).where(Resource.body_id == body_id) if resource_type: statement = statement.where(Resource.resource_type == resource_type) result = await active_session.execute( statement.order_by(Resource.created_at) ) return list(result.scalars().all()) if session is not None: return await query(session) async with AsyncSessionLocal() as active_session: return await query(active_session) @staticmethod async def get_all_resources_grouped_by_body( body_ids: Optional[List[str]] = None, session: Optional[AsyncSession] = None, ) -> Dict[str, List[Resource]]: async def query(active_session: AsyncSession) -> Dict[str, List[Resource]]: statement = select(Resource).order_by( Resource.body_id, Resource.created_at ) if body_ids: statement = statement.where(Resource.body_id.in_(body_ids)) result = await active_session.execute(statement) grouped: Dict[str, List[Resource]] = defaultdict(list) for resource in result.scalars().all(): grouped[resource.body_id].append(resource) return dict(grouped) if session is not None: return await query(session) async with AsyncSessionLocal() as active_session: return await query(active_session) @staticmethod async def delete_resource( resource_id: int, session: Optional[AsyncSession] = None, ) -> bool: async def delete(active_session: AsyncSession) -> bool: result = await active_session.execute( select(Resource).where(Resource.id == resource_id) ) resource = result.scalar_one_or_none() if resource is None: return False await active_session.delete(resource) await active_session.commit() return True if session is not None: return await delete(session) async with AsyncSessionLocal() as active_session: return await delete(active_session) resource_service = ResourceService()