Coverage for src/kwai/modules/teams/repositories/team_member_db_query.py: 92%
39 statements
« prev ^ index » next coverage.py v7.6.10, created at 2024-01-01 00:00 +0000
« prev ^ index » next coverage.py v7.6.10, created at 2024-01-01 00:00 +0000
1"""Module that defines a database query for team members."""
3from collections import defaultdict
4from dataclasses import dataclass
5from typing import Self
7from sql_smith.functions import on
9from kwai.core.db.database_query import DatabaseQuery
10from kwai.core.db.table_row import JoinedTableRow
11from kwai.core.domain.value_objects.date import Date
12from kwai.core.domain.value_objects.name import Name
13from kwai.core.domain.value_objects.timestamp import Timestamp
14from kwai.core.domain.value_objects.traceable_time import TraceableTime
15from kwai.core.domain.value_objects.unique_id import UniqueId
16from kwai.modules.club.domain.value_objects import Birthdate, Gender, License
17from kwai.modules.teams.domain.team import TeamIdentifier
18from kwai.modules.teams.domain.team_member import (
19 MemberEntity,
20 MemberIdentifier,
21 TeamMember,
22)
23from kwai.modules.teams.repositories._tables import (
24 CountryRow,
25 MemberPersonRow,
26 MemberRow,
27 TeamMemberRow,
28)
31@dataclass(frozen=True, kw_only=True, slots=True)
32class TeamMemberQueryRow(JoinedTableRow):
33 """A data transfer object for the team member query."""
35 team_member: TeamMemberRow
36 member: MemberRow
37 person: MemberPersonRow
38 country: CountryRow
40 def create_team_member(self) -> TeamMember:
41 """Create a team member from a row."""
42 return TeamMember(
43 active=self.team_member.active == 1,
44 member=MemberEntity(
45 id_=MemberIdentifier(self.member.id),
46 uuid=UniqueId.create_from_string(self.member.uuid),
47 name=Name(
48 first_name=self.person.firstname, last_name=self.person.lastname
49 ),
50 license=License(
51 number=self.member.license,
52 end_date=Date.create_from_date(self.member.license_end_date),
53 ),
54 birthdate=Birthdate(Date.create_from_date(self.person.birthdate)),
55 gender=Gender(self.person.gender),
56 nationality=self.country.create_country(),
57 active_in_club=self.member.active == 1,
58 ),
59 traceable_time=TraceableTime(
60 created_at=Timestamp(self.team_member.created_at),
61 updated_at=Timestamp(self.team_member.updated_at),
62 ),
63 )
66class TeamMemberDbQuery(DatabaseQuery):
67 """A database query for getting team members."""
69 def init(self):
70 self._query.from_(TeamMemberRow.__table_name__).left_join(
71 MemberRow.__table_name__,
72 on(TeamMemberRow.column("member_id"), MemberRow.column("id")),
73 ).join(
74 MemberPersonRow.__table_name__,
75 on(MemberRow.column("person_id"), MemberPersonRow.column("id")),
76 ).inner_join(
77 CountryRow.__table_name__,
78 on(CountryRow.column("id"), MemberPersonRow.column("nationality_id")),
79 )
81 @property
82 def columns(self):
83 return TeamMemberQueryRow.get_aliases()
85 def filter_by_teams(self, *ids: TeamIdentifier) -> Self:
86 """Filter by teams.
88 Only the rows that belong to the teams with the given ids, will be returned.
89 """
90 unpacked_ids = tuple(i.value for i in ids)
91 self._query.and_where(TeamMemberRow.field("team_id").in_(*unpacked_ids))
92 return self
94 async def fetch_team_members(self) -> dict[TeamIdentifier, list[TeamMember]]:
95 """Fetch team members.
97 A specialized fetch method that already transforms the rows into TeamMember
98 objects.
100 Returns:
101 A dictionary that contains the list of team members for each team.
102 The key is the identifier of the team.
103 """
104 result: dict[TeamIdentifier, list[TeamMember]] = defaultdict(list)
106 async for row in self.fetch():
107 team_member_row = TeamMemberQueryRow.map(row)
108 result[TeamIdentifier(team_member_row.team_member.team_id)].append(
109 team_member_row.create_team_member()
110 )
112 return result