]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/models/video/sql/shared/abstract-videos-model-query-builder.ts
Optimize rows parsing
[github/Chocobozzz/PeerTube.git] / server / models / video / sql / shared / abstract-videos-model-query-builder.ts
CommitLineData
1d43c3a6 1import validator from 'validator'
d9bf974f 2import { AbstractVideosQueryBuilder } from './abstract-videos-query-builder'
17bb4538 3import { VideoTables } from './video-tables'
1d43c3a6
C
4
5/**
6 *
7 * Abstract builder to create SQL query and fetch video models
8 *
9 */
d9bf974f
C
10
11export class AbstractVideosModelQueryBuilder extends AbstractVideosQueryBuilder {
12 protected attributes: { [key: string]: string } = {}
13 protected joins: string[] = []
1d43c3a6 14 protected where: string
d9bf974f 15
17bb4538 16 protected tables: VideoTables
d9bf974f 17
1d43c3a6 18 constructor (protected readonly mode: 'list' | 'get') {
d9bf974f
C
19 super()
20
17bb4538 21 this.tables = new VideoTables(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
17bb4538 47 ...this.buildAttributesObject('VideoChannel', this.tables.getChannelAttributes()),
d9bf974f
C
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
17bb4538 69 ...this.buildAttributesObject('VideoChannel->Account', this.tables.getAccountAttributes()),
d9bf974f
C
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
17bb4538 82 ...this.buildAttributesObject('Thumbnails', this.tables.getThumbnailAttributes())
d9bf974f
C
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
17bb4538 93 ...this.buildAttributesObject('VideoFiles', this.tables.getFileAttributes())
1d43c3a6
C
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
17bb4538
C
110 ...this.buildAttributesObject('VideoStreamingPlaylists', this.tables.getStreamingPlaylistAttributes()),
111 ...this.buildAttributesObject('VideoStreamingPlaylists->VideoFiles', this.tables.getFileAttributes())
d9bf974f
C
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
17bb4538 126 ...this.buildAttributesObject('userVideoHistory', this.tables.getUserHistoryAttributes())
d9bf974f
C
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
17bb4538 141 ...this.buildAttributesObject('VideoPlaylistElement', this.tables.getPlaylistAttributes())
d9bf974f
C
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
17bb4538
C
156 ...this.buildAttributesObject('Tags', this.tables.getTagAttributes()),
157 ...this.buildAttributesObject('Tags->VideoTagModel', this.tables.getVideoTagAttributes())
d9bf974f
C
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
17bb4538 169 ...this.buildAttributesObject('VideoBlacklist', this.tables.getBlacklistedAttributes())
d9bf974f
C
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
17bb4538 181 ...this.buildAttributesObject('ScheduleVideoUpdate', this.tables.getScheduleUpdateAttributes())
d9bf974f
C
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
17bb4538 193 ...this.buildAttributesObject('VideoLive', this.tables.getLiveAttributes())
d9bf974f
C
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
17bb4538
C
208 ...this.buildAttributesObject('Trackers', this.tables.getTrackerAttributes()),
209 ...this.buildAttributesObject('Trackers->VideoTrackerModel', this.tables.getVideoTrackerAttributes())
d9bf974f
C
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
17bb4538 222 ...this.buildAttributesObject('VideoFiles->RedundancyVideos', this.tables.getRedundancyAttributes())
1d43c3a6
C
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
17bb4538 235 ...this.buildAttributesObject('VideoStreamingPlaylists->RedundancyVideos', this.tables.getRedundancyAttributes())
d9bf974f
C
236 }
237 }
238
239 protected buildActorInclude (prefixKey: string) {
17bb4538 240 return this.buildAttributesObject(prefixKey, this.tables.getActorAttributes())
d9bf974f
C
241 }
242
243 protected buildAvatarInclude (prefixKey: string) {
17bb4538 244 return this.buildAttributesObject(prefixKey, this.tables.getAvatarAttributes())
d9bf974f
C
245 }
246
247 protected buildServerInclude (prefixKey: string) {
17bb4538 248 return this.buildAttributesObject(prefixKey, this.tables.getServerAttributes())
d9bf974f
C
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}