diff options
author | Chocobozzz <me@florianbigard.com> | 2021-06-11 14:09:33 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2021-06-11 14:09:52 +0200 |
commit | 71d4af1efc810f853e1a0d986bf758c201692594 (patch) | |
tree | 2066053638baefb6430772c2e0a0aa1774019a51 /server/models/video/sql/shared | |
parent | 3c79c2ce86eaf9e151ab6c2c9d1f646968a16744 (diff) | |
download | PeerTube-71d4af1efc810f853e1a0d986bf758c201692594.tar.gz PeerTube-71d4af1efc810f853e1a0d986bf758c201692594.tar.zst PeerTube-71d4af1efc810f853e1a0d986bf758c201692594.zip |
Use raw SQL for most of video queries
Diffstat (limited to 'server/models/video/sql/shared')
5 files changed, 65 insertions, 28 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 index 65df8d914..d959cb5d0 100644 --- a/server/models/video/sql/shared/abstract-videos-model-query-builder.ts +++ b/server/models/video/sql/shared/abstract-videos-model-query-builder.ts | |||
@@ -80,6 +80,18 @@ export class AbstractVideosModelQueryBuilder extends AbstractVideosQueryBuilder | |||
80 | } | 80 | } |
81 | } | 81 | } |
82 | 82 | ||
83 | protected includeOwnerUser () { | ||
84 | this.addJoin('INNER JOIN "videoChannel" AS "VideoChannel" ON "video"."channelId" = "VideoChannel"."id"') | ||
85 | this.addJoin('INNER JOIN "account" AS "VideoChannel->Account" ON "VideoChannel"."accountId" = "VideoChannel->Account"."id"') | ||
86 | |||
87 | this.attributes = { | ||
88 | ...this.attributes, | ||
89 | |||
90 | ...this.buildAttributesObject('VideoChannel', this.tables.getChannelAttributes()), | ||
91 | ...this.buildAttributesObject('VideoChannel->Account', this.tables.getUserAccountAttributes()) | ||
92 | } | ||
93 | } | ||
94 | |||
83 | protected includeThumbnails () { | 95 | protected includeThumbnails () { |
84 | this.addJoin('LEFT OUTER JOIN "thumbnail" AS "Thumbnails" ON "video"."id" = "Thumbnails"."videoId"') | 96 | this.addJoin('LEFT OUTER JOIN "thumbnail" AS "Thumbnails" ON "video"."id" = "Thumbnails"."videoId"') |
85 | 97 | ||
@@ -269,14 +281,20 @@ export class AbstractVideosModelQueryBuilder extends AbstractVideosQueryBuilder | |||
269 | return result | 281 | return result |
270 | } | 282 | } |
271 | 283 | ||
272 | protected whereId (id: string | number) { | 284 | protected whereId (options: { id?: string | number, url?: string }) { |
273 | if (validator.isInt('' + id)) { | 285 | if (options.url) { |
286 | this.where = 'WHERE "video"."url" = :videoUrl' | ||
287 | this.replacements.videoUrl = options.url | ||
288 | return | ||
289 | } | ||
290 | |||
291 | if (validator.isInt('' + options.id)) { | ||
274 | this.where = 'WHERE "video".id = :videoId' | 292 | this.where = 'WHERE "video".id = :videoId' |
275 | } else { | 293 | } else { |
276 | this.where = 'WHERE uuid = :videoId' | 294 | this.where = 'WHERE uuid = :videoId' |
277 | } | 295 | } |
278 | 296 | ||
279 | this.replacements.videoId = id | 297 | this.replacements.videoId = options.id |
280 | } | 298 | } |
281 | 299 | ||
282 | protected addJoin (join: string) { | 300 | protected addJoin (join: string) { |
diff --git a/server/models/video/sql/shared/abstract-videos-query-builder.ts b/server/models/video/sql/shared/abstract-videos-query-builder.ts index 7e67fa34f..10699317a 100644 --- a/server/models/video/sql/shared/abstract-videos-query-builder.ts +++ b/server/models/video/sql/shared/abstract-videos-query-builder.ts | |||
@@ -13,16 +13,17 @@ export class AbstractVideosQueryBuilder { | |||
13 | protected query: string | 13 | protected query: string |
14 | protected replacements: any = {} | 14 | protected replacements: any = {} |
15 | 15 | ||
16 | protected runQuery (transaction?: Transaction) { | 16 | protected runQuery (options: { transaction?: Transaction, logging?: boolean } = {}) { |
17 | logger.debug('Running videos query.', { query: this.query, replacements: this.replacements }) | 17 | logger.debug('Running videos query.', { query: this.query, replacements: this.replacements }) |
18 | 18 | ||
19 | const options = { | 19 | const queryOptions = { |
20 | transaction, | 20 | transaction: options.transaction, |
21 | logging: options.logging, | ||
21 | replacements: this.replacements, | 22 | replacements: this.replacements, |
22 | type: QueryTypes.SELECT as QueryTypes.SELECT, | 23 | type: QueryTypes.SELECT as QueryTypes.SELECT, |
23 | next: false | 24 | next: false |
24 | } | 25 | } |
25 | 26 | ||
26 | return this.sequelize.query<any>(this.query, options) | 27 | return this.sequelize.query<any>(this.query, queryOptions) |
27 | } | 28 | } |
28 | } | 29 | } |
diff --git a/server/models/video/sql/shared/video-file-query-builder.ts b/server/models/video/sql/shared/video-file-query-builder.ts index 7d822f8fa..a62fa64f8 100644 --- a/server/models/video/sql/shared/video-file-query-builder.ts +++ b/server/models/video/sql/shared/video-file-query-builder.ts | |||
@@ -18,13 +18,13 @@ export class VideoFileQueryBuilder extends AbstractVideosModelQueryBuilder { | |||
18 | queryWebTorrentVideos (options: BuildVideoGetQueryOptions) { | 18 | queryWebTorrentVideos (options: BuildVideoGetQueryOptions) { |
19 | this.buildWebtorrentFilesQuery(options) | 19 | this.buildWebtorrentFilesQuery(options) |
20 | 20 | ||
21 | return this.runQuery(options.transaction) | 21 | return this.runQuery(options) |
22 | } | 22 | } |
23 | 23 | ||
24 | queryStreamingPlaylistVideos (options: BuildVideoGetQueryOptions) { | 24 | queryStreamingPlaylistVideos (options: BuildVideoGetQueryOptions) { |
25 | this.buildVideoStreamingPlaylistFilesQuery(options) | 25 | this.buildVideoStreamingPlaylistFilesQuery(options) |
26 | 26 | ||
27 | return this.runQuery(options.transaction) | 27 | return this.runQuery(options) |
28 | } | 28 | } |
29 | 29 | ||
30 | private buildWebtorrentFilesQuery (options: BuildVideoGetQueryOptions) { | 30 | private buildWebtorrentFilesQuery (options: BuildVideoGetQueryOptions) { |
@@ -34,11 +34,11 @@ export class VideoFileQueryBuilder extends AbstractVideosModelQueryBuilder { | |||
34 | 34 | ||
35 | this.includeWebtorrentFiles(true) | 35 | this.includeWebtorrentFiles(true) |
36 | 36 | ||
37 | if (options.forGetAPI === true) { | 37 | if (this.shouldIncludeRedundancies(options)) { |
38 | this.includeWebTorrentRedundancies() | 38 | this.includeWebTorrentRedundancies() |
39 | } | 39 | } |
40 | 40 | ||
41 | this.whereId(options.id) | 41 | this.whereId(options) |
42 | 42 | ||
43 | this.query = this.buildQuery() | 43 | this.query = this.buildQuery() |
44 | } | 44 | } |
@@ -50,11 +50,11 @@ export class VideoFileQueryBuilder extends AbstractVideosModelQueryBuilder { | |||
50 | 50 | ||
51 | this.includeStreamingPlaylistFiles(true) | 51 | this.includeStreamingPlaylistFiles(true) |
52 | 52 | ||
53 | if (options.forGetAPI === true) { | 53 | if (this.shouldIncludeRedundancies(options)) { |
54 | this.includeStreamingPlaylistRedundancies() | 54 | this.includeStreamingPlaylistRedundancies() |
55 | } | 55 | } |
56 | 56 | ||
57 | this.whereId(options.id) | 57 | this.whereId(options) |
58 | 58 | ||
59 | this.query = this.buildQuery() | 59 | this.query = this.buildQuery() |
60 | } | 60 | } |
@@ -62,4 +62,8 @@ export class VideoFileQueryBuilder extends AbstractVideosModelQueryBuilder { | |||
62 | private buildQuery () { | 62 | private buildQuery () { |
63 | return `${this.buildSelect()} FROM "video" ${this.joins} ${this.where}` | 63 | return `${this.buildSelect()} FROM "video" ${this.joins} ${this.where}` |
64 | } | 64 | } |
65 | |||
66 | private shouldIncludeRedundancies (options: BuildVideoGetQueryOptions) { | ||
67 | return options.type === 'api' | ||
68 | } | ||
65 | } | 69 | } |
diff --git a/server/models/video/sql/shared/video-model-builder.ts b/server/models/video/sql/shared/video-model-builder.ts index 2a60dab04..467a9378a 100644 --- a/server/models/video/sql/shared/video-model-builder.ts +++ b/server/models/video/sql/shared/video-model-builder.ts | |||
@@ -1,5 +1,4 @@ | |||
1 | 1 | ||
2 | import { logger } from '@server/helpers/logger' | ||
3 | import { AccountModel } from '@server/models/account/account' | 2 | import { AccountModel } from '@server/models/account/account' |
4 | import { ActorModel } from '@server/models/actor/actor' | 3 | import { ActorModel } from '@server/models/actor/actor' |
5 | import { ActorImageModel } from '@server/models/actor/actor-image' | 4 | import { ActorImageModel } from '@server/models/actor/actor-image' |
@@ -56,7 +55,7 @@ export class VideoModelBuilder { | |||
56 | this.reinit() | 55 | this.reinit() |
57 | 56 | ||
58 | for (const row of rows) { | 57 | for (const row of rows) { |
59 | this.buildVideo(row) | 58 | this.buildVideoAndAccount(row) |
60 | 59 | ||
61 | const videoModel = this.videosMemo[row.id] | 60 | const videoModel = this.videosMemo[row.id] |
62 | 61 | ||
@@ -131,22 +130,10 @@ export class VideoModelBuilder { | |||
131 | } | 130 | } |
132 | } | 131 | } |
133 | 132 | ||
134 | private buildVideo (row: SQLRow) { | 133 | private buildVideoAndAccount (row: SQLRow) { |
135 | if (this.videosMemo[row.id]) return | 134 | if (this.videosMemo[row.id]) return |
136 | 135 | ||
137 | // Build Channel | ||
138 | const channelModel = new VideoChannelModel(this.grab(row, this.tables.getChannelAttributes(), 'VideoChannel'), this.buildOpts) | ||
139 | channelModel.Actor = this.buildActor(row, 'VideoChannel') | ||
140 | |||
141 | const accountModel = new AccountModel(this.grab(row, this.tables.getAccountAttributes(), 'VideoChannel.Account'), this.buildOpts) | ||
142 | accountModel.Actor = this.buildActor(row, 'VideoChannel.Account') | ||
143 | |||
144 | channelModel.Account = accountModel | ||
145 | |||
146 | const videoModel = new VideoModel(this.grab(row, this.tables.getVideoAttributes(), ''), this.buildOpts) | 136 | const videoModel = new VideoModel(this.grab(row, this.tables.getVideoAttributes(), ''), this.buildOpts) |
147 | videoModel.VideoChannel = channelModel | ||
148 | |||
149 | this.videosMemo[row.id] = videoModel | ||
150 | 137 | ||
151 | videoModel.UserVideoHistories = [] | 138 | videoModel.UserVideoHistories = [] |
152 | videoModel.Thumbnails = [] | 139 | videoModel.Thumbnails = [] |
@@ -155,10 +142,29 @@ export class VideoModelBuilder { | |||
155 | videoModel.Tags = [] | 142 | videoModel.Tags = [] |
156 | videoModel.Trackers = [] | 143 | videoModel.Trackers = [] |
157 | 144 | ||
145 | this.buildAccount(row, videoModel) | ||
146 | |||
147 | this.videosMemo[row.id] = videoModel | ||
148 | |||
158 | // Keep rows order | 149 | // Keep rows order |
159 | this.videos.push(videoModel) | 150 | this.videos.push(videoModel) |
160 | } | 151 | } |
161 | 152 | ||
153 | private buildAccount (row: SQLRow, videoModel: VideoModel) { | ||
154 | const id = row['VideoChannel.Account.id'] | ||
155 | if (!id) return | ||
156 | |||
157 | const channelModel = new VideoChannelModel(this.grab(row, this.tables.getChannelAttributes(), 'VideoChannel'), this.buildOpts) | ||
158 | channelModel.Actor = this.buildActor(row, 'VideoChannel') | ||
159 | |||
160 | const accountModel = new AccountModel(this.grab(row, this.tables.getAccountAttributes(), 'VideoChannel.Account'), this.buildOpts) | ||
161 | accountModel.Actor = this.buildActor(row, 'VideoChannel.Account') | ||
162 | |||
163 | channelModel.Account = accountModel | ||
164 | |||
165 | videoModel.VideoChannel = channelModel | ||
166 | } | ||
167 | |||
162 | private buildActor (row: SQLRow, prefix: string) { | 168 | private buildActor (row: SQLRow, prefix: string) { |
163 | const actorPrefix = `${prefix}.Actor` | 169 | const actorPrefix = `${prefix}.Actor` |
164 | const avatarPrefix = `${actorPrefix}.Avatar` | 170 | const avatarPrefix = `${actorPrefix}.Avatar` |
diff --git a/server/models/video/sql/shared/video-tables.ts b/server/models/video/sql/shared/video-tables.ts index fddf1210c..52929fa5e 100644 --- a/server/models/video/sql/shared/video-tables.ts +++ b/server/models/video/sql/shared/video-tables.ts | |||
@@ -10,6 +10,10 @@ export class VideoTables { | |||
10 | 10 | ||
11 | } | 11 | } |
12 | 12 | ||
13 | getChannelAttributesForUser () { | ||
14 | return [ 'id', 'accountId' ] | ||
15 | } | ||
16 | |||
13 | getChannelAttributes () { | 17 | getChannelAttributes () { |
14 | let attributeKeys = [ | 18 | let attributeKeys = [ |
15 | 'id', | 19 | 'id', |
@@ -29,6 +33,10 @@ export class VideoTables { | |||
29 | return attributeKeys | 33 | return attributeKeys |
30 | } | 34 | } |
31 | 35 | ||
36 | getUserAccountAttributes () { | ||
37 | return [ 'id', 'userId' ] | ||
38 | } | ||
39 | |||
32 | getAccountAttributes () { | 40 | getAccountAttributes () { |
33 | let attributeKeys = [ 'id', 'name', 'actorId' ] | 41 | let attributeKeys = [ 'id', 'name', 'actorId' ] |
34 | 42 | ||