PeerTube/server/models/video/sql/video-model-get-query-build...

177 lines
5.3 KiB
TypeScript
Raw Normal View History

2021-06-10 12:43:55 +00:00
import { Sequelize, Transaction } from 'sequelize'
import { AbstractVideosModelQueryBuilder } from './shared/abstract-videos-model-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-06-11 08:59:27 +00:00
import { VideoTables } from './shared/video-tables'
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
export type BuildVideoGetQueryOptions = {
2021-06-11 12:09:33 +00:00
id?: number | string
url?: string
type: 'api' | 'full-light' | 'account-blacklist-files' | 'all-files' | 'thumbnails' | 'thumbnails-blacklist' | 'id' | 'blacklist-rights'
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
}
2021-06-10 14:57:13 +00:00
export class VideosModelGetQueryBuilder {
videoQueryBuilder: VideosModelGetQuerySubBuilder
webtorrentFilesQueryBuilder: VideoFileQueryBuilder
streamingPlaylistFilesQueryBuilder: VideoFileQueryBuilder
private readonly videoModelBuilder: VideoModelBuilder
constructor (protected readonly sequelize: Sequelize) {
this.videoQueryBuilder = new VideosModelGetQuerySubBuilder(sequelize)
this.webtorrentFilesQueryBuilder = new VideoFileQueryBuilder(sequelize)
this.streamingPlaylistFilesQueryBuilder = new VideoFileQueryBuilder(sequelize)
2021-06-11 08:59:27 +00:00
this.videoModelBuilder = new VideoModelBuilder('get', new VideoTables('get'))
2021-06-10 14:57:13 +00:00
}
2021-06-11 12:09:33 +00:00
async queryVideo (options: BuildVideoGetQueryOptions) {
2021-06-10 14:57:13 +00:00
const [ videoRows, webtorrentFilesRows, streamingPlaylistFilesRows ] = await Promise.all([
this.videoQueryBuilder.queryVideos(options),
2021-06-11 12:09:33 +00:00
this.shouldQueryVideoFiles(options)
? this.webtorrentFilesQueryBuilder.queryWebTorrentVideos(options)
: Promise.resolve(undefined),
this.shouldQueryVideoFiles(options)
? this.streamingPlaylistFilesQueryBuilder.queryStreamingPlaylistVideos(options)
: Promise.resolve(undefined)
2021-06-10 14:57:13 +00:00
])
const videos = this.videoModelBuilder.buildVideosFromRows(videoRows, webtorrentFilesRows, streamingPlaylistFilesRows)
if (videos.length > 1) {
throw new Error('Video results is more than ')
}
if (videos.length === 0) return null
return videos[0]
}
2021-06-11 12:09:33 +00:00
private shouldQueryVideoFiles (options: BuildVideoGetQueryOptions) {
return [ 'api', 'full-light', 'account-blacklist-files', 'all-files' ].includes(options.type)
}
2021-06-10 14:57:13 +00:00
}
export class VideosModelGetQuerySubBuilder extends AbstractVideosModelQueryBuilder {
2021-06-10 12:43:55 +00:00
protected attributes: { [key: string]: string }
2021-06-10 14:57:13 +00:00
protected webtorrentFilesQuery: string
protected streamingPlaylistFilesQuery: string
2021-06-10 12:43:55 +00:00
constructor (protected readonly sequelize: Sequelize) {
super('get')
}
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:09:33 +00:00
if (this.shouldIncludeThumbnails(options)) {
this.includeThumbnails()
}
2021-06-10 12:43:55 +00:00
2021-06-11 12:09:33 +00:00
if (this.shouldIncludeBlacklisted(options)) {
this.includeBlacklisted()
}
2021-06-10 12:43:55 +00:00
2021-06-11 12:09:33 +00:00
if (this.shouldIncludeAccount(options)) {
this.includeChannels()
this.includeAccounts()
}
2021-06-10 12:43:55 +00:00
2021-06-11 12:09:33 +00:00
if (this.shouldIncludeTags(options)) {
this.includeTags()
}
2021-06-10 12:43:55 +00:00
2021-06-11 12:09:33 +00:00
if (this.shouldIncludeScheduleUpdate(options)) {
this.includeScheduleUpdate()
}
2021-06-10 12:43:55 +00:00
2021-06-11 12:09:33 +00:00
if (this.shouldIncludeLive(options)) {
this.includeLive()
}
2021-06-10 12:43:55 +00:00
2021-06-11 12:09:33 +00:00
if (options.userId && this.shouldIncludeUserHistory(options)) {
2021-06-10 12:43:55 +00:00
this.includeUserHistory(options.userId)
}
2021-06-11 12:09:33 +00:00
if (this.shouldIncludeOwnerUser(options)) {
this.includeOwnerUser()
}
if (this.shouldIncludeTrackers(options)) {
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) {
const order = this.shouldIncludeTags(options)
? '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
}
2021-06-11 12:09:33 +00:00
private shouldIncludeTrackers (options: BuildVideoGetQueryOptions) {
return options.type === 'api'
}
private shouldIncludeLive (options: BuildVideoGetQueryOptions) {
return [ 'api', 'full-light' ].includes(options.type)
}
private shouldIncludeScheduleUpdate (options: BuildVideoGetQueryOptions) {
return [ 'api', 'full-light' ].includes(options.type)
}
private shouldIncludeTags (options: BuildVideoGetQueryOptions) {
return [ 'api', 'full-light' ].includes(options.type)
}
private shouldIncludeUserHistory (options: BuildVideoGetQueryOptions) {
return [ 'api', 'full-light' ].includes(options.type)
}
private shouldIncludeAccount (options: BuildVideoGetQueryOptions) {
return [ 'api', 'full-light', 'account-blacklist-files' ].includes(options.type)
}
private shouldIncludeBlacklisted (options: BuildVideoGetQueryOptions) {
return [ 'api', 'full-light', 'account-blacklist-files', 'thumbnails-blacklist', 'blacklist-rights' ].includes(options.type)
}
private shouldIncludeOwnerUser (options: BuildVideoGetQueryOptions) {
return options.type === 'blacklist-rights'
}
private shouldIncludeThumbnails (options: BuildVideoGetQueryOptions) {
return [ 'api', 'full-light', 'account-blacklist-files', 'thumbnails', 'thumbnails-blacklist' ].includes(options.type)
}
2021-06-10 12:43:55 +00:00
}