aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models/video/sql/shared
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2021-06-11 14:09:33 +0200
committerChocobozzz <me@florianbigard.com>2021-06-11 14:09:52 +0200
commit71d4af1efc810f853e1a0d986bf758c201692594 (patch)
tree2066053638baefb6430772c2e0a0aa1774019a51 /server/models/video/sql/shared
parent3c79c2ce86eaf9e151ab6c2c9d1f646968a16744 (diff)
downloadPeerTube-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')
-rw-r--r--server/models/video/sql/shared/abstract-videos-model-query-builder.ts24
-rw-r--r--server/models/video/sql/shared/abstract-videos-query-builder.ts9
-rw-r--r--server/models/video/sql/shared/video-file-query-builder.ts16
-rw-r--r--server/models/video/sql/shared/video-model-builder.ts36
-rw-r--r--server/models/video/sql/shared/video-tables.ts8
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
2import { logger } from '@server/helpers/logger'
3import { AccountModel } from '@server/models/account/account' 2import { AccountModel } from '@server/models/account/account'
4import { ActorModel } from '@server/models/actor/actor' 3import { ActorModel } from '@server/models/actor/actor'
5import { ActorImageModel } from '@server/models/actor/actor-image' 4import { 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