]>
Commit | Line | Data |
---|---|---|
bae61627 C |
1 | import { Sequelize } from 'sequelize' |
2 | import { AbstractRunQuery } from '@server/models/shared' | |
bae61627 | 3 | import { ActorImageType } from '@shared/models' |
8c4bbd94 | 4 | import { getInstanceFollowsSort } from '../../../shared' |
bae61627 C |
5 | import { ActorFollowTableAttributes } from './actor-follow-table-attributes' |
6 | ||
7 | type BaseOptions = { | |
8 | sort: string | |
9 | count: number | |
10 | start: number | |
11 | } | |
12 | ||
13 | export abstract class InstanceListFollowsQueryBuilder <T extends BaseOptions> extends AbstractRunQuery { | |
14 | protected readonly tableAttributes = new ActorFollowTableAttributes() | |
15 | ||
16 | protected innerQuery: string | |
17 | ||
18 | constructor ( | |
19 | protected readonly sequelize: Sequelize, | |
20 | protected readonly options: T | |
21 | ) { | |
22 | super(sequelize) | |
23 | } | |
24 | ||
25 | protected abstract getWhere (): string | |
26 | ||
27 | protected getJoins () { | |
28 | return 'INNER JOIN "actor" "ActorFollower" ON "ActorFollower"."id" = "ActorFollowModel"."actorId" ' + | |
29 | 'INNER JOIN "actor" "ActorFollowing" ON "ActorFollowing"."id" = "ActorFollowModel"."targetActorId" ' | |
30 | } | |
31 | ||
32 | protected getServerJoin (actorName: string) { | |
33 | return `LEFT JOIN "server" "${actorName}->Server" ON "${actorName}"."serverId" = "${actorName}->Server"."id" ` | |
34 | } | |
35 | ||
36 | protected getAvatarsJoin (actorName: string) { | |
37 | return `LEFT JOIN "actorImage" "${actorName}->Avatars" ON "${actorName}.id" = "${actorName}->Avatars"."actorId" ` + | |
38 | `AND "${actorName}->Avatars"."type" = ${ActorImageType.AVATAR}` | |
39 | } | |
40 | ||
41 | private buildInnerQuery () { | |
42 | this.innerQuery = `${this.getInnerSelect()} ` + | |
43 | `FROM "actorFollow" AS "ActorFollowModel" ` + | |
44 | `${this.getJoins()} ` + | |
45 | `${this.getServerJoin('ActorFollowing')} ` + | |
46 | `${this.getServerJoin('ActorFollower')} ` + | |
47 | `${this.getWhere()} ` + | |
48 | `${this.getOrder()} ` + | |
49 | `LIMIT :limit OFFSET :offset ` | |
50 | ||
51 | this.replacements.limit = this.options.count | |
52 | this.replacements.offset = this.options.start | |
53 | } | |
54 | ||
55 | protected buildListQuery () { | |
56 | this.buildInnerQuery() | |
57 | ||
58 | this.query = `${this.getSelect()} ` + | |
59 | `FROM (${this.innerQuery}) AS "ActorFollowModel" ` + | |
60 | `${this.getAvatarsJoin('ActorFollower')} ` + | |
61 | `${this.getAvatarsJoin('ActorFollowing')} ` + | |
62 | `${this.getOrder()}` | |
63 | } | |
64 | ||
65 | protected buildCountQuery () { | |
66 | this.query = `SELECT COUNT(*) AS "total" ` + | |
67 | `FROM "actorFollow" AS "ActorFollowModel" ` + | |
68 | `${this.getJoins()} ` + | |
69 | `${this.getServerJoin('ActorFollowing')} ` + | |
70 | `${this.getServerJoin('ActorFollower')} ` + | |
71 | `${this.getWhere()}` | |
72 | } | |
73 | ||
74 | private getInnerSelect () { | |
75 | return this.buildSelect([ | |
76 | this.tableAttributes.getFollowAttributes(), | |
77 | this.tableAttributes.getActorAttributes('ActorFollower'), | |
78 | this.tableAttributes.getActorAttributes('ActorFollowing'), | |
79 | this.tableAttributes.getServerAttributes('ActorFollower'), | |
80 | this.tableAttributes.getServerAttributes('ActorFollowing') | |
81 | ]) | |
82 | } | |
83 | ||
84 | private getSelect () { | |
85 | return this.buildSelect([ | |
86 | '"ActorFollowModel".*', | |
87 | this.tableAttributes.getAvatarAttributes('ActorFollower'), | |
88 | this.tableAttributes.getAvatarAttributes('ActorFollowing') | |
89 | ]) | |
90 | } | |
91 | ||
92 | private getOrder () { | |
93 | const orders = getInstanceFollowsSort(this.options.sort) | |
94 | ||
95 | return 'ORDER BY ' + orders.map(o => `"${o[0]}" ${o[1]}`).join(', ') | |
96 | } | |
97 | } |