101 lines
3.9 KiB
Python
101 lines
3.9 KiB
Python
# myapp/repositories/classification.py
|
||
# ------------------------------------------------------------
|
||
# Persistence layer for the ``Classification`` lookup table.
|
||
# ------------------------------------------------------------
|
||
|
||
from __future__ import annotations
|
||
|
||
from typing import List, Optional
|
||
|
||
from backend.db import BaseRepository
|
||
from backend.models import Classification as ClassificationModel
|
||
|
||
|
||
class ClassificationRepository(BaseRepository[ClassificationModel]):
|
||
"""
|
||
Simple CRUD + lookup helpers for the ``Classifications`` table.
|
||
|
||
Typical rows look like:
|
||
ClassificationId | ClassificationName
|
||
------------------------------------
|
||
1 | Baritone
|
||
2 | Tenor
|
||
3 | Alto / Mezzo
|
||
4 | Soprano
|
||
"""
|
||
|
||
# ------------------------------------------------------------------
|
||
# Table‑level constants – change them here if the schema ever changes.
|
||
# ------------------------------------------------------------------
|
||
_TABLE = "Classifications"
|
||
_PK = "ClassificationId"
|
||
|
||
# ------------------------------------------------------------------
|
||
# Basic CRUD operations
|
||
# ------------------------------------------------------------------
|
||
def create(self, name: str) -> ClassificationModel:
|
||
"""
|
||
Insert a new classification row and return the populated model.
|
||
|
||
Parameters
|
||
----------
|
||
name: str
|
||
Human‑readable name (e.g. “Baritone”, “Tenor”, …).
|
||
|
||
Returns
|
||
-------
|
||
ClassificationModel
|
||
Instance with the newly assigned ``ClassificationId``.
|
||
"""
|
||
classification = ClassificationModel(ClassificationId=-1, ClassificationName=name)
|
||
return self._insert(self._TABLE, classification, self._PK)
|
||
|
||
def get_by_id(self, classification_id: int) -> Optional[ClassificationModel]:
|
||
"""
|
||
Retrieve a single classification by primary key.
|
||
"""
|
||
sql = f"SELECT * FROM {self._TABLE} WHERE {self._PK} = ?"
|
||
row = self.db.fetchone(sql, (classification_id,))
|
||
return ClassificationModel.from_row(row) if row else None
|
||
|
||
def find_by_name(self, name: str) -> Optional[ClassificationModel]:
|
||
"""
|
||
Look up a classification by its exact name.
|
||
"""
|
||
sql = f"SELECT * FROM {self._TABLE} WHERE ClassificationName = ?"
|
||
row = self.db.fetchone(sql, (name,))
|
||
return ClassificationModel.from_row(row) if row else None
|
||
|
||
# ------------------------------------------------------------------
|
||
# Convenience queries
|
||
# ------------------------------------------------------------------
|
||
def list_all(self) -> List[ClassificationModel]:
|
||
"""
|
||
Return every classification row, ordered alphabetically.
|
||
"""
|
||
sql = f"SELECT * FROM {self._TABLE} ORDER BY ClassificationName ASC"
|
||
rows = self.db.fetchall(sql)
|
||
return [ClassificationModel.from_row(r) for r in rows]
|
||
|
||
def ensure_exists(self, name: str) -> ClassificationModel:
|
||
"""
|
||
Idempotent helper used by higher‑level services:
|
||
|
||
* If a classification with ``name`` already exists, return it.
|
||
* Otherwise create a new row and return the freshly inserted model.
|
||
"""
|
||
existing = self.find_by_name(name)
|
||
if existing:
|
||
return existing
|
||
return self.create(name)
|
||
|
||
# ------------------------------------------------------------------
|
||
# Optional delete (use with care – other tables may have FK constraints)
|
||
# ------------------------------------------------------------------
|
||
def delete(self, classification_id: int) -> None:
|
||
"""
|
||
Hard‑delete a classification row. In practice you’ll rarely need
|
||
this because classifications tend to be static reference data.
|
||
"""
|
||
sql = f"DELETE FROM {self._TABLE} WHERE {self._PK} = ?"
|
||
self.db.execute(sql, (classification_id,)) |