feat: local storage logic & endpoints
This commit is contained in:
@@ -1,8 +1,15 @@
|
||||
"""SQLAlchemy repository adapters implementing the domain ports."""
|
||||
|
||||
from app.infrastructure.db.repositories.artist_repository import SqlAlchemyArtistRepository
|
||||
from app.infrastructure.db.repositories.refresh_token_repository import (
|
||||
SqlAlchemyRefreshTokenRepository,
|
||||
)
|
||||
from app.infrastructure.db.repositories.track_repository import SqlAlchemyTrackRepository
|
||||
from app.infrastructure.db.repositories.user_repository import SqlAlchemyUserRepository
|
||||
|
||||
__all__ = ["SqlAlchemyRefreshTokenRepository", "SqlAlchemyUserRepository"]
|
||||
__all__ = [
|
||||
"SqlAlchemyArtistRepository",
|
||||
"SqlAlchemyRefreshTokenRepository",
|
||||
"SqlAlchemyTrackRepository",
|
||||
"SqlAlchemyUserRepository",
|
||||
]
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
"""Artist repository — adapter over ``AsyncSession``."""
|
||||
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.domain.entities.track import Artist
|
||||
from app.infrastructure.db.models.artist import ArtistModel
|
||||
|
||||
|
||||
def _to_entity(row: ArtistModel) -> Artist:
|
||||
return Artist(
|
||||
id=row.id,
|
||||
name=row.name,
|
||||
created_at=row.created_at,
|
||||
updated_at=row.updated_at,
|
||||
)
|
||||
|
||||
|
||||
class SqlAlchemyArtistRepository:
|
||||
def __init__(self, session: AsyncSession) -> None:
|
||||
self._session = session
|
||||
|
||||
async def get_or_create(self, name: str) -> Artist:
|
||||
row = (
|
||||
await self._session.execute(select(ArtistModel).where(ArtistModel.name == name))
|
||||
).scalar_one_or_none()
|
||||
if row is None:
|
||||
row = ArtistModel(name=name)
|
||||
self._session.add(row)
|
||||
await self._session.flush()
|
||||
await self._session.refresh(row)
|
||||
return _to_entity(row)
|
||||
@@ -0,0 +1,83 @@
|
||||
"""Track repository — adapter over ``AsyncSession``."""
|
||||
|
||||
import uuid
|
||||
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.domain.entities.track import Track
|
||||
from app.infrastructure.db.models.track import TrackModel
|
||||
|
||||
|
||||
def _to_entity(row: TrackModel) -> Track:
|
||||
return Track(
|
||||
id=row.id,
|
||||
title=row.title,
|
||||
artist_id=row.artist_id,
|
||||
file_path=row.file_path,
|
||||
file_format=row.file_format,
|
||||
file_size=row.file_size,
|
||||
source=row.source,
|
||||
source_id=row.source_id,
|
||||
duration_seconds=row.duration_seconds,
|
||||
metadata_status=row.metadata_status,
|
||||
created_at=row.created_at,
|
||||
updated_at=row.updated_at,
|
||||
)
|
||||
|
||||
|
||||
class SqlAlchemyTrackRepository:
|
||||
def __init__(self, session: AsyncSession) -> None:
|
||||
self._session = session
|
||||
|
||||
async def get_by_id(self, track_id: uuid.UUID) -> Track | None:
|
||||
row = await self._session.get(TrackModel, track_id)
|
||||
return _to_entity(row) if row is not None else None
|
||||
|
||||
async def get_by_source(self, source: str, source_id: str) -> Track | None:
|
||||
row = (
|
||||
await self._session.execute(
|
||||
select(TrackModel).where(
|
||||
TrackModel.source == source,
|
||||
TrackModel.source_id == source_id,
|
||||
)
|
||||
)
|
||||
).scalar_one_or_none()
|
||||
return _to_entity(row) if row is not None else None
|
||||
|
||||
async def add(
|
||||
self,
|
||||
*,
|
||||
id: uuid.UUID,
|
||||
title: str,
|
||||
artist_id: uuid.UUID,
|
||||
file_path: str,
|
||||
file_format: str,
|
||||
file_size: int,
|
||||
source: str,
|
||||
source_id: str,
|
||||
metadata_status: str,
|
||||
added_by: uuid.UUID | None,
|
||||
) -> Track:
|
||||
row = TrackModel(
|
||||
id=id,
|
||||
title=title,
|
||||
artist_id=artist_id,
|
||||
file_path=file_path,
|
||||
file_format=file_format,
|
||||
file_size=file_size,
|
||||
source=source,
|
||||
source_id=source_id,
|
||||
metadata_status=metadata_status,
|
||||
added_by=added_by,
|
||||
)
|
||||
self._session.add(row)
|
||||
await self._session.flush()
|
||||
await self._session.refresh(row)
|
||||
return _to_entity(row)
|
||||
|
||||
async def delete(self, track_id: uuid.UUID) -> None:
|
||||
row = await self._session.get(TrackModel, track_id)
|
||||
if row is not None:
|
||||
await self._session.delete(row)
|
||||
await self._session.flush()
|
||||
Reference in New Issue
Block a user