from collections.abc import Mapping from datetime import date from typing import Optional from sqlalchemy import text from app.dao import BaseDAO class ChildDAO(BaseDAO): def create( self, user_id: int, child_name: str, child_gender: int = 2, child_birthday: Optional[date] = None, ) -> int: result = self.db.execute( text( """ INSERT INTO children (parent_user_id, child_name, child_gender, child_birthday, status) VALUES (:user_id, :child_name, :child_gender, :child_birthday, 1) """ ), {"user_id": user_id, "child_name": child_name, "child_gender": child_gender, "child_birthday": child_birthday}, ) child_id = int(result.lastrowid) self.commit() return child_id def get_by_id(self, child_id: int) -> Optional[Mapping]: return ( self.db.execute( text("SELECT * FROM children WHERE child_id = :child_id"), {"child_id": child_id}, ) .mappings() .first() ) def list_by_parent(self, user_id: int, limit: int = 20, cursor: int = None) -> list[Mapping]: params = {"user_id": user_id, "limit": limit + 1} where = "parent_user_id = :user_id AND status = 1" if cursor: where += " AND child_id < :cursor" params["cursor"] = cursor rows = ( self.db.execute( text( f""" SELECT * FROM children WHERE {where} ORDER BY child_id DESC LIMIT :limit """ ), params, ) .mappings() .all() ) return rows def update( self, child_id: int, child_name: Optional[str] = None, child_gender: Optional[int] = None, child_birthday: Optional[date] = None, ) -> None: self.db.execute( text( """ UPDATE children SET child_name = COALESCE(:child_name, child_name), child_gender = COALESCE(:child_gender, child_gender), child_birthday = COALESCE(:child_birthday, child_birthday) WHERE child_id = :child_id """ ), {"child_id": child_id, "child_name": child_name, "child_gender": child_gender, "child_birthday": child_birthday}, ) self.commit() def has_access(self, child_id: int, user_id: int) -> bool: return ( self.db.execute( text( "SELECT 1 FROM children WHERE child_id = :child_id AND parent_user_id = :user_id AND status = 1" ), {"child_id": child_id, "user_id": user_id}, ).scalar_one_or_none() is not None )