Coverage for bc/kwai-bc-training/src/kwai_bc_training/trainings/training_coach_db_query.py: 100%
32 statements
« prev ^ index » next coverage.py v7.11.0, created at 2024-01-01 00:00 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2024-01-01 00:00 +0000
1"""Module that defines a database query to get coaches of training(s)."""
3from collections import defaultdict
4from dataclasses import dataclass
6from kwai_core.db.database_query import DatabaseQuery
7from kwai_core.db.rows import OwnerRow
8from kwai_core.db.table_row import JoinedTableRow
9from kwai_core.domain.value_objects.name import Name
10from kwai_core.domain.value_objects.unique_id import UniqueId
11from sql_smith.functions import on
13from kwai_bc_training.coaches._tables import ( # noqa
14 CoachRow,
15 MemberRow,
16 PersonRow,
17)
18from kwai_bc_training.coaches.coach import CoachEntity, CoachIdentifier
19from kwai_bc_training.trainings._tables import (
20 TrainingCoachRow,
21)
22from kwai_bc_training.trainings.training import (
23 TrainingCoachEntity,
24 TrainingCoachIdentifier,
25 TrainingIdentifier,
26)
29@dataclass(kw_only=True, frozen=True, slots=True)
30class TrainingCoachQueryRow(JoinedTableRow):
31 """A data transfer object for the training coach query."""
33 training_coach: TrainingCoachRow
34 member: MemberRow
35 person: PersonRow
36 coach: CoachRow
37 owner: OwnerRow
39 def create_coach(self) -> TrainingCoachEntity:
40 """Create a training coach from a row."""
41 return TrainingCoachEntity(
42 id=TrainingCoachIdentifier(self.training_coach.id),
43 coach=CoachEntity(
44 id=CoachIdentifier(self.coach.id),
45 name=Name(
46 first_name=self.person.firstname, last_name=self.person.lastname
47 ),
48 active=self.coach.active == 1,
49 uuid=UniqueId.create_from_string(self.member.uuid),
50 ),
51 owner=self.owner.create_owner(),
52 present=self.training_coach.present == 1,
53 type=self.training_coach.coach_type,
54 payed=self.training_coach.payed == 1,
55 remark=(
56 "" if self.training_coach.remark is None else self.training_coach.remark
57 ),
58 )
61class TrainingCoachDbQuery(DatabaseQuery):
62 """A database query for getting coaches of training(s)."""
64 def init(self):
65 self._query.from_(TrainingCoachRow.__table_name__).left_join(
66 CoachRow.__table_name__,
67 on(TrainingCoachRow.column("coach_id"), CoachRow.column("id")),
68 ).join(
69 MemberRow.__table_name__,
70 on(CoachRow.column("member_id"), MemberRow.column("id")),
71 ).join(
72 PersonRow.__table_name__,
73 on(MemberRow.column("person_id"), PersonRow.column("id")),
74 ).join(
75 OwnerRow.__table_name__,
76 on(TrainingCoachRow.column("user_id"), OwnerRow.column("id")),
77 )
79 @property
80 def columns(self):
81 return TrainingCoachQueryRow.get_aliases()
83 def filter_by_trainings(self, *ids: TrainingIdentifier) -> "TrainingCoachDbQuery":
84 """Filter by trainings.
86 Only the rows of the trainings with the given ids, will be returned.
87 """
88 unpacked_ids = tuple(i.value for i in ids)
89 self._query.and_where(TrainingCoachRow.field("training_id").in_(*unpacked_ids))
90 return self
92 async def fetch_coaches(
93 self,
94 ) -> dict[TrainingIdentifier, list[TrainingCoachEntity]]:
95 """Fetch coaches.
97 A specialized fetch method that already transforms the records into
98 TrainingCoach objects.
100 Returns:
101 A dictionary that contains the list of coaches for trainings. The key
102 is the identifier of a training.
103 """
104 result: dict[TrainingIdentifier, list[TrainingCoachEntity]] = defaultdict(list)
106 async for row in self.fetch():
107 training_coach_row = TrainingCoachQueryRow.map(row)
108 result[
109 TrainingIdentifier(training_coach_row.training_coach.training_id)
110 ].append(training_coach_row.create_coach())
111 return result