You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

103 lines
3.6 KiB

from __future__ import annotations
from datetime import datetime, UTC
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.entities import Blob, FileEntry, FileVersion
class FileRepository:
def __init__(self, session: AsyncSession) -> None:
self.session = session
async def get_by_id(self, file_id: str) -> FileEntry | None:
return await self.session.get(FileEntry, file_id)
async def get_by_directory_and_name(self, directory_id: str, name: str) -> FileEntry | None:
result = await self.session.execute(
select(FileEntry).where(
FileEntry.directory_id == directory_id,
FileEntry.name == name,
FileEntry.is_deleted.is_(False),
FileEntry.deleted_at.is_(None),
)
)
return result.scalar_one_or_none()
async def list_by_directory(self, directory_id: str) -> list[FileEntry]:
result = await self.session.execute(
select(FileEntry)
.where(
FileEntry.directory_id == directory_id,
FileEntry.is_deleted.is_(False),
FileEntry.deleted_at.is_(None),
)
.order_by(FileEntry.name.asc())
)
return list(result.scalars().all())
async def list_deleted(self) -> list[FileEntry]:
result = await self.session.execute(
select(FileEntry)
.where(FileEntry.is_deleted.is_(True), FileEntry.deleted_at.is_not(None))
.order_by(FileEntry.deleted_at.desc(), FileEntry.name.asc())
)
return list(result.scalars().all())
async def list_active(self) -> list[FileEntry]:
result = await self.session.execute(
select(FileEntry)
.where(
FileEntry.is_deleted.is_(False),
FileEntry.deleted_at.is_(None),
)
.order_by(FileEntry.created_at.asc())
)
return list(result.scalars().all())
async def create_file_graph(
self,
file_entry: FileEntry,
file_version: FileVersion,
blob: Blob,
) -> FileEntry:
self.session.add(file_entry)
self.session.add(file_version)
await self.session.flush()
self.session.add(blob)
await self.session.flush()
await self.session.refresh(file_entry)
return file_entry
async def get_primary_blob_for_file(self, file_id: str) -> Blob | None:
result = await self.session.execute(
select(Blob)
.join(FileVersion, Blob.file_version_id == FileVersion.id)
.join(FileEntry, FileVersion.id == FileEntry.current_version_id)
.where(FileEntry.id == file_id, Blob.blob_index == 0)
)
return result.scalar_one_or_none()
async def get_blob_by_id(self, blob_id: str) -> Blob | None:
return await self.session.get(Blob, blob_id)
async def soft_delete(self, file_entry: FileEntry) -> FileEntry:
file_entry.is_deleted = True
file_entry.deleted_at = datetime.now(UTC)
await self.session.flush()
await self.session.refresh(file_entry)
return file_entry
async def restore(self, file_entry: FileEntry) -> FileEntry:
file_entry.is_deleted = False
file_entry.deleted_at = None
await self.session.flush()
await self.session.refresh(file_entry)
return file_entry
async def save(self, file_entry: FileEntry) -> FileEntry:
await self.session.flush()
await self.session.refresh(file_entry)
return file_entry