Coverage for app/ddd/infrastructure/repository/user_repository_impl.py: 100%
53 statements
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-15 01:44 +0000
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-15 01:44 +0000
1# class ErrorCode:
3from sqlmodel import Session, select
5from app.ddd.domain import (
6 User,
7 UserDuplicationError,
8 UserId,
9 UserNotFoundError,
10 UserRepository,
11 UserUpdateConflictError,
12 # UserReportDuplicationError,
13)
14from migrations.models import TUser, TUserReport
17class UserRepositoryImpl(UserRepository):
18 def __init__(self, session: Session) -> None:
19 self.__session: Session = session
21 def _fetch_by_id(self, _id: str) -> TUser | None:
22 statement = select(TUser).where(TUser.user_id == _id)
23 return self.__session.exec(statement).first()
25 def _fetch_user_report_by_id(self, _id: str) -> TUserReport | None:
26 statement = select(TUserReport).where(TUserReport.user_report_id == _id)
27 return self.__session.exec(statement).first()
29 def _apply(self, model: TUser | TUserReport) -> None:
30 self.__session.add(model)
32 def _delete(self, model: TUser) -> None:
33 self.__session.delete(model)
35 def find_by_id(self, _id: UserId) -> User:
36 model: TUser | None = self._fetch_by_id(_id.root)
37 if model is None:
38 raise UserNotFoundError(_id.root)
39 return User.model_validate(model)
41 def insert(self, user: User) -> None:
42 model: TUser | None = self._fetch_by_id(user.user_id)
43 if model is not None: # 重複判定
44 raise UserDuplicationError(user.user_id)
45 model = TUser.model_validate(user.model_dump(exclude={"created_at", "updated_at"})) # 新規作成
46 self._apply(model)
48 def insert_user_report(self, user: User) -> None:
49 for user_report in user.user_reports:
50 _id = user_report.user_report_id
51 model: TUserReport | None = self._fetch_user_report_by_id(_id)
52 print(_id)
53 print(model)
54 if model is not None: # 重複判定
55 # raise UserReportDuplicationError(_id)
56 continue
57 model = TUserReport.model_validate(user_report.model_dump(exclude={"created_at", "updated_at"})) # 新規作成
58 self._apply(model)
60 def update(self, user: User) -> None:
61 model: TUser | None = self._fetch_by_id(user.user_id)
62 if model is None: # ない場合更新できない 現在のユースケースでは基本的に発生しない
63 raise UserNotFoundError(user.user_id)
64 if user.updated_at != model.updated_at: # 更新日検証による楽観的ロックの確認
65 raise UserUpdateConflictError(user_id=user.user_id)
66 model.sqlmodel_update(user.model_dump(exclude={"created_at", "updated_at", "user_reports"})) # 更新データの統合
67 self._apply(model)
69 def delete(self, _id: UserId) -> None:
70 model: TUser | None = self._fetch_by_id(_id.root)
71 if model is None:
72 raise UserNotFoundError(_id.root)
74 # TODO(nonomura): 論理削除する場合
75 # model.updated_at = datetime.now()
76 # model.deleted_at = datetime.now() # 論理削除する場合
77 # self._apply(model)
79 self._delete(model) # 物理削除用
81 def query(self) -> list[User]:
82 """TODO(nonomura): 検索条件整理後に整理。必要に応じてクエリサービスに分ける."""
83 models: list[TUser] = self.__session.query(TUser).all()
84 return [User.model_validate(model) for model in models]