diff options
Diffstat (limited to 'server/models/video/video-file.ts')
-rw-r--r-- | server/models/video/video-file.ts | 87 |
1 files changed, 81 insertions, 6 deletions
diff --git a/server/models/video/video-file.ts b/server/models/video/video-file.ts index 68e2d562a..cacef0106 100644 --- a/server/models/video/video-file.ts +++ b/server/models/video/video-file.ts | |||
@@ -23,22 +23,52 @@ import { parseAggregateResult, throwIfNotValid } from '../utils' | |||
23 | import { VideoModel } from './video' | 23 | import { VideoModel } from './video' |
24 | import { VideoRedundancyModel } from '../redundancy/video-redundancy' | 24 | import { VideoRedundancyModel } from '../redundancy/video-redundancy' |
25 | import { VideoStreamingPlaylistModel } from './video-streaming-playlist' | 25 | import { VideoStreamingPlaylistModel } from './video-streaming-playlist' |
26 | import { FindOptions, QueryTypes, Transaction } from 'sequelize' | 26 | import { FindOptions, Op, QueryTypes, Transaction } from 'sequelize' |
27 | import { MIMETYPES } from '../../initializers/constants' | 27 | import { MIMETYPES } from '../../initializers/constants' |
28 | import { MVideoFile } from '@server/typings/models' | 28 | import { MVideoFile, MVideoFileStreamingPlaylistVideo, MVideoFileVideo } from '../../typings/models/video/video-file' |
29 | import { MStreamingPlaylist, MStreamingPlaylistVideo, MVideo } from '@server/typings/models' | ||
29 | 30 | ||
30 | @Table({ | 31 | @Table({ |
31 | tableName: 'videoFile', | 32 | tableName: 'videoFile', |
32 | indexes: [ | 33 | indexes: [ |
33 | { | 34 | { |
34 | fields: [ 'videoId' ] | 35 | fields: [ 'videoId' ], |
36 | where: { | ||
37 | videoId: { | ||
38 | [Op.ne]: null | ||
39 | } | ||
40 | } | ||
41 | }, | ||
42 | { | ||
43 | fields: [ 'videoStreamingPlaylistId' ], | ||
44 | where: { | ||
45 | videoStreamingPlaylistId: { | ||
46 | [Op.ne]: null | ||
47 | } | ||
48 | } | ||
35 | }, | 49 | }, |
50 | |||
36 | { | 51 | { |
37 | fields: [ 'infoHash' ] | 52 | fields: [ 'infoHash' ] |
38 | }, | 53 | }, |
54 | |||
39 | { | 55 | { |
40 | fields: [ 'videoId', 'resolution', 'fps' ], | 56 | fields: [ 'videoId', 'resolution', 'fps' ], |
41 | unique: true | 57 | unique: true, |
58 | where: { | ||
59 | videoId: { | ||
60 | [Op.ne]: null | ||
61 | } | ||
62 | } | ||
63 | }, | ||
64 | { | ||
65 | fields: [ 'videoStreamingPlaylistId', 'resolution', 'fps' ], | ||
66 | unique: true, | ||
67 | where: { | ||
68 | videoStreamingPlaylistId: { | ||
69 | [Op.ne]: null | ||
70 | } | ||
71 | } | ||
42 | } | 72 | } |
43 | ] | 73 | ] |
44 | }) | 74 | }) |
@@ -81,12 +111,24 @@ export class VideoFileModel extends Model<VideoFileModel> { | |||
81 | 111 | ||
82 | @BelongsTo(() => VideoModel, { | 112 | @BelongsTo(() => VideoModel, { |
83 | foreignKey: { | 113 | foreignKey: { |
84 | allowNull: false | 114 | allowNull: true |
85 | }, | 115 | }, |
86 | onDelete: 'CASCADE' | 116 | onDelete: 'CASCADE' |
87 | }) | 117 | }) |
88 | Video: VideoModel | 118 | Video: VideoModel |
89 | 119 | ||
120 | @ForeignKey(() => VideoStreamingPlaylistModel) | ||
121 | @Column | ||
122 | videoStreamingPlaylistId: number | ||
123 | |||
124 | @BelongsTo(() => VideoStreamingPlaylistModel, { | ||
125 | foreignKey: { | ||
126 | allowNull: true | ||
127 | }, | ||
128 | onDelete: 'CASCADE' | ||
129 | }) | ||
130 | VideoStreamingPlaylist: VideoStreamingPlaylistModel | ||
131 | |||
90 | @HasMany(() => VideoRedundancyModel, { | 132 | @HasMany(() => VideoRedundancyModel, { |
91 | foreignKey: { | 133 | foreignKey: { |
92 | allowNull: true | 134 | allowNull: true |
@@ -163,6 +205,36 @@ export class VideoFileModel extends Model<VideoFileModel> { | |||
163 | })) | 205 | })) |
164 | } | 206 | } |
165 | 207 | ||
208 | // Redefine upsert because sequelize does not use an appropriate where clause in the update query with 2 unique indexes | ||
209 | static async customUpsert ( | ||
210 | videoFile: MVideoFile, | ||
211 | mode: 'streaming-playlist' | 'video', | ||
212 | transaction: Transaction | ||
213 | ) { | ||
214 | const baseWhere = { | ||
215 | fps: videoFile.fps, | ||
216 | resolution: videoFile.resolution | ||
217 | } | ||
218 | |||
219 | if (mode === 'streaming-playlist') Object.assign(baseWhere, { videoStreamingPlaylistId: videoFile.videoStreamingPlaylistId }) | ||
220 | else Object.assign(baseWhere, { videoId: videoFile.videoId }) | ||
221 | |||
222 | const element = await VideoFileModel.findOne({ where: baseWhere, transaction }) | ||
223 | if (!element) return videoFile.save({ transaction }) | ||
224 | |||
225 | for (const k of Object.keys(videoFile.toJSON())) { | ||
226 | element[k] = videoFile[k] | ||
227 | } | ||
228 | |||
229 | return element.save({ transaction }) | ||
230 | } | ||
231 | |||
232 | getVideoOrStreamingPlaylist (this: MVideoFileVideo | MVideoFileStreamingPlaylistVideo): MVideo | MStreamingPlaylistVideo { | ||
233 | if (this.videoId) return (this as MVideoFileVideo).Video | ||
234 | |||
235 | return (this as MVideoFileStreamingPlaylistVideo).VideoStreamingPlaylist | ||
236 | } | ||
237 | |||
166 | isAudio () { | 238 | isAudio () { |
167 | return !!MIMETYPES.AUDIO.EXT_MIMETYPE[this.extname] | 239 | return !!MIMETYPES.AUDIO.EXT_MIMETYPE[this.extname] |
168 | } | 240 | } |
@@ -170,6 +242,9 @@ export class VideoFileModel extends Model<VideoFileModel> { | |||
170 | hasSameUniqueKeysThan (other: MVideoFile) { | 242 | hasSameUniqueKeysThan (other: MVideoFile) { |
171 | return this.fps === other.fps && | 243 | return this.fps === other.fps && |
172 | this.resolution === other.resolution && | 244 | this.resolution === other.resolution && |
173 | this.videoId === other.videoId | 245 | ( |
246 | (this.videoId !== null && this.videoId === other.videoId) || | ||
247 | (this.videoStreamingPlaylistId !== null && this.videoStreamingPlaylistId === other.videoStreamingPlaylistId) | ||
248 | ) | ||
174 | } | 249 | } |
175 | } | 250 | } |