"""Base CRUD class for timetable operations.""" from typing import List, Optional, Dict, Any from uuid import UUID from supabase import Client class BaseCRUD: def __init__(self, table_name: str): self.table_name = table_name async def get_by_id(self, db: Client, id: UUID) -> Optional[Dict[str, Any]]: """Get record by ID.""" result = db.table(self.table_name).select("*").eq("id", str(id)).execute() return result.data[0] if result.data else None async def get_by_ids(self, db: Client, ids: List[UUID]) -> List[Dict[str, Any]]: """Get multiple records by IDs.""" str_ids = [str(id) for id in ids] result = db.table(self.table_name).select("*").in_("id", str_ids).execute() return result.data or [] async def get_multi( self, db: Client, skip: int = 0, limit: int = 100, order_by: str = "created_at", ascending: bool = False, filters: Optional[Dict[str, Any]] = None ) -> List[Dict[str, Any]]: """Alias for get_all - get all records with pagination and optional filtering.""" return await self.get_all(db, skip=skip, limit=limit, order_by=order_by, ascending=ascending, filters=filters) async def get_all( self, db: Client, skip: int = 0, limit: int = 100, order_by: str = "created_at", ascending: bool = False, filters: Optional[Dict[str, Any]] = None ) -> List[Dict[str, Any]]: """Get all records with pagination and optional filtering.""" query = db.table(self.table_name).select("*") # Apply filters if provided if filters: for key, value in filters.items(): if value is not None: if isinstance(value, UUID): query = query.eq(key, str(value)) elif isinstance(value, list): query = query.in_(key, [str(v) if isinstance(v, UUID) else v for v in value]) else: query = query.eq(key, value) query = query.order(order_by, desc=not ascending) query = query.range(skip, skip + limit - 1) result = query.execute() return result.data or [] async def count(self, db: Client, filters: Optional[Dict[str, Any]] = None) -> int: """Count records with optional filters.""" query = db.table(self.table_name).select("id", count="exact") if filters: for key, value in filters.items(): query = query.eq(key, str(value) if isinstance(value, UUID) else value) result = query.execute() return result.count if hasattr(result, 'count') else len(result.data) async def create(self, db: Client, data: Dict[str, Any]) -> Dict[str, Any]: """Create new record.""" # Convert UUIDs to strings processed_data = {} for key, value in data.items(): if isinstance(value, UUID): processed_data[key] = str(value) elif isinstance(value, list): processed_data[key] = [ str(v) if isinstance(v, UUID) else v for v in value ] else: processed_data[key] = value result = db.table(self.table_name).insert(processed_data).execute() return result.data[0] if result.data else processed_data async def update( self, db: Client, id: UUID, data: Dict[str, Any] ) -> Optional[Dict[str, Any]]: """Update existing record.""" # Convert UUIDs to strings and remove None values processed_data = {} for key, value in data.items(): if value is not None: if isinstance(value, UUID): processed_data[key] = str(value) elif isinstance(value, list): processed_data[key] = [ str(v) if isinstance(v, UUID) else v for v in value ] else: processed_data[key] = value if not processed_data: return await self.get_by_id(db, id) result = db.table(self.table_name) \ .update(processed_data) \ .eq("id", str(id)).execute() return result.data[0] if result.data else None async def delete(self, db: Client, id: UUID) -> bool: """Delete record by ID.""" result = db.table(self.table_name).delete().eq("id", str(id)).execute() return bool(result.data)