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'
11 * Build videos list SQL query and create video models
15 export class VideosModelListQueryBuilder extends AbstractVideoQueryBuilder {
16 protected attributes: { [key: string]: string }
18 private innerQuery: string
19 private innerSort: string
21 webtorrentFilesQueryBuilder: VideoFileQueryBuilder
22 streamingPlaylistFilesQueryBuilder: VideoFileQueryBuilder
24 private readonly videoModelBuilder: VideoModelBuilder
26 constructor (protected readonly sequelize: Sequelize) {
27 super(sequelize, 'list')
29 this.videoModelBuilder = new VideoModelBuilder(this.mode, this.tables)
30 this.webtorrentFilesQueryBuilder = new VideoFileQueryBuilder(sequelize)
31 this.streamingPlaylistFilesQueryBuilder = new VideoFileQueryBuilder(sequelize)
34 async queryVideos (options: BuildVideosListQueryOptions) {
35 this.buildInnerQuery(options)
36 this.buildMainQuery(options)
38 const rows = await this.runQuery()
40 if (options.include & VideoInclude.FILES) {
41 const videoIds = Array.from(new Set(rows.map(r => r.id)))
43 if (videoIds.length !== 0) {
44 const fileQueryOptions = {
45 ...pick(options, [ 'transaction', 'logging' ]),
48 includeRedundancy: false
51 const [ rowsWebTorrentFiles, rowsStreamingPlaylist ] = await Promise.all([
52 this.webtorrentFilesQueryBuilder.queryWebTorrentVideos(fileQueryOptions),
53 this.streamingPlaylistFilesQueryBuilder.queryStreamingPlaylistVideos(fileQueryOptions)
56 return this.videoModelBuilder.buildVideosFromRows({ rows, include: options.include, rowsStreamingPlaylist, rowsWebTorrentFiles })
60 return this.videoModelBuilder.buildVideosFromRows({ rows, include: options.include })
63 private buildInnerQuery (options: BuildVideosListQueryOptions) {
64 const idsQueryBuilder = new VideosIdListQueryBuilder(this.sequelize)
65 const { query, sort, replacements } = idsQueryBuilder.getQuery(options)
67 this.replacements = replacements
68 this.innerQuery = query
72 private buildMainQuery (options: BuildVideosListQueryOptions) {
77 this.addJoin('INNER JOIN "video" ON "tmp"."id" = "video"."id"')
79 this.includeChannels()
80 this.includeAccounts()
81 this.includeThumbnails()
84 this.includeUserHistory(options.user.id)
87 if (options.videoPlaylistId) {
88 this.includePlaylist(options.videoPlaylistId)
91 if (options.include & VideoInclude.BLACKLISTED) {
92 this.includeBlacklisted()
95 if (options.include & VideoInclude.BLOCKED_OWNER) {
96 this.includeBlockedOwnerAndServer(options.serverAccountIdForBlock, options.user)
99 const select = this.buildSelect()
101 this.query = `${select} FROM (${this.innerQuery}) AS "tmp" ${this.joins} ${this.innerSort}`