aboutsummaryrefslogtreecommitdiffhomepage
path: root/server
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2021-06-10 16:57:13 +0200
committerChocobozzz <me@florianbigard.com>2021-06-11 09:31:59 +0200
commit1d43c3a613c72d69f7360fee9e5bfe6f662d62f7 (patch)
treed4ba891ffdb1182e39620c06feff1503365d66b5 /server
parentd9bf974f5df787bbeaab5b04949ca91a2b3ca2a3 (diff)
downloadPeerTube-1d43c3a613c72d69f7360fee9e5bfe6f662d62f7.tar.gz
PeerTube-1d43c3a613c72d69f7360fee9e5bfe6f662d62f7.tar.zst
PeerTube-1d43c3a613c72d69f7360fee9e5bfe6f662d62f7.zip
Use separate queries for video files
Diffstat (limited to 'server')
-rw-r--r--server/controllers/api/videos/index.ts2
-rw-r--r--server/models/video/sql/shared/abstract-videos-model-query-builder.ts65
-rw-r--r--server/models/video/sql/shared/abstract-videos-query-builder.ts6
-rw-r--r--server/models/video/sql/shared/video-attributes.ts6
-rw-r--r--server/models/video/sql/shared/video-file-query-builder.ts66
-rw-r--r--server/models/video/sql/shared/video-model-builder.ts37
-rw-r--r--server/models/video/sql/video-model-get-query-builder.ts87
-rw-r--r--server/models/video/sql/videos-id-list-query-builder.ts6
-rw-r--r--server/models/video/sql/videos-model-list-query-builder.ts14
9 files changed, 232 insertions, 57 deletions
diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts
index 8c6c44144..35992e993 100644
--- a/server/controllers/api/videos/index.ts
+++ b/server/controllers/api/videos/index.ts
@@ -147,7 +147,7 @@ async function getVideo (_req: express.Request, res: express.Response) {
147 147
148 const video = await Hooks.wrapPromiseFun( 148 const video = await Hooks.wrapPromiseFun(
149 VideoModel.loadForGetAPI, 149 VideoModel.loadForGetAPI,
150 { id: res.locals.onlyVideoWithRights.id, userId }, 150 { id: _req.params.id, userId },
151 'filter:api.video.get.result' 151 'filter:api.video.get.result'
152 ) 152 )
153 153
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 bdf926cbe..8ed207eea 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
@@ -1,19 +1,24 @@
1import validator from 'validator'
1import { AbstractVideosQueryBuilder } from './abstract-videos-query-builder' 2import { AbstractVideosQueryBuilder } from './abstract-videos-query-builder'
2import { VideoAttributes } from './video-attributes' 3import { VideoAttributes } from './video-attributes'
3import { VideoModelBuilder } from './video-model-builder' 4
5/**
6 *
7 * Abstract builder to create SQL query and fetch video models
8 *
9 */
4 10
5export class AbstractVideosModelQueryBuilder extends AbstractVideosQueryBuilder { 11export class AbstractVideosModelQueryBuilder extends AbstractVideosQueryBuilder {
6 protected attributes: { [key: string]: string } = {} 12 protected attributes: { [key: string]: string } = {}
7 protected joins: string[] = [] 13 protected joins: string[] = []
14 protected where: string
8 15
9 protected videoAttributes: VideoAttributes 16 protected videoAttributes: VideoAttributes
10 protected videoModelBuilder: VideoModelBuilder
11 17
12 constructor (private readonly mode: 'list' | 'get') { 18 constructor (protected readonly mode: 'list' | 'get') {
13 super() 19 super()
14 20
15 this.videoAttributes = new VideoAttributes(this.mode) 21 this.videoAttributes = new VideoAttributes(this.mode)
16 this.videoModelBuilder = new VideoModelBuilder(this.mode, this.videoAttributes)
17 } 22 }
18 23
19 protected buildSelect () { 24 protected buildSelect () {
@@ -78,21 +83,30 @@ export class AbstractVideosModelQueryBuilder extends AbstractVideosQueryBuilder
78 } 83 }
79 } 84 }
80 85
81 protected includeFiles () { 86 protected includeWebtorrentFiles (required: boolean) {
82 this.joins.push( 87 const joinType = required ? 'INNER' : 'LEFT'
83 'LEFT JOIN "videoFile" AS "VideoFiles" ON "VideoFiles"."videoId" = "video"."id"', 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'
84 99
85 'LEFT JOIN "videoStreamingPlaylist" AS "VideoStreamingPlaylists" ON "VideoStreamingPlaylists"."videoId" = "video"."id"', 100 this.joins.push(
101 joinType + ' JOIN "videoStreamingPlaylist" AS "VideoStreamingPlaylists" ON "VideoStreamingPlaylists"."videoId" = "video"."id"',
86 102
87 'LEFT JOIN "videoFile" AS "VideoStreamingPlaylists->VideoFiles" ' + 103 joinType + ' JOIN "videoFile" AS "VideoStreamingPlaylists->VideoFiles" ' +
88 'ON "VideoStreamingPlaylists->VideoFiles"."videoStreamingPlaylistId" = "VideoStreamingPlaylists"."id"' 104 'ON "VideoStreamingPlaylists->VideoFiles"."videoStreamingPlaylistId" = "VideoStreamingPlaylists"."id"'
89 ) 105 )
90 106
91 this.attributes = { 107 this.attributes = {
92 ...this.attributes, 108 ...this.attributes,
93 109
94 ...this.buildAttributesObject('VideoFiles', this.videoAttributes.getFileAttributes()),
95
96 ...this.buildAttributesObject('VideoStreamingPlaylists', this.videoAttributes.getStreamingPlaylistAttributes()), 110 ...this.buildAttributesObject('VideoStreamingPlaylists', this.videoAttributes.getStreamingPlaylistAttributes()),
97 ...this.buildAttributesObject('VideoStreamingPlaylists->VideoFiles', this.videoAttributes.getFileAttributes()) 111 ...this.buildAttributesObject('VideoStreamingPlaylists->VideoFiles', this.videoAttributes.getFileAttributes())
98 } 112 }
@@ -196,11 +210,8 @@ export class AbstractVideosModelQueryBuilder extends AbstractVideosQueryBuilder
196 } 210 }
197 } 211 }
198 212
199 protected includeRedundancies () { 213 protected includeWebTorrentRedundancies () {
200 this.joins.push( 214 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 ' + 215 'LEFT OUTER JOIN "videoRedundancy" AS "VideoFiles->RedundancyVideos" ON ' +
205 '"VideoFiles"."id" = "VideoFiles->RedundancyVideos"."videoFileId"' 216 '"VideoFiles"."id" = "VideoFiles->RedundancyVideos"."videoFileId"'
206 ) 217 )
@@ -208,7 +219,19 @@ export class AbstractVideosModelQueryBuilder extends AbstractVideosQueryBuilder
208 this.attributes = { 219 this.attributes = {
209 ...this.attributes, 220 ...this.attributes,
210 221
211 ...this.buildAttributesObject('VideoFiles->RedundancyVideos', this.videoAttributes.getRedundancyAttributes()), 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
212 ...this.buildAttributesObject('VideoStreamingPlaylists->RedundancyVideos', this.videoAttributes.getRedundancyAttributes()) 235 ...this.buildAttributesObject('VideoStreamingPlaylists->RedundancyVideos', this.videoAttributes.getRedundancyAttributes())
213 } 236 }
214 } 237 }
@@ -236,4 +259,14 @@ export class AbstractVideosModelQueryBuilder extends AbstractVideosQueryBuilder
236 259
237 return result 260 return result
238 } 261 }
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 }
239} 272}
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 01694e691..c1bbeb71e 100644
--- a/server/models/video/sql/shared/abstract-videos-query-builder.ts
+++ b/server/models/video/sql/shared/abstract-videos-query-builder.ts
@@ -1,6 +1,12 @@
1import { QueryTypes, Sequelize, Transaction } from 'sequelize' 1import { QueryTypes, Sequelize, Transaction } from 'sequelize'
2import { logger } from '@server/helpers/logger' 2import { logger } from '@server/helpers/logger'
3 3
4/**
5 *
6 * Abstact builder to run video SQL queries
7 *
8 */
9
4export class AbstractVideosQueryBuilder { 10export class AbstractVideosQueryBuilder {
5 protected sequelize: Sequelize 11 protected sequelize: Sequelize
6 12
diff --git a/server/models/video/sql/shared/video-attributes.ts b/server/models/video/sql/shared/video-attributes.ts
index 1a1650dc7..e21b33c73 100644
--- a/server/models/video/sql/shared/video-attributes.ts
+++ b/server/models/video/sql/shared/video-attributes.ts
@@ -1,3 +1,9 @@
1
2/**
3 *
4 * Class to build video attributes we want to fetch from the database
5 *
6 */
1export class VideoAttributes { 7export class VideoAttributes {
2 8
3 constructor (readonly mode: 'get' | 'list') { 9 constructor (readonly mode: 'get' | 'list') {
diff --git a/server/models/video/sql/shared/video-file-query-builder.ts b/server/models/video/sql/shared/video-file-query-builder.ts
new file mode 100644
index 000000000..29b11a298
--- /dev/null
+++ b/server/models/video/sql/shared/video-file-query-builder.ts
@@ -0,0 +1,66 @@
1import { Sequelize } from 'sequelize'
2import { BuildVideoGetQueryOptions } from '../video-model-get-query-builder'
3import { AbstractVideosModelQueryBuilder } from './abstract-videos-model-query-builder'
4
5/**
6 *
7 * Fetch files (webtorrent and streaming playlist) according to a video
8 *
9 */
10
11export class VideoFileQueryBuilder extends AbstractVideosModelQueryBuilder {
12 protected attributes: { [key: string]: string }
13 protected joins: string[] = []
14
15 constructor (protected readonly sequelize: Sequelize) {
16 super('get')
17 }
18
19 queryWebTorrentVideos (options: BuildVideoGetQueryOptions) {
20 this.buildWebtorrentFilesQuery(options)
21
22 return this.runQuery(options.transaction, true)
23 }
24
25 queryStreamingPlaylistVideos (options: BuildVideoGetQueryOptions) {
26 this.buildVideoStreamingPlaylistFilesQuery(options)
27
28 return this.runQuery(options.transaction, true)
29 }
30
31 private buildWebtorrentFilesQuery (options: BuildVideoGetQueryOptions) {
32 this.attributes = {
33 '"video"."id"': ''
34 }
35
36 this.includeWebtorrentFiles(true)
37
38 if (options.forGetAPI === true) {
39 this.includeWebTorrentRedundancies()
40 }
41
42 this.whereId(options.id)
43
44 this.query = this.buildQuery()
45 }
46
47 private buildVideoStreamingPlaylistFilesQuery (options: BuildVideoGetQueryOptions) {
48 this.attributes = {
49 '"video"."id"': ''
50 }
51
52 this.includeStreamingPlaylistFiles(true)
53
54 if (options.forGetAPI === true) {
55 this.includeStreamingPlaylistRedundancies()
56 }
57
58 this.whereId(options.id)
59
60 this.query = this.buildQuery()
61 }
62
63 private buildQuery () {
64 return `${this.buildSelect()} FROM "video" ${this.joins.join(' ')} ${this.where}`
65 }
66}
diff --git a/server/models/video/sql/shared/video-model-builder.ts b/server/models/video/sql/shared/video-model-builder.ts
index 9719f6d2e..627ea6443 100644
--- a/server/models/video/sql/shared/video-model-builder.ts
+++ b/server/models/video/sql/shared/video-model-builder.ts
@@ -17,6 +17,12 @@ import { VideoLiveModel } from '../../video-live'
17import { VideoStreamingPlaylistModel } from '../../video-streaming-playlist' 17import { VideoStreamingPlaylistModel } from '../../video-streaming-playlist'
18import { VideoAttributes } from './video-attributes' 18import { VideoAttributes } from './video-attributes'
19 19
20/**
21 *
22 * Build video models from SQL rows
23 *
24 */
25
20export class VideoModelBuilder { 26export class VideoModelBuilder {
21 private videosMemo: { [ id: number ]: VideoModel } 27 private videosMemo: { [ id: number ]: VideoModel }
22 private videoStreamingPlaylistMemo: { [ id: number ]: VideoStreamingPlaylistModel } 28 private videoStreamingPlaylistMemo: { [ id: number ]: VideoStreamingPlaylistModel }
@@ -43,7 +49,7 @@ export class VideoModelBuilder {
43 49
44 } 50 }
45 51
46 buildVideosFromRows (rows: any[]) { 52 buildVideosFromRows (rows: any[], rowsWebtorrentFiles?: any[], rowsStreamingPlaylist?: any[]) {
47 this.reinit() 53 this.reinit()
48 54
49 for (const row of rows) { 55 for (const row of rows) {
@@ -53,10 +59,15 @@ export class VideoModelBuilder {
53 59
54 this.setUserHistory(row, videoModel) 60 this.setUserHistory(row, videoModel)
55 this.addThumbnail(row, videoModel) 61 this.addThumbnail(row, videoModel)
56 this.addWebTorrentFile(row, videoModel)
57 62
58 this.addStreamingPlaylist(row, videoModel) 63 if (!rowsWebtorrentFiles) {
59 this.addStreamingPlaylistFile(row) 64 this.addWebTorrentFile(row, videoModel)
65 }
66
67 if (!rowsStreamingPlaylist) {
68 this.addStreamingPlaylist(row, videoModel)
69 this.addStreamingPlaylistFile(row)
70 }
60 71
61 if (this.mode === 'get') { 72 if (this.mode === 'get') {
62 this.addTag(row, videoModel) 73 this.addTag(row, videoModel)
@@ -65,16 +76,30 @@ export class VideoModelBuilder {
65 this.setScheduleVideoUpdate(row, videoModel) 76 this.setScheduleVideoUpdate(row, videoModel)
66 this.setLive(row, videoModel) 77 this.setLive(row, videoModel)
67 78
68 if (row.VideoFiles.id) { 79 if (!rowsWebtorrentFiles && row.VideoFiles.id) {
69 this.addRedundancy(row.VideoFiles.RedundancyVideos, this.videoFileMemo[row.VideoFiles.id]) 80 this.addRedundancy(row.VideoFiles.RedundancyVideos, this.videoFileMemo[row.VideoFiles.id])
70 } 81 }
71 82
72 if (row.VideoStreamingPlaylists.id) { 83 if (!rowsStreamingPlaylist && row.VideoStreamingPlaylists.id) {
73 this.addRedundancy(row.VideoStreamingPlaylists.RedundancyVideos, this.videoStreamingPlaylistMemo[row.VideoStreamingPlaylists.id]) 84 this.addRedundancy(row.VideoStreamingPlaylists.RedundancyVideos, this.videoStreamingPlaylistMemo[row.VideoStreamingPlaylists.id])
74 } 85 }
75 } 86 }
76 } 87 }
77 88
89 for (const row of rowsWebtorrentFiles || []) {
90 const videoModel = this.videosMemo[row.id]
91 this.addWebTorrentFile(row, videoModel)
92 this.addRedundancy(row.VideoFiles.RedundancyVideos, this.videoFileMemo[row.VideoFiles.id])
93 }
94
95 for (const row of rowsStreamingPlaylist || []) {
96 const videoModel = this.videosMemo[row.id]
97
98 this.addStreamingPlaylist(row, videoModel)
99 this.addStreamingPlaylistFile(row)
100 this.addRedundancy(row.VideoStreamingPlaylists.RedundancyVideos, this.videoStreamingPlaylistMemo[row.VideoStreamingPlaylists.id])
101 }
102
78 return this.videos 103 return this.videos
79 } 104 }
80 105
diff --git a/server/models/video/sql/video-model-get-query-builder.ts b/server/models/video/sql/video-model-get-query-builder.ts
index 0a3723e63..1a921d802 100644
--- a/server/models/video/sql/video-model-get-query-builder.ts
+++ b/server/models/video/sql/video-model-get-query-builder.ts
@@ -1,6 +1,14 @@
1import { Sequelize, Transaction } from 'sequelize' 1import { Sequelize, Transaction } from 'sequelize'
2import validator from 'validator'
3import { AbstractVideosModelQueryBuilder } from './shared/abstract-videos-model-query-builder' 2import { AbstractVideosModelQueryBuilder } from './shared/abstract-videos-model-query-builder'
3import { VideoAttributes } from './shared/video-attributes'
4import { VideoFileQueryBuilder } from './shared/video-file-query-builder'
5import { VideoModelBuilder } from './shared/video-model-builder'
6
7/**
8 *
9 * Build a GET SQL query, fetch rows and create the video model
10 *
11 */
4 12
5export type BuildVideoGetQueryOptions = { 13export type BuildVideoGetQueryOptions = {
6 id: number | string 14 id: number | string
@@ -9,31 +17,57 @@ export type BuildVideoGetQueryOptions = {
9 forGetAPI?: boolean 17 forGetAPI?: boolean
10} 18}
11 19
12export class VideosModelGetQueryBuilder extends AbstractVideosModelQueryBuilder { 20export class VideosModelGetQueryBuilder {
21 videoQueryBuilder: VideosModelGetQuerySubBuilder
22 webtorrentFilesQueryBuilder: VideoFileQueryBuilder
23 streamingPlaylistFilesQueryBuilder: VideoFileQueryBuilder
24
25 private readonly videoModelBuilder: VideoModelBuilder
26
27 constructor (protected readonly sequelize: Sequelize) {
28 this.videoQueryBuilder = new VideosModelGetQuerySubBuilder(sequelize)
29 this.webtorrentFilesQueryBuilder = new VideoFileQueryBuilder(sequelize)
30 this.streamingPlaylistFilesQueryBuilder = new VideoFileQueryBuilder(sequelize)
31
32 this.videoModelBuilder = new VideoModelBuilder('get', new VideoAttributes('get'))
33 }
34
35 async queryVideos (options: BuildVideoGetQueryOptions) {
36 const [ videoRows, webtorrentFilesRows, streamingPlaylistFilesRows ] = await Promise.all([
37 this.videoQueryBuilder.queryVideos(options),
38 this.webtorrentFilesQueryBuilder.queryWebTorrentVideos(options),
39 this.streamingPlaylistFilesQueryBuilder.queryStreamingPlaylistVideos(options)
40 ])
41
42 const videos = this.videoModelBuilder.buildVideosFromRows(videoRows, webtorrentFilesRows, streamingPlaylistFilesRows)
43
44 if (videos.length > 1) {
45 throw new Error('Video results is more than ')
46 }
47
48 if (videos.length === 0) return null
49 return videos[0]
50 }
51}
52
53export class VideosModelGetQuerySubBuilder extends AbstractVideosModelQueryBuilder {
13 protected attributes: { [key: string]: string } 54 protected attributes: { [key: string]: string }
14 protected joins: string[] = [] 55 protected joins: string[] = []
15 protected where: string 56
57 protected webtorrentFilesQuery: string
58 protected streamingPlaylistFilesQuery: string
16 59
17 constructor (protected readonly sequelize: Sequelize) { 60 constructor (protected readonly sequelize: Sequelize) {
18 super('get') 61 super('get')
19 } 62 }
20 63
21 queryVideos (options: BuildVideoGetQueryOptions) { 64 queryVideos (options: BuildVideoGetQueryOptions) {
22 this.buildGetQuery(options) 65 this.buildMainGetQuery(options)
23
24 return this.runQuery(options.transaction, true).then(rows => {
25 const videos = this.videoModelBuilder.buildVideosFromRows(rows)
26
27 if (videos.length > 1) {
28 throw new Error('Video results is more than ')
29 }
30 66
31 if (videos.length === 0) return null 67 return this.runQuery(options.transaction, true)
32 return videos[0]
33 })
34 } 68 }
35 69
36 private buildGetQuery (options: BuildVideoGetQueryOptions) { 70 private buildMainGetQuery (options: BuildVideoGetQueryOptions) {
37 this.attributes = { 71 this.attributes = {
38 '"video".*': '' 72 '"video".*': ''
39 } 73 }
@@ -45,8 +79,6 @@ export class VideosModelGetQueryBuilder extends AbstractVideosModelQueryBuilder
45 79
46 this.includeThumbnails() 80 this.includeThumbnails()
47 81
48 this.includeFiles()
49
50 this.includeBlacklisted() 82 this.includeBlacklisted()
51 83
52 this.includeScheduleUpdate() 84 this.includeScheduleUpdate()
@@ -59,28 +91,17 @@ export class VideosModelGetQueryBuilder extends AbstractVideosModelQueryBuilder
59 91
60 if (options.forGetAPI === true) { 92 if (options.forGetAPI === true) {
61 this.includeTrackers() 93 this.includeTrackers()
62 this.includeRedundancies()
63 } 94 }
64 95
65 this.whereId(options.id) 96 this.whereId(options.id)
66 97
67 const select = this.buildSelect() 98 this.query = this.buildQuery()
68 const order = this.buildOrder()
69
70 this.query = `${select} FROM "video" ${this.joins.join(' ')} ${this.where} ${order}`
71 } 99 }
72 100
73 private whereId (id: string | number) { 101 private buildQuery () {
74 if (validator.isInt('' + id)) { 102 const order = 'ORDER BY "Tags"."name" ASC'
75 this.where = 'WHERE "video".id = :videoId' 103 const from = `SELECT * FROM "video" ${this.where} LIMIT 1`
76 } else {
77 this.where = 'WHERE uuid = :videoId'
78 }
79
80 this.replacements.videoId = id
81 }
82 104
83 private buildOrder () { 105 return `${this.buildSelect()} FROM (${from}) AS "video" ${this.joins.join(' ')} ${this.where} ${order}`
84 return 'ORDER BY "Tags"."name" ASC'
85 } 106 }
86} 107}
diff --git a/server/models/video/sql/videos-id-list-query-builder.ts b/server/models/video/sql/videos-id-list-query-builder.ts
index 6e0d97d9e..30b251f0f 100644
--- a/server/models/video/sql/videos-id-list-query-builder.ts
+++ b/server/models/video/sql/videos-id-list-query-builder.ts
@@ -6,6 +6,12 @@ import { MUserAccountId, MUserId } from '@server/types/models'
6import { VideoFilter, VideoPrivacy, VideoState } from '@shared/models' 6import { VideoFilter, VideoPrivacy, VideoState } from '@shared/models'
7import { AbstractVideosQueryBuilder } from './shared/abstract-videos-query-builder' 7import { AbstractVideosQueryBuilder } from './shared/abstract-videos-query-builder'
8 8
9/**
10 *
11 * Build videos list SQL query to fetch rows
12 *
13 */
14
9export type BuildVideosListQueryOptions = { 15export type BuildVideosListQueryOptions = {
10 attributes?: string[] 16 attributes?: string[]
11 17
diff --git a/server/models/video/sql/videos-model-list-query-builder.ts b/server/models/video/sql/videos-model-list-query-builder.ts
index 38b9c91d0..acb76d80a 100644
--- a/server/models/video/sql/videos-model-list-query-builder.ts
+++ b/server/models/video/sql/videos-model-list-query-builder.ts
@@ -1,7 +1,14 @@
1import { Sequelize } from 'sequelize' 1import { Sequelize } from 'sequelize'
2import { AbstractVideosModelQueryBuilder } from './shared/abstract-videos-model-query-builder' 2import { AbstractVideosModelQueryBuilder } from './shared/abstract-videos-model-query-builder'
3import { VideoModelBuilder } from './shared/video-model-builder'
3import { BuildVideosListQueryOptions, VideosIdListQueryBuilder } from './videos-id-list-query-builder' 4import { BuildVideosListQueryOptions, VideosIdListQueryBuilder } from './videos-id-list-query-builder'
4 5
6/**
7 *
8 * Build videos list SQL query and create video models
9 *
10 */
11
5export class VideosModelListQueryBuilder extends AbstractVideosModelQueryBuilder { 12export class VideosModelListQueryBuilder extends AbstractVideosModelQueryBuilder {
6 protected attributes: { [key: string]: string } 13 protected attributes: { [key: string]: string }
7 protected joins: string[] = [] 14 protected joins: string[] = []
@@ -9,8 +16,12 @@ export class VideosModelListQueryBuilder extends AbstractVideosModelQueryBuilder
9 private innerQuery: string 16 private innerQuery: string
10 private innerSort: string 17 private innerSort: string
11 18
19 private readonly videoModelBuilder: VideoModelBuilder
20
12 constructor (protected readonly sequelize: Sequelize) { 21 constructor (protected readonly sequelize: Sequelize) {
13 super('list') 22 super('list')
23
24 this.videoModelBuilder = new VideoModelBuilder(this.mode, this.videoAttributes)
14 } 25 }
15 26
16 queryVideos (options: BuildVideosListQueryOptions) { 27 queryVideos (options: BuildVideosListQueryOptions) {
@@ -41,7 +52,8 @@ export class VideosModelListQueryBuilder extends AbstractVideosModelQueryBuilder
41 this.includeThumbnails() 52 this.includeThumbnails()
42 53
43 if (options.withFiles) { 54 if (options.withFiles) {
44 this.includeFiles() 55 this.includeWebtorrentFiles(false)
56 this.includeStreamingPlaylistFiles(false)
45 } 57 }
46 58
47 if (options.user) { 59 if (options.user) {