mirror of https://github.com/Chocobozzz/PeerTube
Optimize feeds query
parent
c53853ca1b
commit
7fb45bdacb
|
@ -313,7 +313,12 @@ export class AbstractVideoQueryBuilder extends AbstractRunQuery {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
protected whereId (options: { id?: string | number, url?: string }) {
|
protected whereId (options: { ids?: number[], id?: string | number, url?: string }) {
|
||||||
|
if (options.ids) {
|
||||||
|
this.where = `WHERE "video"."id" IN (${createSafeIn(this.sequelize, options.ids)})`
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (options.url) {
|
if (options.url) {
|
||||||
this.where = 'WHERE "video"."url" = :videoUrl'
|
this.where = 'WHERE "video"."url" = :videoUrl'
|
||||||
this.replacements.videoUrl = options.url
|
this.replacements.videoUrl = options.url
|
||||||
|
|
|
@ -1,7 +1,17 @@
|
||||||
import { Sequelize } from 'sequelize'
|
import { Sequelize, Transaction } from 'sequelize'
|
||||||
import { BuildVideoGetQueryOptions } from '../video-model-get-query-builder'
|
|
||||||
import { AbstractVideoQueryBuilder } from './abstract-video-query-builder'
|
import { AbstractVideoQueryBuilder } from './abstract-video-query-builder'
|
||||||
|
|
||||||
|
export type FileQueryOptions = {
|
||||||
|
id?: string | number
|
||||||
|
url?: string
|
||||||
|
|
||||||
|
includeRedundancy: boolean
|
||||||
|
|
||||||
|
transaction?: Transaction
|
||||||
|
|
||||||
|
logging?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Fetch files (webtorrent and streaming playlist) according to a video
|
* Fetch files (webtorrent and streaming playlist) according to a video
|
||||||
|
@ -15,26 +25,26 @@ export class VideoFileQueryBuilder extends AbstractVideoQueryBuilder {
|
||||||
super(sequelize, 'get')
|
super(sequelize, 'get')
|
||||||
}
|
}
|
||||||
|
|
||||||
queryWebTorrentVideos (options: BuildVideoGetQueryOptions) {
|
queryWebTorrentVideos (options: FileQueryOptions) {
|
||||||
this.buildWebtorrentFilesQuery(options)
|
this.buildWebtorrentFilesQuery(options)
|
||||||
|
|
||||||
return this.runQuery(options)
|
return this.runQuery(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
queryStreamingPlaylistVideos (options: BuildVideoGetQueryOptions) {
|
queryStreamingPlaylistVideos (options: FileQueryOptions) {
|
||||||
this.buildVideoStreamingPlaylistFilesQuery(options)
|
this.buildVideoStreamingPlaylistFilesQuery(options)
|
||||||
|
|
||||||
return this.runQuery(options)
|
return this.runQuery(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
private buildWebtorrentFilesQuery (options: BuildVideoGetQueryOptions) {
|
private buildWebtorrentFilesQuery (options: FileQueryOptions) {
|
||||||
this.attributes = {
|
this.attributes = {
|
||||||
'"video"."id"': ''
|
'"video"."id"': ''
|
||||||
}
|
}
|
||||||
|
|
||||||
this.includeWebtorrentFiles()
|
this.includeWebtorrentFiles()
|
||||||
|
|
||||||
if (this.shouldIncludeRedundancies(options)) {
|
if (options.includeRedundancy) {
|
||||||
this.includeWebTorrentRedundancies()
|
this.includeWebTorrentRedundancies()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,14 +53,14 @@ export class VideoFileQueryBuilder extends AbstractVideoQueryBuilder {
|
||||||
this.query = this.buildQuery()
|
this.query = this.buildQuery()
|
||||||
}
|
}
|
||||||
|
|
||||||
private buildVideoStreamingPlaylistFilesQuery (options: BuildVideoGetQueryOptions) {
|
private buildVideoStreamingPlaylistFilesQuery (options: FileQueryOptions) {
|
||||||
this.attributes = {
|
this.attributes = {
|
||||||
'"video"."id"': ''
|
'"video"."id"': ''
|
||||||
}
|
}
|
||||||
|
|
||||||
this.includeStreamingPlaylistFiles()
|
this.includeStreamingPlaylistFiles()
|
||||||
|
|
||||||
if (this.shouldIncludeRedundancies(options)) {
|
if (options.includeRedundancy) {
|
||||||
this.includeStreamingPlaylistRedundancies()
|
this.includeStreamingPlaylistRedundancies()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,8 +72,4 @@ export class VideoFileQueryBuilder extends AbstractVideoQueryBuilder {
|
||||||
private buildQuery () {
|
private buildQuery () {
|
||||||
return `${this.buildSelect()} FROM "video" ${this.joins} ${this.where}`
|
return `${this.buildSelect()} FROM "video" ${this.joins} ${this.where}`
|
||||||
}
|
}
|
||||||
|
|
||||||
private shouldIncludeRedundancies (options: BuildVideoGetQueryOptions) {
|
|
||||||
return options.type === 'api'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { pick } from 'lodash'
|
||||||
import { Sequelize, Transaction } from 'sequelize'
|
import { Sequelize, Transaction } from 'sequelize'
|
||||||
import { AbstractVideoQueryBuilder } from './shared/abstract-video-query-builder'
|
import { AbstractVideoQueryBuilder } from './shared/abstract-video-query-builder'
|
||||||
import { VideoFileQueryBuilder } from './shared/video-file-query-builder'
|
import { VideoFileQueryBuilder } from './shared/video-file-query-builder'
|
||||||
|
@ -50,15 +51,21 @@ export class VideoModelGetQueryBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
async queryVideo (options: BuildVideoGetQueryOptions) {
|
async queryVideo (options: BuildVideoGetQueryOptions) {
|
||||||
|
const fileQueryOptions = {
|
||||||
|
...pick(options, [ 'id', 'url', 'transaction', 'logging' ]),
|
||||||
|
|
||||||
|
includeRedundancy: this.shouldIncludeRedundancies(options)
|
||||||
|
}
|
||||||
|
|
||||||
const [ videoRows, webtorrentFilesRows, streamingPlaylistFilesRows ] = await Promise.all([
|
const [ videoRows, webtorrentFilesRows, streamingPlaylistFilesRows ] = await Promise.all([
|
||||||
this.videoQueryBuilder.queryVideos(options),
|
this.videoQueryBuilder.queryVideos(options),
|
||||||
|
|
||||||
VideoModelGetQueryBuilder.videoFilesInclude.has(options.type)
|
VideoModelGetQueryBuilder.videoFilesInclude.has(options.type)
|
||||||
? this.webtorrentFilesQueryBuilder.queryWebTorrentVideos(options)
|
? this.webtorrentFilesQueryBuilder.queryWebTorrentVideos(fileQueryOptions)
|
||||||
: Promise.resolve(undefined),
|
: Promise.resolve(undefined),
|
||||||
|
|
||||||
VideoModelGetQueryBuilder.videoFilesInclude.has(options.type)
|
VideoModelGetQueryBuilder.videoFilesInclude.has(options.type)
|
||||||
? this.streamingPlaylistFilesQueryBuilder.queryStreamingPlaylistVideos(options)
|
? this.streamingPlaylistFilesQueryBuilder.queryStreamingPlaylistVideos(fileQueryOptions)
|
||||||
: Promise.resolve(undefined)
|
: Promise.resolve(undefined)
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -76,6 +83,10 @@ export class VideoModelGetQueryBuilder {
|
||||||
|
|
||||||
return videos[0]
|
return videos[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private shouldIncludeRedundancies (options: BuildVideoGetQueryOptions) {
|
||||||
|
return options.type === 'api'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class VideosModelGetQuerySubBuilder extends AbstractVideoQueryBuilder {
|
export class VideosModelGetQuerySubBuilder extends AbstractVideoQueryBuilder {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import { VideoInclude } from '@shared/models'
|
import { pick } from 'lodash'
|
||||||
import { Sequelize } from 'sequelize'
|
import { Sequelize } from 'sequelize'
|
||||||
|
import { VideoInclude } from '@shared/models'
|
||||||
import { AbstractVideoQueryBuilder } from './shared/abstract-video-query-builder'
|
import { AbstractVideoQueryBuilder } from './shared/abstract-video-query-builder'
|
||||||
|
import { VideoFileQueryBuilder } from './shared/video-file-query-builder'
|
||||||
import { VideoModelBuilder } from './shared/video-model-builder'
|
import { VideoModelBuilder } from './shared/video-model-builder'
|
||||||
import { BuildVideosListQueryOptions, VideosIdListQueryBuilder } from './videos-id-list-query-builder'
|
import { BuildVideosListQueryOptions, VideosIdListQueryBuilder } from './videos-id-list-query-builder'
|
||||||
|
|
||||||
|
@ -16,20 +18,46 @@ export class VideosModelListQueryBuilder extends AbstractVideoQueryBuilder {
|
||||||
private innerQuery: string
|
private innerQuery: string
|
||||||
private innerSort: string
|
private innerSort: string
|
||||||
|
|
||||||
|
webtorrentFilesQueryBuilder: VideoFileQueryBuilder
|
||||||
|
streamingPlaylistFilesQueryBuilder: VideoFileQueryBuilder
|
||||||
|
|
||||||
private readonly videoModelBuilder: VideoModelBuilder
|
private readonly videoModelBuilder: VideoModelBuilder
|
||||||
|
|
||||||
constructor (protected readonly sequelize: Sequelize) {
|
constructor (protected readonly sequelize: Sequelize) {
|
||||||
super(sequelize, 'list')
|
super(sequelize, 'list')
|
||||||
|
|
||||||
this.videoModelBuilder = new VideoModelBuilder(this.mode, this.tables)
|
this.videoModelBuilder = new VideoModelBuilder(this.mode, this.tables)
|
||||||
|
this.webtorrentFilesQueryBuilder = new VideoFileQueryBuilder(sequelize)
|
||||||
|
this.streamingPlaylistFilesQueryBuilder = new VideoFileQueryBuilder(sequelize)
|
||||||
}
|
}
|
||||||
|
|
||||||
queryVideos (options: BuildVideosListQueryOptions) {
|
async queryVideos (options: BuildVideosListQueryOptions) {
|
||||||
this.buildInnerQuery(options)
|
this.buildInnerQuery(options)
|
||||||
this.buildMainQuery(options)
|
this.buildMainQuery(options)
|
||||||
|
|
||||||
return this.runQuery()
|
const rows = await this.runQuery()
|
||||||
.then(rows => this.videoModelBuilder.buildVideosFromRows({ rows, include: options.include }))
|
|
||||||
|
if (options.include & VideoInclude.FILES) {
|
||||||
|
const videoIds = Array.from(new Set(rows.map(r => r.id)))
|
||||||
|
|
||||||
|
if (videoIds.length !== 0) {
|
||||||
|
const fileQueryOptions = {
|
||||||
|
...pick(options, [ 'transaction', 'logging' ]),
|
||||||
|
|
||||||
|
ids: videoIds,
|
||||||
|
includeRedundancy: false
|
||||||
|
}
|
||||||
|
|
||||||
|
const [ rowsWebTorrentFiles, rowsStreamingPlaylist ] = await Promise.all([
|
||||||
|
this.webtorrentFilesQueryBuilder.queryWebTorrentVideos(fileQueryOptions),
|
||||||
|
this.streamingPlaylistFilesQueryBuilder.queryStreamingPlaylistVideos(fileQueryOptions)
|
||||||
|
])
|
||||||
|
|
||||||
|
return this.videoModelBuilder.buildVideosFromRows({ rows, include: options.include, rowsStreamingPlaylist, rowsWebTorrentFiles })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.videoModelBuilder.buildVideosFromRows({ rows, include: options.include })
|
||||||
}
|
}
|
||||||
|
|
||||||
private buildInnerQuery (options: BuildVideosListQueryOptions) {
|
private buildInnerQuery (options: BuildVideosListQueryOptions) {
|
||||||
|
@ -52,11 +80,6 @@ export class VideosModelListQueryBuilder extends AbstractVideoQueryBuilder {
|
||||||
this.includeAccounts()
|
this.includeAccounts()
|
||||||
this.includeThumbnails()
|
this.includeThumbnails()
|
||||||
|
|
||||||
if (options.include & VideoInclude.FILES) {
|
|
||||||
this.includeWebtorrentFiles()
|
|
||||||
this.includeStreamingPlaylistFiles()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.user) {
|
if (options.user) {
|
||||||
this.includeUserHistory(options.user.id)
|
this.includeUserHistory(options.user.id)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue