cosmo/backend/app/services/resource_service.py

100 lines
3.5 KiB
Python

"""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()