1 import { Sequelize, Transaction } from 'sequelize'
2 import { AbstractVideosModelQueryBuilder } from './shared/abstract-videos-model-query-builder'
3 import { VideoFileQueryBuilder } from './shared/video-file-query-builder'
4 import { VideoModelBuilder } from './shared/video-model-builder'
5 import { VideoTables } from './shared/video-tables'
9 * Build a GET SQL query, fetch rows and create the video model
16 'account-blacklist-files' |
19 'thumbnails-blacklist' |
23 export type BuildVideoGetQueryOptions = {
30 transaction?: Transaction
35 export class VideosModelGetQueryBuilder {
36 videoQueryBuilder: VideosModelGetQuerySubBuilder
37 webtorrentFilesQueryBuilder: VideoFileQueryBuilder
38 streamingPlaylistFilesQueryBuilder: VideoFileQueryBuilder
40 private readonly videoModelBuilder: VideoModelBuilder
42 private static readonly videoFilesInclude = new Set<GetType>([ 'api', 'full-light', 'account-blacklist-files', 'all-files' ])
44 constructor (protected readonly sequelize: Sequelize) {
45 this.videoQueryBuilder = new VideosModelGetQuerySubBuilder(sequelize)
46 this.webtorrentFilesQueryBuilder = new VideoFileQueryBuilder(sequelize)
47 this.streamingPlaylistFilesQueryBuilder = new VideoFileQueryBuilder(sequelize)
49 this.videoModelBuilder = new VideoModelBuilder('get', new VideoTables('get'))
52 async queryVideo (options: BuildVideoGetQueryOptions) {
53 const [ videoRows, webtorrentFilesRows, streamingPlaylistFilesRows ] = await Promise.all([
54 this.videoQueryBuilder.queryVideos(options),
56 VideosModelGetQueryBuilder.videoFilesInclude.has(options.type)
57 ? this.webtorrentFilesQueryBuilder.queryWebTorrentVideos(options)
58 : Promise.resolve(undefined),
60 VideosModelGetQueryBuilder.videoFilesInclude.has(options.type)
61 ? this.streamingPlaylistFilesQueryBuilder.queryStreamingPlaylistVideos(options)
62 : Promise.resolve(undefined)
65 const videos = this.videoModelBuilder.buildVideosFromRows(videoRows, webtorrentFilesRows, streamingPlaylistFilesRows)
67 if (videos.length > 1) {
68 throw new Error('Video results is more than ')
71 if (videos.length === 0) return null
76 export class VideosModelGetQuerySubBuilder extends AbstractVideosModelQueryBuilder {
77 protected attributes: { [key: string]: string }
79 protected webtorrentFilesQuery: string
80 protected streamingPlaylistFilesQuery: string
82 private static readonly trackersInclude = new Set<GetType>([ 'api' ])
83 private static readonly liveInclude = new Set<GetType>([ 'api', 'full-light' ])
84 private static readonly scheduleUpdateInclude = new Set<GetType>([ 'api', 'full-light' ])
85 private static readonly tagsInclude = new Set<GetType>([ 'api', 'full-light' ])
86 private static readonly userHistoryInclude = new Set<GetType>([ 'api', 'full-light' ])
87 private static readonly accountInclude = new Set<GetType>([ 'api', 'full-light', 'account-blacklist-files' ])
88 private static readonly ownerUserInclude = new Set<GetType>([ 'blacklist-rights' ])
90 private static readonly blacklistedInclude = new Set<GetType>([
93 'account-blacklist-files',
94 'thumbnails-blacklist',
98 private static readonly thumbnailsInclude = new Set<GetType>([
101 'account-blacklist-files',
103 'thumbnails-blacklist'
106 constructor (protected readonly sequelize: Sequelize) {
110 queryVideos (options: BuildVideoGetQueryOptions) {
111 this.buildMainGetQuery(options)
113 return this.runQuery(options)
116 private buildMainGetQuery (options: BuildVideoGetQueryOptions) {
121 if (VideosModelGetQuerySubBuilder.thumbnailsInclude.has(options.type)) {
122 this.includeThumbnails()
125 if (VideosModelGetQuerySubBuilder.blacklistedInclude.has(options.type)) {
126 this.includeBlacklisted()
129 if (VideosModelGetQuerySubBuilder.accountInclude.has(options.type)) {
130 this.includeChannels()
131 this.includeAccounts()
134 if (VideosModelGetQuerySubBuilder.tagsInclude.has(options.type)) {
138 if (VideosModelGetQuerySubBuilder.scheduleUpdateInclude.has(options.type)) {
139 this.includeScheduleUpdate()
142 if (VideosModelGetQuerySubBuilder.liveInclude.has(options.type)) {
146 if (options.userId && VideosModelGetQuerySubBuilder.userHistoryInclude.has(options.type)) {
147 this.includeUserHistory(options.userId)
150 if (VideosModelGetQuerySubBuilder.ownerUserInclude.has(options.type)) {
151 this.includeOwnerUser()
154 if (VideosModelGetQuerySubBuilder.trackersInclude.has(options.type)) {
155 this.includeTrackers()
158 this.whereId(options)
160 this.query = this.buildQuery(options)
163 private buildQuery (options: BuildVideoGetQueryOptions) {
164 const order = VideosModelGetQuerySubBuilder.tagsInclude.has(options.type)
165 ? 'ORDER BY "Tags"."name" ASC'
168 const from = `SELECT * FROM "video" ${this.where} LIMIT 1`
170 return `${this.buildSelect()} FROM (${from}) AS "video" ${this.joins} ${order}`