100 lines
3.5 KiB
Python
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()
|