]>
Commit | Line | Data |
---|---|---|
d9bf974f | 1 | import { Sequelize, Transaction } from 'sequelize' |
d9bf974f | 2 | import { AbstractVideosModelQueryBuilder } from './shared/abstract-videos-model-query-builder' |
1d43c3a6 C |
3 | import { VideoAttributes } from './shared/video-attributes' |
4 | import { VideoFileQueryBuilder } from './shared/video-file-query-builder' | |
5 | import { VideoModelBuilder } from './shared/video-model-builder' | |
6 | ||
7 | /** | |
8 | * | |
9 | * Build a GET SQL query, fetch rows and create the video model | |
10 | * | |
11 | */ | |
d9bf974f C |
12 | |
13 | export type BuildVideoGetQueryOptions = { | |
14 | id: number | string | |
15 | transaction?: Transaction | |
16 | userId?: number | |
17 | forGetAPI?: boolean | |
18 | } | |
19 | ||
1d43c3a6 C |
20 | export 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 | ||
32 | this.videoModelBuilder = new VideoModelBuilder('get', new VideoAttributes('get')) | |
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 | ||
53 | export class VideosModelGetQuerySubBuilder extends AbstractVideosModelQueryBuilder { | |
d9bf974f C |
54 | protected attributes: { [key: string]: string } |
55 | protected joins: string[] = [] | |
1d43c3a6 C |
56 | |
57 | protected webtorrentFilesQuery: string | |
58 | protected streamingPlaylistFilesQuery: string | |
d9bf974f C |
59 | |
60 | constructor (protected readonly sequelize: Sequelize) { | |
61 | super('get') | |
62 | } | |
63 | ||
64 | queryVideos (options: BuildVideoGetQueryOptions) { | |
1d43c3a6 | 65 | this.buildMainGetQuery(options) |
d9bf974f | 66 | |
1d43c3a6 | 67 | return this.runQuery(options.transaction, true) |
d9bf974f C |
68 | } |
69 | ||
1d43c3a6 | 70 | private buildMainGetQuery (options: BuildVideoGetQueryOptions) { |
d9bf974f C |
71 | this.attributes = { |
72 | '"video".*': '' | |
73 | } | |
74 | ||
75 | this.includeChannels() | |
76 | this.includeAccounts() | |
77 | ||
78 | this.includeTags() | |
79 | ||
80 | this.includeThumbnails() | |
81 | ||
d9bf974f C |
82 | this.includeBlacklisted() |
83 | ||
84 | this.includeScheduleUpdate() | |
85 | ||
86 | this.includeLive() | |
87 | ||
88 | if (options.userId) { | |
89 | this.includeUserHistory(options.userId) | |
90 | } | |
91 | ||
92 | if (options.forGetAPI === true) { | |
93 | this.includeTrackers() | |
d9bf974f C |
94 | } |
95 | ||
96 | this.whereId(options.id) | |
97 | ||
1d43c3a6 | 98 | this.query = this.buildQuery() |
d9bf974f C |
99 | } |
100 | ||
1d43c3a6 C |
101 | private buildQuery () { |
102 | const order = 'ORDER BY "Tags"."name" ASC' | |
103 | const from = `SELECT * FROM "video" ${this.where} LIMIT 1` | |
d9bf974f | 104 | |
1d43c3a6 | 105 | return `${this.buildSelect()} FROM (${from}) AS "video" ${this.joins.join(' ')} ${this.where} ${order}` |
d9bf974f C |
106 | } |
107 | } |