from collections.abc import Mapping from typing import Optional from sqlalchemy import text from app.dao import BaseDAO class ParentDAO(BaseDAO): def create( self, openid: str, unionid: Optional[str] = None, nickname: Optional[str] = None, avatar_url: Optional[str] = None, ) -> int: result = self.db.execute( text( """ INSERT INTO parents (openid, unionid, nickname, avatar_url, status) VALUES (:openid, :unionid, :nickname, :avatar_url, 1) """ ), {"openid": openid, "unionid": unionid, "nickname": nickname, "avatar_url": avatar_url}, ) self.commit() return int(self.db.execute(text("SELECT last_insert_rowid()")).scalar_one()) def get_by_id(self, user_id: int) -> Optional[Mapping]: return ( self.db.execute( text("SELECT * FROM parents WHERE user_id = :user_id"), {"user_id": user_id}, ) .mappings() .first() ) def get_by_openid(self, openid: str) -> Optional[Mapping]: return ( self.db.execute( text("SELECT * FROM parents WHERE openid = :openid"), {"openid": openid}, ) .mappings() .first() ) def update( self, user_id: int, nickname: Optional[str] = None, avatar_url: Optional[str] = None, phone: Optional[str] = None, ) -> None: self.db.execute( text( """ UPDATE parents SET nickname = COALESCE(:nickname, nickname), avatar_url = COALESCE(:avatar_url, avatar_url), phone = COALESCE(:phone, phone) WHERE user_id = :user_id """ ), {"user_id": user_id, "nickname": nickname, "avatar_url": avatar_url, "phone": phone}, ) self.commit() def upsert( self, openid: str, unionid: Optional[str] = None, nickname: Optional[str] = None, avatar_url: Optional[str] = None, ) -> int: from app.settings import settings existing = self.get_by_openid(openid) if existing: self.update(existing["user_id"], nickname, avatar_url) return existing["user_id"] if settings.db_type == "sqlite": return self.create(openid, unionid, nickname, avatar_url) self.db.execute( text( """ INSERT INTO parents (openid, unionid, nickname, avatar_url, status) VALUES (:openid, :unionid, :nickname, :avatar_url, 1) ON DUPLICATE KEY UPDATE user_id = LAST_INSERT_ID(user_id), updated_at = CURRENT_TIMESTAMP """ ), {"openid": openid, "unionid": unionid, "nickname": nickname, "avatar_url": avatar_url}, ) self.commit() return int(self.db.execute(text("SELECT LAST_INSERT_ID()")).scalar_one())