]>
Commit | Line | Data |
---|---|---|
1d43c3a6 | 1 | import validator from 'validator' |
d9bf974f C |
2 | import { AbstractVideosQueryBuilder } from './abstract-videos-query-builder' |
3 | import { VideoAttributes } from './video-attributes' | |
1d43c3a6 C |
4 | |
5 | /** | |
6 | * | |
7 | * Abstract builder to create SQL query and fetch video models | |
8 | * | |
9 | */ | |
d9bf974f C |
10 | |
11 | export class AbstractVideosModelQueryBuilder extends AbstractVideosQueryBuilder { | |
12 | protected attributes: { [key: string]: string } = {} | |
13 | protected joins: string[] = [] | |
1d43c3a6 | 14 | protected where: string |
d9bf974f C |
15 | |
16 | protected videoAttributes: VideoAttributes | |
d9bf974f | 17 | |
1d43c3a6 | 18 | constructor (protected readonly mode: 'list' | 'get') { |
d9bf974f C |
19 | super() |
20 | ||
21 | this.videoAttributes = new VideoAttributes(this.mode) | |
d9bf974f C |
22 | } |
23 | ||
24 | protected buildSelect () { | |
25 | return 'SELECT ' + Object.keys(this.attributes).map(key => { | |
26 | const value = this.attributes[key] | |
27 | if (value) return `${key} AS ${value}` | |
28 | ||
29 | return key | |
30 | }).join(', ') | |
31 | } | |
32 | ||
33 | protected includeChannels () { | |
34 | this.joins.push( | |
35 | 'INNER JOIN "videoChannel" AS "VideoChannel" ON "video"."channelId" = "VideoChannel"."id"', | |
36 | 'INNER JOIN "actor" AS "VideoChannel->Actor" ON "VideoChannel"."actorId" = "VideoChannel->Actor"."id"', | |
37 | ||
38 | 'LEFT OUTER JOIN "server" AS "VideoChannel->Actor->Server" ON "VideoChannel->Actor"."serverId" = "VideoChannel->Actor->Server"."id"', | |
39 | ||
40 | 'LEFT OUTER JOIN "actorImage" AS "VideoChannel->Actor->Avatar" ' + | |
41 | 'ON "VideoChannel->Actor"."avatarId" = "VideoChannel->Actor->Avatar"."id"' | |
42 | ) | |
43 | ||
44 | this.attributes = { | |
45 | ...this.attributes, | |
46 | ||
47 | ...this.buildAttributesObject('VideoChannel', this.videoAttributes.getChannelAttributes()), | |
48 | ...this.buildActorInclude('VideoChannel->Actor'), | |
49 | ...this.buildAvatarInclude('VideoChannel->Actor->Avatar'), | |
50 | ...this.buildServerInclude('VideoChannel->Actor->Server') | |
51 | } | |
52 | } | |
53 | ||
54 | protected includeAccounts () { | |
55 | this.joins.push( | |
56 | 'INNER JOIN "account" AS "VideoChannel->Account" ON "VideoChannel"."accountId" = "VideoChannel->Account"."id"', | |
57 | 'INNER JOIN "actor" AS "VideoChannel->Account->Actor" ON "VideoChannel->Account"."actorId" = "VideoChannel->Account->Actor"."id"', | |
58 | ||
59 | 'LEFT OUTER JOIN "server" AS "VideoChannel->Account->Actor->Server" ' + | |
60 | 'ON "VideoChannel->Account->Actor"."serverId" = "VideoChannel->Account->Actor->Server"."id"', | |
61 | ||
62 | 'LEFT OUTER JOIN "actorImage" AS "VideoChannel->Account->Actor->Avatar" ' + | |
63 | 'ON "VideoChannel->Account->Actor"."avatarId" = "VideoChannel->Account->Actor->Avatar"."id"' | |
64 | ) | |
65 | ||
66 | this.attributes = { | |
67 | ...this.attributes, | |
68 | ||
69 | ...this.buildAttributesObject('VideoChannel->Account', this.videoAttributes.getAccountAttributes()), | |
70 | ...this.buildActorInclude('VideoChannel->Account->Actor'), | |
71 | ...this.buildAvatarInclude('VideoChannel->Account->Actor->Avatar'), | |
72 | ...this.buildServerInclude('VideoChannel->Account->Actor->Server') | |
73 | } | |
74 | } | |
75 | ||
76 | protected includeThumbnails () { | |
77 | this.joins.push('LEFT OUTER JOIN "thumbnail" AS "Thumbnails" ON "video"."id" = "Thumbnails"."videoId"') | |
78 | ||
79 | this.attributes = { | |
80 | ...this.attributes, | |
81 | ||
82 | ...this.buildAttributesObject('Thumbnails', this.videoAttributes.getThumbnailAttributes()) | |
83 | } | |
84 | } | |
85 | ||
1d43c3a6 C |
86 | protected includeWebtorrentFiles (required: boolean) { |
87 | const joinType = required ? 'INNER' : 'LEFT' | |
88 | this.joins.push(joinType + ' JOIN "videoFile" AS "VideoFiles" ON "VideoFiles"."videoId" = "video"."id"') | |
89 | ||
90 | this.attributes = { | |
91 | ...this.attributes, | |
92 | ||
93 | ...this.buildAttributesObject('VideoFiles', this.videoAttributes.getFileAttributes()) | |
94 | } | |
95 | } | |
96 | ||
97 | protected includeStreamingPlaylistFiles (required: boolean) { | |
98 | const joinType = required ? 'INNER' : 'LEFT' | |
d9bf974f | 99 | |
1d43c3a6 C |
100 | this.joins.push( |
101 | joinType + ' JOIN "videoStreamingPlaylist" AS "VideoStreamingPlaylists" ON "VideoStreamingPlaylists"."videoId" = "video"."id"', | |
d9bf974f | 102 | |
1d43c3a6 | 103 | joinType + ' JOIN "videoFile" AS "VideoStreamingPlaylists->VideoFiles" ' + |
d9bf974f C |
104 | 'ON "VideoStreamingPlaylists->VideoFiles"."videoStreamingPlaylistId" = "VideoStreamingPlaylists"."id"' |
105 | ) | |
106 | ||
107 | this.attributes = { | |
108 | ...this.attributes, | |
109 | ||
d9bf974f C |
110 | ...this.buildAttributesObject('VideoStreamingPlaylists', this.videoAttributes.getStreamingPlaylistAttributes()), |
111 | ...this.buildAttributesObject('VideoStreamingPlaylists->VideoFiles', this.videoAttributes.getFileAttributes()) | |
112 | } | |
113 | } | |
114 | ||
115 | protected includeUserHistory (userId: number) { | |
116 | this.joins.push( | |
117 | 'LEFT OUTER JOIN "userVideoHistory" ' + | |
118 | 'ON "video"."id" = "userVideoHistory"."videoId" AND "userVideoHistory"."userId" = :userVideoHistoryId' | |
119 | ) | |
120 | ||
121 | this.replacements.userVideoHistoryId = userId | |
122 | ||
123 | this.attributes = { | |
124 | ...this.attributes, | |
125 | ||
126 | ...this.buildAttributesObject('userVideoHistory', this.videoAttributes.getUserHistoryAttributes()) | |
127 | } | |
128 | } | |
129 | ||
130 | protected includePlaylist (playlistId: number) { | |
131 | this.joins.push( | |
132 | 'INNER JOIN "videoPlaylistElement" as "VideoPlaylistElement" ON "videoPlaylistElement"."videoId" = "video"."id" ' + | |
133 | 'AND "VideoPlaylistElement"."videoPlaylistId" = :videoPlaylistId' | |
134 | ) | |
135 | ||
136 | this.replacements.videoPlaylistId = playlistId | |
137 | ||
138 | this.attributes = { | |
139 | ...this.attributes, | |
140 | ||
141 | ...this.buildAttributesObject('VideoPlaylistElement', this.videoAttributes.getPlaylistAttributes()) | |
142 | } | |
143 | } | |
144 | ||
145 | protected includeTags () { | |
146 | this.joins.push( | |
147 | 'LEFT OUTER JOIN (' + | |
148 | '"videoTag" AS "Tags->VideoTagModel" INNER JOIN "tag" AS "Tags" ON "Tags"."id" = "Tags->VideoTagModel"."tagId"' + | |
149 | ') ' + | |
150 | 'ON "video"."id" = "Tags->VideoTagModel"."videoId"' | |
151 | ) | |
152 | ||
153 | this.attributes = { | |
154 | ...this.attributes, | |
155 | ||
156 | ...this.buildAttributesObject('Tags', this.videoAttributes.getTagAttributes()), | |
157 | ...this.buildAttributesObject('Tags->VideoTagModel', this.videoAttributes.getVideoTagAttributes()) | |
158 | } | |
159 | } | |
160 | ||
161 | protected includeBlacklisted () { | |
162 | this.joins.push( | |
163 | 'LEFT OUTER JOIN "videoBlacklist" AS "VideoBlacklist" ON "video"."id" = "VideoBlacklist"."videoId"' | |
164 | ) | |
165 | ||
166 | this.attributes = { | |
167 | ...this.attributes, | |
168 | ||
169 | ...this.buildAttributesObject('VideoBlacklist', this.videoAttributes.getBlacklistedAttributes()) | |
170 | } | |
171 | } | |
172 | ||
173 | protected includeScheduleUpdate () { | |
174 | this.joins.push( | |
175 | 'LEFT OUTER JOIN "scheduleVideoUpdate" AS "ScheduleVideoUpdate" ON "video"."id" = "ScheduleVideoUpdate"."videoId"' | |
176 | ) | |
177 | ||
178 | this.attributes = { | |
179 | ...this.attributes, | |
180 | ||
181 | ...this.buildAttributesObject('ScheduleVideoUpdate', this.videoAttributes.getScheduleUpdateAttributes()) | |
182 | } | |
183 | } | |
184 | ||
185 | protected includeLive () { | |
186 | this.joins.push( | |
187 | 'LEFT OUTER JOIN "videoLive" AS "VideoLive" ON "video"."id" = "VideoLive"."videoId"' | |
188 | ) | |
189 | ||
190 | this.attributes = { | |
191 | ...this.attributes, | |
192 | ||
193 | ...this.buildAttributesObject('VideoLive', this.videoAttributes.getLiveAttributes()) | |
194 | } | |
195 | } | |
196 | ||
197 | protected includeTrackers () { | |
198 | this.joins.push( | |
199 | 'LEFT OUTER JOIN (' + | |
200 | '"videoTracker" AS "Trackers->VideoTrackerModel" ' + | |
201 | 'INNER JOIN "tracker" AS "Trackers" ON "Trackers"."id" = "Trackers->VideoTrackerModel"."trackerId"' + | |
202 | ') ON "video"."id" = "Trackers->VideoTrackerModel"."videoId"' | |
203 | ) | |
204 | ||
205 | this.attributes = { | |
206 | ...this.attributes, | |
207 | ||
208 | ...this.buildAttributesObject('Trackers', this.videoAttributes.getTrackerAttributes()), | |
209 | ...this.buildAttributesObject('Trackers->VideoTrackerModel', this.videoAttributes.getVideoTrackerAttributes()) | |
210 | } | |
211 | } | |
212 | ||
1d43c3a6 | 213 | protected includeWebTorrentRedundancies () { |
d9bf974f | 214 | this.joins.push( |
d9bf974f C |
215 | 'LEFT OUTER JOIN "videoRedundancy" AS "VideoFiles->RedundancyVideos" ON ' + |
216 | '"VideoFiles"."id" = "VideoFiles->RedundancyVideos"."videoFileId"' | |
217 | ) | |
218 | ||
219 | this.attributes = { | |
220 | ...this.attributes, | |
221 | ||
1d43c3a6 C |
222 | ...this.buildAttributesObject('VideoFiles->RedundancyVideos', this.videoAttributes.getRedundancyAttributes()) |
223 | } | |
224 | } | |
225 | ||
226 | protected includeStreamingPlaylistRedundancies () { | |
227 | this.joins.push( | |
228 | 'LEFT OUTER JOIN "videoRedundancy" AS "VideoStreamingPlaylists->RedundancyVideos" ' + | |
229 | 'ON "VideoStreamingPlaylists"."id" = "VideoStreamingPlaylists->RedundancyVideos"."videoStreamingPlaylistId"' | |
230 | ) | |
231 | ||
232 | this.attributes = { | |
233 | ...this.attributes, | |
234 | ||
d9bf974f C |
235 | ...this.buildAttributesObject('VideoStreamingPlaylists->RedundancyVideos', this.videoAttributes.getRedundancyAttributes()) |
236 | } | |
237 | } | |
238 | ||
239 | protected buildActorInclude (prefixKey: string) { | |
240 | return this.buildAttributesObject(prefixKey, this.videoAttributes.getActorAttributes()) | |
241 | } | |
242 | ||
243 | protected buildAvatarInclude (prefixKey: string) { | |
244 | return this.buildAttributesObject(prefixKey, this.videoAttributes.getAvatarAttributes()) | |
245 | } | |
246 | ||
247 | protected buildServerInclude (prefixKey: string) { | |
248 | return this.buildAttributesObject(prefixKey, this.videoAttributes.getServerAttributes()) | |
249 | } | |
250 | ||
251 | protected buildAttributesObject (prefixKey: string, attributeKeys: string[]) { | |
252 | const result: { [id: string]: string} = {} | |
253 | ||
254 | const prefixValue = prefixKey.replace(/->/g, '.') | |
255 | ||
256 | for (const attribute of attributeKeys) { | |
257 | result[`"${prefixKey}"."${attribute}"`] = `"${prefixValue}.${attribute}"` | |
258 | } | |
259 | ||
260 | return result | |
261 | } | |
1d43c3a6 C |
262 | |
263 | protected whereId (id: string | number) { | |
264 | if (validator.isInt('' + id)) { | |
265 | this.where = 'WHERE "video".id = :videoId' | |
266 | } else { | |
267 | this.where = 'WHERE uuid = :videoId' | |
268 | } | |
269 | ||
270 | this.replacements.videoId = id | |
271 | } | |
d9bf974f | 272 | } |