]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/models/video/sql/video/videos-model-list-query-builder.ts
Feature/Add replay privacy (#5692)
[github/Chocobozzz/PeerTube.git] / server / models / video / sql / video / videos-model-list-query-builder.ts
1 import { Sequelize } from 'sequelize'
2 import { pick } from '@shared/core-utils'
3 import { VideoInclude } from '@shared/models'
4 import { AbstractVideoQueryBuilder } from './shared/abstract-video-query-builder'
5 import { VideoFileQueryBuilder } from './shared/video-file-query-builder'
6 import { VideoModelBuilder } from './shared/video-model-builder'
7 import { BuildVideosListQueryOptions, VideosIdListQueryBuilder } from './videos-id-list-query-builder'
8
9 /**
10 *
11 * Build videos list SQL query and create video models
12 *
13 */
14
15 export class VideosModelListQueryBuilder extends AbstractVideoQueryBuilder {
16 protected attributes: { [key: string]: string }
17
18 private innerQuery: string
19 private innerSort: string
20
21 webtorrentFilesQueryBuilder: VideoFileQueryBuilder
22 streamingPlaylistFilesQueryBuilder: VideoFileQueryBuilder
23
24 private readonly videoModelBuilder: VideoModelBuilder
25
26 constructor (protected readonly sequelize: Sequelize) {
27 super(sequelize, 'list')
28
29 this.videoModelBuilder = new VideoModelBuilder(this.mode, this.tables)
30 this.webtorrentFilesQueryBuilder = new VideoFileQueryBuilder(sequelize)
31 this.streamingPlaylistFilesQueryBuilder = new VideoFileQueryBuilder(sequelize)
32 }
33
34 async queryVideos (options: BuildVideosListQueryOptions) {
35 this.buildInnerQuery(options)
36 this.buildMainQuery(options)
37
38 const rows = await this.runQuery()
39
40 if (options.include & VideoInclude.FILES) {
41 const videoIds = Array.from(new Set(rows.map(r => r.id)))
42
43 if (videoIds.length !== 0) {
44 const fileQueryOptions = {
45 ...pick(options, [ 'transaction', 'logging' ]),
46
47 ids: videoIds,
48 includeRedundancy: false
49 }
50
51 const [ rowsWebTorrentFiles, rowsStreamingPlaylist ] = await Promise.all([
52 this.webtorrentFilesQueryBuilder.queryWebTorrentVideos(fileQueryOptions),
53 this.streamingPlaylistFilesQueryBuilder.queryStreamingPlaylistVideos(fileQueryOptions)
54 ])
55
56 return this.videoModelBuilder.buildVideosFromRows({ rows, include: options.include, rowsStreamingPlaylist, rowsWebTorrentFiles })
57 }
58 }
59
60 return this.videoModelBuilder.buildVideosFromRows({ rows, include: options.include })
61 }
62
63 private buildInnerQuery (options: BuildVideosListQueryOptions) {
64 const idsQueryBuilder = new VideosIdListQueryBuilder(this.sequelize)
65 const { query, sort, replacements } = idsQueryBuilder.getQuery(options)
66
67 this.replacements = replacements
68 this.innerQuery = query
69 this.innerSort = sort
70 }
71
72 private buildMainQuery (options: BuildVideosListQueryOptions) {
73 this.attributes = {
74 '"video".*': ''
75 }
76
77 this.addJoin('INNER JOIN "video" ON "tmp"."id" = "video"."id"')
78
79 this.includeChannels()
80 this.includeAccounts()
81 this.includeThumbnails()
82
83 if (options.user) {
84 this.includeUserHistory(options.user.id)
85 }
86
87 if (options.videoPlaylistId) {
88 this.includePlaylist(options.videoPlaylistId)
89 }
90
91 if (options.include & VideoInclude.BLACKLISTED) {
92 this.includeBlacklisted()
93 }
94
95 if (options.include & VideoInclude.BLOCKED_OWNER) {
96 this.includeBlockedOwnerAndServer(options.serverAccountIdForBlock, options.user)
97 }
98
99 const select = this.buildSelect()
100
101 this.query = `${select} FROM (${this.innerQuery}) AS "tmp" ${this.joins} ${this.innerSort}`
102 }
103 }