121 lines
3.8 KiB
Python
121 lines
3.8 KiB
Python
from collections.abc import Mapping
|
|
from datetime import date
|
|
from typing import Optional
|
|
|
|
from sqlalchemy import text
|
|
|
|
from app.dao import BaseDAO
|
|
from app.db_compat import inserted_primary_key
|
|
|
|
|
|
class ChildDAO(BaseDAO):
|
|
def _create_relation(self, user_id: int, child_id: int) -> None:
|
|
self.db.execute(
|
|
text(
|
|
"""
|
|
INSERT INTO parent_child_relations (user_id, child_id, relation_type, is_primary, status)
|
|
VALUES (:user_id, :child_id, 9, 0, 1)
|
|
"""
|
|
),
|
|
{"user_id": user_id, "child_id": child_id},
|
|
)
|
|
|
|
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 (child_name, child_gender, child_birthday, status)
|
|
VALUES (:child_name, :child_gender, :child_birthday, 1)
|
|
"""
|
|
),
|
|
{"child_name": child_name, "child_gender": child_gender, "child_birthday": child_birthday},
|
|
)
|
|
child_id = inserted_primary_key(result)
|
|
self._create_relation(user_id, child_id)
|
|
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 = "pcr.user_id = :user_id AND pcr.status = 1 AND c.status = 1"
|
|
if cursor is not None:
|
|
where += " AND c.child_id < :cursor"
|
|
params["cursor"] = cursor
|
|
|
|
rows = (
|
|
self.db.execute(
|
|
text(
|
|
f"""
|
|
SELECT c.*
|
|
FROM children AS c
|
|
JOIN parent_child_relations AS pcr
|
|
ON pcr.child_id = c.child_id
|
|
WHERE {where}
|
|
ORDER BY c.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 AS c
|
|
JOIN parent_child_relations AS pcr
|
|
ON pcr.child_id = c.child_id
|
|
WHERE c.child_id = :child_id
|
|
AND pcr.user_id = :user_id
|
|
AND c.status = 1
|
|
AND pcr.status = 1
|
|
"""
|
|
),
|
|
{"child_id": child_id, "user_id": user_id},
|
|
).scalar_one_or_none()
|
|
is not None
|
|
)
|