]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/models/video/sql/video-model-get-query-builder.ts
Optimize join build
[github/Chocobozzz/PeerTube.git] / server / models / video / sql / video-model-get-query-builder.ts
CommitLineData
d9bf974f 1import { Sequelize, Transaction } from 'sequelize'
d9bf974f 2import { AbstractVideosModelQueryBuilder } from './shared/abstract-videos-model-query-builder'
1d43c3a6
C
3import { VideoFileQueryBuilder } from './shared/video-file-query-builder'
4import { VideoModelBuilder } from './shared/video-model-builder'
17bb4538 5import { VideoTables } from './shared/video-tables'
1d43c3a6
C
6
7/**
8 *
9 * Build a GET SQL query, fetch rows and create the video model
10 *
11 */
d9bf974f
C
12
13export type BuildVideoGetQueryOptions = {
14 id: number | string
15 transaction?: Transaction
16 userId?: number
17 forGetAPI?: boolean
18}
19
1d43c3a6
C
20export class VideosModelGetQueryBuilder {
21 videoQueryBuilder: VideosModelGetQuerySubBuilder
22 webtorrentFilesQueryBuilder: VideoFileQueryBuilder
23 streamingPlaylistFilesQueryBuilder: VideoFileQueryBuilder
24
25 private readonly videoModelBuilder: VideoModelBuilder
26
27 constructor (protected readonly sequelize: Sequelize) {
28 this.videoQueryBuilder = new VideosModelGetQuerySubBuilder(sequelize)
29 this.webtorrentFilesQueryBuilder = new VideoFileQueryBuilder(sequelize)
30 this.streamingPlaylistFilesQueryBuilder = new VideoFileQueryBuilder(sequelize)
31
17bb4538 32 this.videoModelBuilder = new VideoModelBuilder('get', new VideoTables('get'))
1d43c3a6
C
33 }
34
35 async queryVideos (options: BuildVideoGetQueryOptions) {
36 const [ videoRows, webtorrentFilesRows, streamingPlaylistFilesRows ] = await Promise.all([
37 this.videoQueryBuilder.queryVideos(options),
38 this.webtorrentFilesQueryBuilder.queryWebTorrentVideos(options),
39 this.streamingPlaylistFilesQueryBuilder.queryStreamingPlaylistVideos(options)
40 ])
41
42 const videos = this.videoModelBuilder.buildVideosFromRows(videoRows, webtorrentFilesRows, streamingPlaylistFilesRows)
43
44 if (videos.length > 1) {
45 throw new Error('Video results is more than ')
46 }
47
48 if (videos.length === 0) return null
49 return videos[0]
50 }
51}
52
53export class VideosModelGetQuerySubBuilder extends AbstractVideosModelQueryBuilder {
d9bf974f 54 protected attributes: { [key: string]: string }
1d43c3a6
C
55
56 protected webtorrentFilesQuery: string
57 protected streamingPlaylistFilesQuery: string
d9bf974f
C
58
59 constructor (protected readonly sequelize: Sequelize) {
60 super('get')
61 }
62
63 queryVideos (options: BuildVideoGetQueryOptions) {
1d43c3a6 64 this.buildMainGetQuery(options)
d9bf974f 65
17bb4538 66 return this.runQuery(options.transaction)
d9bf974f
C
67 }
68
1d43c3a6 69 private buildMainGetQuery (options: BuildVideoGetQueryOptions) {
d9bf974f
C
70 this.attributes = {
71 '"video".*': ''
72 }
73
74 this.includeChannels()
75 this.includeAccounts()
76
77 this.includeTags()
78
79 this.includeThumbnails()
80
d9bf974f
C
81 this.includeBlacklisted()
82
83 this.includeScheduleUpdate()
84
85 this.includeLive()
86
87 if (options.userId) {
88 this.includeUserHistory(options.userId)
89 }
90
91 if (options.forGetAPI === true) {
92 this.includeTrackers()
d9bf974f
C
93 }
94
95 this.whereId(options.id)
96
1d43c3a6 97 this.query = this.buildQuery()
d9bf974f
C
98 }
99
1d43c3a6
C
100 private buildQuery () {
101 const order = 'ORDER BY "Tags"."name" ASC'
102 const from = `SELECT * FROM "video" ${this.where} LIMIT 1`
d9bf974f 103
3c79c2ce 104 return `${this.buildSelect()} FROM (${from}) AS "video" ${this.joins} ${order}`
d9bf974f
C
105 }
106}