diff options
author | Chocobozzz <me@florianbigard.com> | 2021-06-10 14:43:55 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2021-06-10 15:26:18 +0200 |
commit | d9bf974f5df787bbeaab5b04949ca91a2b3ca2a3 (patch) | |
tree | aa02ee0cc28c845432e91da43b1e6de2a2f04039 /server/models/video/sql/shared/abstract-videos-model-query-builder.ts | |
parent | e5dbd5084e7ae91ce118c0bccd5b84c47b88c55f (diff) | |
download | PeerTube-d9bf974f5df787bbeaab5b04949ca91a2b3ca2a3.tar.gz PeerTube-d9bf974f5df787bbeaab5b04949ca91a2b3ca2a3.tar.zst PeerTube-d9bf974f5df787bbeaab5b04949ca91a2b3ca2a3.zip |
Use raw SQL for video get request
Diffstat (limited to 'server/models/video/sql/shared/abstract-videos-model-query-builder.ts')
-rw-r--r-- | server/models/video/sql/shared/abstract-videos-model-query-builder.ts | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/server/models/video/sql/shared/abstract-videos-model-query-builder.ts b/server/models/video/sql/shared/abstract-videos-model-query-builder.ts new file mode 100644 index 000000000..bdf926cbe --- /dev/null +++ b/server/models/video/sql/shared/abstract-videos-model-query-builder.ts | |||
@@ -0,0 +1,239 @@ | |||
1 | import { AbstractVideosQueryBuilder } from './abstract-videos-query-builder' | ||
2 | import { VideoAttributes } from './video-attributes' | ||
3 | import { VideoModelBuilder } from './video-model-builder' | ||
4 | |||
5 | export class AbstractVideosModelQueryBuilder extends AbstractVideosQueryBuilder { | ||
6 | protected attributes: { [key: string]: string } = {} | ||
7 | protected joins: string[] = [] | ||
8 | |||
9 | protected videoAttributes: VideoAttributes | ||
10 | protected videoModelBuilder: VideoModelBuilder | ||
11 | |||
12 | constructor (private readonly mode: 'list' | 'get') { | ||
13 | super() | ||
14 | |||
15 | this.videoAttributes = new VideoAttributes(this.mode) | ||
16 | this.videoModelBuilder = new VideoModelBuilder(this.mode, this.videoAttributes) | ||
17 | } | ||
18 | |||
19 | protected buildSelect () { | ||
20 | return 'SELECT ' + Object.keys(this.attributes).map(key => { | ||
21 | const value = this.attributes[key] | ||
22 | if (value) return `${key} AS ${value}` | ||
23 | |||
24 | return key | ||
25 | }).join(', ') | ||
26 | } | ||
27 | |||
28 | protected includeChannels () { | ||
29 | this.joins.push( | ||
30 | 'INNER JOIN "videoChannel" AS "VideoChannel" ON "video"."channelId" = "VideoChannel"."id"', | ||
31 | 'INNER JOIN "actor" AS "VideoChannel->Actor" ON "VideoChannel"."actorId" = "VideoChannel->Actor"."id"', | ||
32 | |||
33 | 'LEFT OUTER JOIN "server" AS "VideoChannel->Actor->Server" ON "VideoChannel->Actor"."serverId" = "VideoChannel->Actor->Server"."id"', | ||
34 | |||
35 | 'LEFT OUTER JOIN "actorImage" AS "VideoChannel->Actor->Avatar" ' + | ||
36 | 'ON "VideoChannel->Actor"."avatarId" = "VideoChannel->Actor->Avatar"."id"' | ||
37 | ) | ||
38 | |||
39 | this.attributes = { | ||
40 | ...this.attributes, | ||
41 | |||
42 | ...this.buildAttributesObject('VideoChannel', this.videoAttributes.getChannelAttributes()), | ||
43 | ...this.buildActorInclude('VideoChannel->Actor'), | ||
44 | ...this.buildAvatarInclude('VideoChannel->Actor->Avatar'), | ||
45 | ...this.buildServerInclude('VideoChannel->Actor->Server') | ||
46 | } | ||
47 | } | ||
48 | |||
49 | protected includeAccounts () { | ||
50 | this.joins.push( | ||
51 | 'INNER JOIN "account" AS "VideoChannel->Account" ON "VideoChannel"."accountId" = "VideoChannel->Account"."id"', | ||
52 | 'INNER JOIN "actor" AS "VideoChannel->Account->Actor" ON "VideoChannel->Account"."actorId" = "VideoChannel->Account->Actor"."id"', | ||
53 | |||
54 | 'LEFT OUTER JOIN "server" AS "VideoChannel->Account->Actor->Server" ' + | ||
55 | 'ON "VideoChannel->Account->Actor"."serverId" = "VideoChannel->Account->Actor->Server"."id"', | ||
56 | |||
57 | 'LEFT OUTER JOIN "actorImage" AS "VideoChannel->Account->Actor->Avatar" ' + | ||
58 | 'ON "VideoChannel->Account->Actor"."avatarId" = "VideoChannel->Account->Actor->Avatar"."id"' | ||
59 | ) | ||
60 | |||
61 | this.attributes = { | ||
62 | ...this.attributes, | ||
63 | |||
64 | ...this.buildAttributesObject('VideoChannel->Account', this.videoAttributes.getAccountAttributes()), | ||
65 | ...this.buildActorInclude('VideoChannel->Account->Actor'), | ||
66 | ...this.buildAvatarInclude('VideoChannel->Account->Actor->Avatar'), | ||
67 | ...this.buildServerInclude('VideoChannel->Account->Actor->Server') | ||
68 | } | ||
69 | } | ||
70 | |||
71 | protected includeThumbnails () { | ||
72 | this.joins.push('LEFT OUTER JOIN "thumbnail" AS "Thumbnails" ON "video"."id" = "Thumbnails"."videoId"') | ||
73 | |||
74 | this.attributes = { | ||
75 | ...this.attributes, | ||
76 | |||
77 | ...this.buildAttributesObject('Thumbnails', this.videoAttributes.getThumbnailAttributes()) | ||
78 | } | ||
79 | } | ||
80 | |||
81 | protected includeFiles () { | ||
82 | this.joins.push( | ||
83 | 'LEFT JOIN "videoFile" AS "VideoFiles" ON "VideoFiles"."videoId" = "video"."id"', | ||
84 | |||
85 | 'LEFT JOIN "videoStreamingPlaylist" AS "VideoStreamingPlaylists" ON "VideoStreamingPlaylists"."videoId" = "video"."id"', | ||
86 | |||
87 | 'LEFT JOIN "videoFile" AS "VideoStreamingPlaylists->VideoFiles" ' + | ||
88 | 'ON "VideoStreamingPlaylists->VideoFiles"."videoStreamingPlaylistId" = "VideoStreamingPlaylists"."id"' | ||
89 | ) | ||
90 | |||
91 | this.attributes = { | ||
92 | ...this.attributes, | ||
93 | |||
94 | ...this.buildAttributesObject('VideoFiles', this.videoAttributes.getFileAttributes()), | ||
95 | |||
96 | ...this.buildAttributesObject('VideoStreamingPlaylists', this.videoAttributes.getStreamingPlaylistAttributes()), | ||
97 | ...this.buildAttributesObject('VideoStreamingPlaylists->VideoFiles', this.videoAttributes.getFileAttributes()) | ||
98 | } | ||
99 | } | ||
100 | |||
101 | protected includeUserHistory (userId: number) { | ||
102 | this.joins.push( | ||
103 | 'LEFT OUTER JOIN "userVideoHistory" ' + | ||
104 | 'ON "video"."id" = "userVideoHistory"."videoId" AND "userVideoHistory"."userId" = :userVideoHistoryId' | ||
105 | ) | ||
106 | |||
107 | this.replacements.userVideoHistoryId = userId | ||
108 | |||
109 | this.attributes = { | ||
110 | ...this.attributes, | ||
111 | |||
112 | ...this.buildAttributesObject('userVideoHistory', this.videoAttributes.getUserHistoryAttributes()) | ||
113 | } | ||
114 | } | ||
115 | |||
116 | protected includePlaylist (playlistId: number) { | ||
117 | this.joins.push( | ||
118 | 'INNER JOIN "videoPlaylistElement" as "VideoPlaylistElement" ON "videoPlaylistElement"."videoId" = "video"."id" ' + | ||
119 | 'AND "VideoPlaylistElement"."videoPlaylistId" = :videoPlaylistId' | ||
120 | ) | ||
121 | |||
122 | this.replacements.videoPlaylistId = playlistId | ||
123 | |||
124 | this.attributes = { | ||
125 | ...this.attributes, | ||
126 | |||
127 | ...this.buildAttributesObject('VideoPlaylistElement', this.videoAttributes.getPlaylistAttributes()) | ||
128 | } | ||
129 | } | ||
130 | |||
131 | protected includeTags () { | ||
132 | this.joins.push( | ||
133 | 'LEFT OUTER JOIN (' + | ||
134 | '"videoTag" AS "Tags->VideoTagModel" INNER JOIN "tag" AS "Tags" ON "Tags"."id" = "Tags->VideoTagModel"."tagId"' + | ||
135 | ') ' + | ||
136 | 'ON "video"."id" = "Tags->VideoTagModel"."videoId"' | ||
137 | ) | ||
138 | |||
139 | this.attributes = { | ||
140 | ...this.attributes, | ||
141 | |||
142 | ...this.buildAttributesObject('Tags', this.videoAttributes.getTagAttributes()), | ||
143 | ...this.buildAttributesObject('Tags->VideoTagModel', this.videoAttributes.getVideoTagAttributes()) | ||
144 | } | ||
145 | } | ||
146 | |||
147 | protected includeBlacklisted () { | ||
148 | this.joins.push( | ||
149 | 'LEFT OUTER JOIN "videoBlacklist" AS "VideoBlacklist" ON "video"."id" = "VideoBlacklist"."videoId"' | ||
150 | ) | ||
151 | |||
152 | this.attributes = { | ||
153 | ...this.attributes, | ||
154 | |||
155 | ...this.buildAttributesObject('VideoBlacklist', this.videoAttributes.getBlacklistedAttributes()) | ||
156 | } | ||
157 | } | ||
158 | |||
159 | protected includeScheduleUpdate () { | ||
160 | this.joins.push( | ||
161 | 'LEFT OUTER JOIN "scheduleVideoUpdate" AS "ScheduleVideoUpdate" ON "video"."id" = "ScheduleVideoUpdate"."videoId"' | ||
162 | ) | ||
163 | |||
164 | this.attributes = { | ||
165 | ...this.attributes, | ||
166 | |||
167 | ...this.buildAttributesObject('ScheduleVideoUpdate', this.videoAttributes.getScheduleUpdateAttributes()) | ||
168 | } | ||
169 | } | ||
170 | |||
171 | protected includeLive () { | ||
172 | this.joins.push( | ||
173 | 'LEFT OUTER JOIN "videoLive" AS "VideoLive" ON "video"."id" = "VideoLive"."videoId"' | ||
174 | ) | ||
175 | |||
176 | this.attributes = { | ||
177 | ...this.attributes, | ||
178 | |||
179 | ...this.buildAttributesObject('VideoLive', this.videoAttributes.getLiveAttributes()) | ||
180 | } | ||
181 | } | ||
182 | |||
183 | protected includeTrackers () { | ||
184 | this.joins.push( | ||
185 | 'LEFT OUTER JOIN (' + | ||
186 | '"videoTracker" AS "Trackers->VideoTrackerModel" ' + | ||
187 | 'INNER JOIN "tracker" AS "Trackers" ON "Trackers"."id" = "Trackers->VideoTrackerModel"."trackerId"' + | ||
188 | ') ON "video"."id" = "Trackers->VideoTrackerModel"."videoId"' | ||
189 | ) | ||
190 | |||
191 | this.attributes = { | ||
192 | ...this.attributes, | ||
193 | |||
194 | ...this.buildAttributesObject('Trackers', this.videoAttributes.getTrackerAttributes()), | ||
195 | ...this.buildAttributesObject('Trackers->VideoTrackerModel', this.videoAttributes.getVideoTrackerAttributes()) | ||
196 | } | ||
197 | } | ||
198 | |||
199 | protected includeRedundancies () { | ||
200 | this.joins.push( | ||
201 | 'LEFT OUTER JOIN "videoRedundancy" AS "VideoStreamingPlaylists->RedundancyVideos" ' + | ||
202 | 'ON "VideoStreamingPlaylists"."id" = "VideoStreamingPlaylists->RedundancyVideos"."videoStreamingPlaylistId"', | ||
203 | |||
204 | 'LEFT OUTER JOIN "videoRedundancy" AS "VideoFiles->RedundancyVideos" ON ' + | ||
205 | '"VideoFiles"."id" = "VideoFiles->RedundancyVideos"."videoFileId"' | ||
206 | ) | ||
207 | |||
208 | this.attributes = { | ||
209 | ...this.attributes, | ||
210 | |||
211 | ...this.buildAttributesObject('VideoFiles->RedundancyVideos', this.videoAttributes.getRedundancyAttributes()), | ||
212 | ...this.buildAttributesObject('VideoStreamingPlaylists->RedundancyVideos', this.videoAttributes.getRedundancyAttributes()) | ||
213 | } | ||
214 | } | ||
215 | |||
216 | protected buildActorInclude (prefixKey: string) { | ||
217 | return this.buildAttributesObject(prefixKey, this.videoAttributes.getActorAttributes()) | ||
218 | } | ||
219 | |||
220 | protected buildAvatarInclude (prefixKey: string) { | ||
221 | return this.buildAttributesObject(prefixKey, this.videoAttributes.getAvatarAttributes()) | ||
222 | } | ||
223 | |||
224 | protected buildServerInclude (prefixKey: string) { | ||
225 | return this.buildAttributesObject(prefixKey, this.videoAttributes.getServerAttributes()) | ||
226 | } | ||
227 | |||
228 | protected buildAttributesObject (prefixKey: string, attributeKeys: string[]) { | ||
229 | const result: { [id: string]: string} = {} | ||
230 | |||
231 | const prefixValue = prefixKey.replace(/->/g, '.') | ||
232 | |||
233 | for (const attribute of attributeKeys) { | ||
234 | result[`"${prefixKey}"."${attribute}"`] = `"${prefixValue}.${attribute}"` | ||
235 | } | ||
236 | |||
237 | return result | ||
238 | } | ||
239 | } | ||