138 lines
4.2 KiB
Python
138 lines
4.2 KiB
Python
from collections.abc import Mapping
|
|
from typing import Optional
|
|
|
|
from sqlalchemy import text
|
|
from sqlalchemy.exc import IntegrityError
|
|
|
|
from app.dao import BaseDAO
|
|
from app.db_compat import inserted_primary_key
|
|
|
|
|
|
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},
|
|
)
|
|
user_id = inserted_primary_key(result)
|
|
self.commit()
|
|
return user_id
|
|
|
|
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 set_avatar_file_key(self, user_id: int, avatar_file_key: str) -> None:
|
|
self.db.execute(
|
|
text(
|
|
"""
|
|
UPDATE parents
|
|
SET avatar_file_key = :avatar_file_key,
|
|
avatar_url = NULL
|
|
WHERE user_id = :user_id
|
|
"""
|
|
),
|
|
{"user_id": user_id, "avatar_file_key": avatar_file_key},
|
|
)
|
|
self.commit()
|
|
|
|
def update_from_wechat_login(
|
|
self,
|
|
user_id: int,
|
|
unionid: Optional[str] = None,
|
|
nickname: Optional[str] = None,
|
|
avatar_url: Optional[str] = None,
|
|
) -> None:
|
|
self.db.execute(
|
|
text(
|
|
"""
|
|
UPDATE parents
|
|
SET unionid = CASE
|
|
WHEN unionid IS NULL AND :unionid IS NOT NULL THEN :unionid
|
|
ELSE unionid
|
|
END,
|
|
nickname = COALESCE(:nickname, nickname),
|
|
avatar_url = COALESCE(:avatar_url, avatar_url)
|
|
WHERE user_id = :user_id
|
|
"""
|
|
),
|
|
{
|
|
"user_id": user_id,
|
|
"unionid": unionid,
|
|
"nickname": nickname,
|
|
"avatar_url": avatar_url,
|
|
},
|
|
)
|
|
self.commit()
|
|
|
|
def upsert(
|
|
self,
|
|
openid: str,
|
|
unionid: Optional[str] = None,
|
|
nickname: Optional[str] = None,
|
|
avatar_url: Optional[str] = None,
|
|
) -> int:
|
|
existing = self.get_by_openid(openid)
|
|
if existing:
|
|
self.update_from_wechat_login(existing["user_id"], unionid, nickname, avatar_url)
|
|
return int(existing["user_id"])
|
|
|
|
try:
|
|
return self.create(openid, unionid, nickname, avatar_url)
|
|
except IntegrityError:
|
|
self.db.rollback()
|
|
existing = self.get_by_openid(openid)
|
|
if not existing:
|
|
raise
|
|
if unionid or nickname or avatar_url:
|
|
self.update_from_wechat_login(existing["user_id"], unionid, nickname, avatar_url)
|
|
return int(existing["user_id"])
|