]>
Commit | Line | Data |
---|---|---|
d9bf974f | 1 | import { Sequelize, Transaction } from 'sequelize' |
7e7d8e48 | 2 | import { AbstractVideoQueryBuilder } from './shared/abstract-video-query-builder' |
1d43c3a6 C |
3 | import { VideoFileQueryBuilder } from './shared/video-file-query-builder' |
4 | import { VideoModelBuilder } from './shared/video-model-builder' | |
7e7d8e48 | 5 | import { VideoTableAttributes } from './shared/video-table-attributes' |
1d43c3a6 C |
6 | |
7 | /** | |
8 | * | |
9 | * Build a GET SQL query, fetch rows and create the video model | |
10 | * | |
11 | */ | |
d9bf974f | 12 | |
20a206c3 C |
13 | export type GetType = |
14 | 'api' | | |
15 | 'full-light' | | |
16 | 'account-blacklist-files' | | |
17 | 'all-files' | | |
18 | 'thumbnails' | | |
19 | 'thumbnails-blacklist' | | |
20 | 'id' | | |
21 | 'blacklist-rights' | |
22 | ||
d9bf974f | 23 | export type BuildVideoGetQueryOptions = { |
71d4af1e C |
24 | id?: number | string |
25 | url?: string | |
26 | ||
20a206c3 | 27 | type: GetType |
71d4af1e | 28 | |
d9bf974f | 29 | userId?: number |
71d4af1e C |
30 | transaction?: Transaction |
31 | ||
32 | logging?: boolean | |
d9bf974f C |
33 | } |
34 | ||
3c10840f | 35 | export class VideoModelGetQueryBuilder { |
1d43c3a6 C |
36 | videoQueryBuilder: VideosModelGetQuerySubBuilder |
37 | webtorrentFilesQueryBuilder: VideoFileQueryBuilder | |
38 | streamingPlaylistFilesQueryBuilder: VideoFileQueryBuilder | |
39 | ||
40 | private readonly videoModelBuilder: VideoModelBuilder | |
41 | ||
20a206c3 C |
42 | private static readonly videoFilesInclude = new Set<GetType>([ 'api', 'full-light', 'account-blacklist-files', 'all-files' ]) |
43 | ||
1d43c3a6 C |
44 | constructor (protected readonly sequelize: Sequelize) { |
45 | this.videoQueryBuilder = new VideosModelGetQuerySubBuilder(sequelize) | |
46 | this.webtorrentFilesQueryBuilder = new VideoFileQueryBuilder(sequelize) | |
47 | this.streamingPlaylistFilesQueryBuilder = new VideoFileQueryBuilder(sequelize) | |
48 | ||
7e7d8e48 | 49 | this.videoModelBuilder = new VideoModelBuilder('get', new VideoTableAttributes('get')) |
1d43c3a6 C |
50 | } |
51 | ||
71d4af1e | 52 | async queryVideo (options: BuildVideoGetQueryOptions) { |
1d43c3a6 C |
53 | const [ videoRows, webtorrentFilesRows, streamingPlaylistFilesRows ] = await Promise.all([ |
54 | this.videoQueryBuilder.queryVideos(options), | |
71d4af1e | 55 | |
3c10840f | 56 | VideoModelGetQueryBuilder.videoFilesInclude.has(options.type) |
71d4af1e C |
57 | ? this.webtorrentFilesQueryBuilder.queryWebTorrentVideos(options) |
58 | : Promise.resolve(undefined), | |
59 | ||
3c10840f | 60 | VideoModelGetQueryBuilder.videoFilesInclude.has(options.type) |
71d4af1e C |
61 | ? this.streamingPlaylistFilesQueryBuilder.queryStreamingPlaylistVideos(options) |
62 | : Promise.resolve(undefined) | |
1d43c3a6 C |
63 | ]) |
64 | ||
2760b454 C |
65 | const videos = this.videoModelBuilder.buildVideosFromRows({ |
66 | rows: videoRows, | |
67 | rowsWebTorrentFiles: webtorrentFilesRows, | |
68 | rowsStreamingPlaylist: streamingPlaylistFilesRows | |
69 | }) | |
1d43c3a6 C |
70 | |
71 | if (videos.length > 1) { | |
7e7d8e48 | 72 | throw new Error('Video results is more than 1') |
1d43c3a6 C |
73 | } |
74 | ||
75 | if (videos.length === 0) return null | |
7e7d8e48 | 76 | |
1d43c3a6 C |
77 | return videos[0] |
78 | } | |
79 | } | |
80 | ||
7e7d8e48 | 81 | export class VideosModelGetQuerySubBuilder extends AbstractVideoQueryBuilder { |
d9bf974f | 82 | protected attributes: { [key: string]: string } |
1d43c3a6 C |
83 | |
84 | protected webtorrentFilesQuery: string | |
85 | protected streamingPlaylistFilesQuery: string | |
d9bf974f | 86 | |
20a206c3 C |
87 | private static readonly trackersInclude = new Set<GetType>([ 'api' ]) |
88 | private static readonly liveInclude = new Set<GetType>([ 'api', 'full-light' ]) | |
89 | private static readonly scheduleUpdateInclude = new Set<GetType>([ 'api', 'full-light' ]) | |
90 | private static readonly tagsInclude = new Set<GetType>([ 'api', 'full-light' ]) | |
91 | private static readonly userHistoryInclude = new Set<GetType>([ 'api', 'full-light' ]) | |
92 | private static readonly accountInclude = new Set<GetType>([ 'api', 'full-light', 'account-blacklist-files' ]) | |
93 | private static readonly ownerUserInclude = new Set<GetType>([ 'blacklist-rights' ]) | |
94 | ||
95 | private static readonly blacklistedInclude = new Set<GetType>([ | |
96 | 'api', | |
97 | 'full-light', | |
98 | 'account-blacklist-files', | |
99 | 'thumbnails-blacklist', | |
100 | 'blacklist-rights' | |
101 | ]) | |
102 | ||
103 | private static readonly thumbnailsInclude = new Set<GetType>([ | |
104 | 'api', | |
105 | 'full-light', | |
106 | 'account-blacklist-files', | |
adddb12b | 107 | 'all-files', |
20a206c3 C |
108 | 'thumbnails', |
109 | 'thumbnails-blacklist' | |
110 | ]) | |
111 | ||
d9bf974f | 112 | constructor (protected readonly sequelize: Sequelize) { |
156c44c8 | 113 | super(sequelize, 'get') |
d9bf974f C |
114 | } |
115 | ||
116 | queryVideos (options: BuildVideoGetQueryOptions) { | |
1d43c3a6 | 117 | this.buildMainGetQuery(options) |
d9bf974f | 118 | |
71d4af1e | 119 | return this.runQuery(options) |
d9bf974f C |
120 | } |
121 | ||
1d43c3a6 | 122 | private buildMainGetQuery (options: BuildVideoGetQueryOptions) { |
d9bf974f C |
123 | this.attributes = { |
124 | '"video".*': '' | |
125 | } | |
126 | ||
20a206c3 | 127 | if (VideosModelGetQuerySubBuilder.thumbnailsInclude.has(options.type)) { |
71d4af1e C |
128 | this.includeThumbnails() |
129 | } | |
d9bf974f | 130 | |
20a206c3 | 131 | if (VideosModelGetQuerySubBuilder.blacklistedInclude.has(options.type)) { |
71d4af1e C |
132 | this.includeBlacklisted() |
133 | } | |
d9bf974f | 134 | |
20a206c3 | 135 | if (VideosModelGetQuerySubBuilder.accountInclude.has(options.type)) { |
71d4af1e C |
136 | this.includeChannels() |
137 | this.includeAccounts() | |
138 | } | |
d9bf974f | 139 | |
20a206c3 | 140 | if (VideosModelGetQuerySubBuilder.tagsInclude.has(options.type)) { |
71d4af1e C |
141 | this.includeTags() |
142 | } | |
d9bf974f | 143 | |
20a206c3 | 144 | if (VideosModelGetQuerySubBuilder.scheduleUpdateInclude.has(options.type)) { |
71d4af1e C |
145 | this.includeScheduleUpdate() |
146 | } | |
d9bf974f | 147 | |
20a206c3 | 148 | if (VideosModelGetQuerySubBuilder.liveInclude.has(options.type)) { |
71d4af1e C |
149 | this.includeLive() |
150 | } | |
d9bf974f | 151 | |
20a206c3 | 152 | if (options.userId && VideosModelGetQuerySubBuilder.userHistoryInclude.has(options.type)) { |
d9bf974f C |
153 | this.includeUserHistory(options.userId) |
154 | } | |
155 | ||
20a206c3 | 156 | if (VideosModelGetQuerySubBuilder.ownerUserInclude.has(options.type)) { |
71d4af1e C |
157 | this.includeOwnerUser() |
158 | } | |
159 | ||
20a206c3 | 160 | if (VideosModelGetQuerySubBuilder.trackersInclude.has(options.type)) { |
d9bf974f | 161 | this.includeTrackers() |
d9bf974f C |
162 | } |
163 | ||
71d4af1e | 164 | this.whereId(options) |
d9bf974f | 165 | |
71d4af1e | 166 | this.query = this.buildQuery(options) |
d9bf974f C |
167 | } |
168 | ||
71d4af1e | 169 | private buildQuery (options: BuildVideoGetQueryOptions) { |
20a206c3 | 170 | const order = VideosModelGetQuerySubBuilder.tagsInclude.has(options.type) |
71d4af1e C |
171 | ? 'ORDER BY "Tags"."name" ASC' |
172 | : '' | |
173 | ||
1d43c3a6 | 174 | const from = `SELECT * FROM "video" ${this.where} LIMIT 1` |
d9bf974f | 175 | |
3c79c2ce | 176 | return `${this.buildSelect()} FROM (${from}) AS "video" ${this.joins} ${order}` |
d9bf974f C |
177 | } |
178 | } |