1
0
Fork 0
peertube/server/models/video/sql/video/video-model-get-query-build...

190 lines
5.7 KiB
TypeScript
Raw Normal View History

2021-06-10 12:43:55 +00:00
import { Sequelize, Transaction } from 'sequelize'
2022-08-17 12:52:23 +00:00
import { pick } from '@shared/core-utils'
2021-11-02 10:00:40 +00:00
import { AbstractVideoQueryBuilder } from './shared/abstract-video-query-builder'
2021-06-10 14:57:13 +00:00
import { VideoFileQueryBuilder } from './shared/video-file-query-builder'
import { VideoModelBuilder } from './shared/video-model-builder'
2021-11-02 10:00:40 +00:00
import { VideoTableAttributes } from './shared/video-table-attributes'
2021-06-10 14:57:13 +00:00
/**
*
* Build a GET SQL query, fetch rows and create the video model
*
*/
2021-06-10 12:43:55 +00:00
2021-06-11 12:26:37 +00:00
export type GetType =
'api' |
2022-06-28 12:57:51 +00:00
'full' |
2021-06-11 12:26:37 +00:00
'account-blacklist-files' |
'all-files' |
'thumbnails' |
'thumbnails-blacklist' |
'id' |
'blacklist-rights'
2021-06-10 12:43:55 +00:00
export type BuildVideoGetQueryOptions = {
2021-06-11 12:09:33 +00:00
id?: number | string
url?: string
2021-06-11 12:26:37 +00:00
type: GetType
2021-06-11 12:09:33 +00:00
2021-06-10 12:43:55 +00:00
userId?: number
2021-06-11 12:09:33 +00:00
transaction?: Transaction
logging?: boolean
2021-06-10 12:43:55 +00:00
}
export class VideoModelGetQueryBuilder {
2021-06-10 14:57:13 +00:00
videoQueryBuilder: VideosModelGetQuerySubBuilder
webVideoFilesQueryBuilder: VideoFileQueryBuilder
2021-06-10 14:57:13 +00:00
streamingPlaylistFilesQueryBuilder: VideoFileQueryBuilder
private readonly videoModelBuilder: VideoModelBuilder
2022-06-28 12:57:51 +00:00
private static readonly videoFilesInclude = new Set<GetType>([ 'api', 'full', 'account-blacklist-files', 'all-files' ])
2021-06-11 12:26:37 +00:00
2021-06-10 14:57:13 +00:00
constructor (protected readonly sequelize: Sequelize) {
this.videoQueryBuilder = new VideosModelGetQuerySubBuilder(sequelize)
this.webVideoFilesQueryBuilder = new VideoFileQueryBuilder(sequelize)
2021-06-10 14:57:13 +00:00
this.streamingPlaylistFilesQueryBuilder = new VideoFileQueryBuilder(sequelize)
2021-11-02 10:00:40 +00:00
this.videoModelBuilder = new VideoModelBuilder('get', new VideoTableAttributes('get'))
2021-06-10 14:57:13 +00:00
}
2021-06-11 12:09:33 +00:00
async queryVideo (options: BuildVideoGetQueryOptions) {
2022-06-27 07:34:26 +00:00
const fileQueryOptions = {
...pick(options, [ 'id', 'url', 'transaction', 'logging' ]),
includeRedundancy: this.shouldIncludeRedundancies(options)
}
const [ videoRows, webVideoFilesRows, streamingPlaylistFilesRows ] = await Promise.all([
2021-06-10 14:57:13 +00:00
this.videoQueryBuilder.queryVideos(options),
2021-06-11 12:09:33 +00:00
VideoModelGetQueryBuilder.videoFilesInclude.has(options.type)
? this.webVideoFilesQueryBuilder.queryWebVideos(fileQueryOptions)
2021-06-11 12:09:33 +00:00
: Promise.resolve(undefined),
VideoModelGetQueryBuilder.videoFilesInclude.has(options.type)
2022-06-27 07:34:26 +00:00
? this.streamingPlaylistFilesQueryBuilder.queryStreamingPlaylistVideos(fileQueryOptions)
2021-06-11 12:09:33 +00:00
: Promise.resolve(undefined)
2021-06-10 14:57:13 +00:00
])
const videos = this.videoModelBuilder.buildVideosFromRows({
rows: videoRows,
rowsWebVideoFiles: webVideoFilesRows,
rowsStreamingPlaylist: streamingPlaylistFilesRows
})
2021-06-10 14:57:13 +00:00
if (videos.length > 1) {
2021-11-02 10:00:40 +00:00
throw new Error('Video results is more than 1')
2021-06-10 14:57:13 +00:00
}
if (videos.length === 0) return null
2021-11-02 10:00:40 +00:00
2021-06-10 14:57:13 +00:00
return videos[0]
}
2022-06-27 07:34:26 +00:00
private shouldIncludeRedundancies (options: BuildVideoGetQueryOptions) {
return options.type === 'api'
}
2021-06-10 14:57:13 +00:00
}
2021-11-02 10:00:40 +00:00
export class VideosModelGetQuerySubBuilder extends AbstractVideoQueryBuilder {
2021-06-10 12:43:55 +00:00
protected attributes: { [key: string]: string }
2021-06-10 14:57:13 +00:00
protected webVideoFilesQuery: string
2021-06-10 14:57:13 +00:00
protected streamingPlaylistFilesQuery: string
2021-06-10 12:43:55 +00:00
2021-06-11 12:26:37 +00:00
private static readonly trackersInclude = new Set<GetType>([ 'api' ])
2022-06-28 12:57:51 +00:00
private static readonly liveInclude = new Set<GetType>([ 'api', 'full' ])
private static readonly scheduleUpdateInclude = new Set<GetType>([ 'api', 'full' ])
private static readonly tagsInclude = new Set<GetType>([ 'api', 'full' ])
private static readonly userHistoryInclude = new Set<GetType>([ 'api', 'full' ])
private static readonly accountInclude = new Set<GetType>([ 'api', 'full', 'account-blacklist-files' ])
2021-06-11 12:26:37 +00:00
private static readonly ownerUserInclude = new Set<GetType>([ 'blacklist-rights' ])
private static readonly blacklistedInclude = new Set<GetType>([
'api',
2022-06-28 12:57:51 +00:00
'full',
2021-06-11 12:26:37 +00:00
'account-blacklist-files',
'thumbnails-blacklist',
'blacklist-rights'
])
private static readonly thumbnailsInclude = new Set<GetType>([
'api',
2022-06-28 12:57:51 +00:00
'full',
2021-06-11 12:26:37 +00:00
'account-blacklist-files',
2021-06-11 14:05:32 +00:00
'all-files',
2021-06-11 12:26:37 +00:00
'thumbnails',
'thumbnails-blacklist'
])
2021-06-10 12:43:55 +00:00
constructor (protected readonly sequelize: Sequelize) {
2022-03-03 09:23:44 +00:00
super(sequelize, 'get')
2021-06-10 12:43:55 +00:00
}
queryVideos (options: BuildVideoGetQueryOptions) {
2021-06-10 14:57:13 +00:00
this.buildMainGetQuery(options)
2021-06-10 12:43:55 +00:00
2021-06-11 12:09:33 +00:00
return this.runQuery(options)
2021-06-10 12:43:55 +00:00
}
2021-06-10 14:57:13 +00:00
private buildMainGetQuery (options: BuildVideoGetQueryOptions) {
2021-06-10 12:43:55 +00:00
this.attributes = {
'"video".*': ''
}
2021-06-11 12:26:37 +00:00
if (VideosModelGetQuerySubBuilder.thumbnailsInclude.has(options.type)) {
2021-06-11 12:09:33 +00:00
this.includeThumbnails()
}
2021-06-10 12:43:55 +00:00
2021-06-11 12:26:37 +00:00
if (VideosModelGetQuerySubBuilder.blacklistedInclude.has(options.type)) {
2021-06-11 12:09:33 +00:00
this.includeBlacklisted()
}
2021-06-10 12:43:55 +00:00
2021-06-11 12:26:37 +00:00
if (VideosModelGetQuerySubBuilder.accountInclude.has(options.type)) {
2021-06-11 12:09:33 +00:00
this.includeChannels()
this.includeAccounts()
}
2021-06-10 12:43:55 +00:00
2021-06-11 12:26:37 +00:00
if (VideosModelGetQuerySubBuilder.tagsInclude.has(options.type)) {
2021-06-11 12:09:33 +00:00
this.includeTags()
}
2021-06-10 12:43:55 +00:00
2021-06-11 12:26:37 +00:00
if (VideosModelGetQuerySubBuilder.scheduleUpdateInclude.has(options.type)) {
2021-06-11 12:09:33 +00:00
this.includeScheduleUpdate()
}
2021-06-10 12:43:55 +00:00
2021-06-11 12:26:37 +00:00
if (VideosModelGetQuerySubBuilder.liveInclude.has(options.type)) {
2021-06-11 12:09:33 +00:00
this.includeLive()
}
2021-06-10 12:43:55 +00:00
2021-06-11 12:26:37 +00:00
if (options.userId && VideosModelGetQuerySubBuilder.userHistoryInclude.has(options.type)) {
2021-06-10 12:43:55 +00:00
this.includeUserHistory(options.userId)
}
2021-06-11 12:26:37 +00:00
if (VideosModelGetQuerySubBuilder.ownerUserInclude.has(options.type)) {
2021-06-11 12:09:33 +00:00
this.includeOwnerUser()
}
2021-06-11 12:26:37 +00:00
if (VideosModelGetQuerySubBuilder.trackersInclude.has(options.type)) {
2021-06-10 12:43:55 +00:00
this.includeTrackers()
}
2021-06-11 12:09:33 +00:00
this.whereId(options)
2021-06-10 12:43:55 +00:00
2021-06-11 12:09:33 +00:00
this.query = this.buildQuery(options)
2021-06-10 12:43:55 +00:00
}
2021-06-11 12:09:33 +00:00
private buildQuery (options: BuildVideoGetQueryOptions) {
2021-06-11 12:26:37 +00:00
const order = VideosModelGetQuerySubBuilder.tagsInclude.has(options.type)
2021-06-11 12:09:33 +00:00
? 'ORDER BY "Tags"."name" ASC'
: ''
2021-06-10 14:57:13 +00:00
const from = `SELECT * FROM "video" ${this.where} LIMIT 1`
2021-06-10 12:43:55 +00:00
2021-06-11 09:27:45 +00:00
return `${this.buildSelect()} FROM (${from}) AS "video" ${this.joins} ${order}`
2021-06-10 12:43:55 +00:00
}
}