diff options
Diffstat (limited to 'server/models')
-rw-r--r-- | server/models/account/account-blocklist.ts | 2 | ||||
-rw-r--r-- | server/models/account/user-notification.ts | 2 | ||||
-rw-r--r-- | server/models/activitypub/actor.ts | 37 | ||||
-rw-r--r-- | server/models/server/server-blocklist.ts | 2 | ||||
-rw-r--r-- | server/models/video/video-caption.ts | 2 | ||||
-rw-r--r-- | server/models/video/video-channel.ts | 23 | ||||
-rw-r--r-- | server/models/video/video-playlist.ts | 2 | ||||
-rw-r--r-- | server/models/video/video.ts | 153 |
8 files changed, 116 insertions, 107 deletions
diff --git a/server/models/account/account-blocklist.ts b/server/models/account/account-blocklist.ts index 6ebe32556..e2f66d733 100644 --- a/server/models/account/account-blocklist.ts +++ b/server/models/account/account-blocklist.ts | |||
@@ -80,7 +80,7 @@ export class AccountBlocklistModel extends Model<AccountBlocklistModel> { | |||
80 | attributes: [ 'accountId', 'id' ], | 80 | attributes: [ 'accountId', 'id' ], |
81 | where: { | 81 | where: { |
82 | accountId: { | 82 | accountId: { |
83 | [Op.in]: accountIds // FIXME: sequelize ANY seems broken | 83 | [Op.in]: accountIds |
84 | }, | 84 | }, |
85 | targetAccountId | 85 | targetAccountId |
86 | }, | 86 | }, |
diff --git a/server/models/account/user-notification.ts b/server/models/account/user-notification.ts index a05f30175..f649b8f95 100644 --- a/server/models/account/user-notification.ts +++ b/server/models/account/user-notification.ts | |||
@@ -363,7 +363,7 @@ export class UserNotificationModel extends Model<UserNotificationModel> { | |||
363 | where: { | 363 | where: { |
364 | userId, | 364 | userId, |
365 | id: { | 365 | id: { |
366 | [Op.in]: notificationIds // FIXME: sequelize ANY seems broken | 366 | [Op.in]: notificationIds |
367 | } | 367 | } |
368 | } | 368 | } |
369 | } | 369 | } |
diff --git a/server/models/activitypub/actor.ts b/server/models/activitypub/actor.ts index 007647ced..d651a281a 100644 --- a/server/models/activitypub/actor.ts +++ b/server/models/activitypub/actor.ts | |||
@@ -43,7 +43,7 @@ import { | |||
43 | MActorFull, | 43 | MActorFull, |
44 | MActorHost, | 44 | MActorHost, |
45 | MActorServer, | 45 | MActorServer, |
46 | MActorSummaryFormattable, | 46 | MActorSummaryFormattable, MActorUrl, |
47 | MActorWithInboxes | 47 | MActorWithInboxes |
48 | } from '../../typings/models' | 48 | } from '../../typings/models' |
49 | import * as Bluebird from 'bluebird' | 49 | import * as Bluebird from 'bluebird' |
@@ -276,7 +276,8 @@ export class ActorModel extends Model<ActorModel> { | |||
276 | }) | 276 | }) |
277 | VideoChannel: VideoChannelModel | 277 | VideoChannel: VideoChannelModel |
278 | 278 | ||
279 | private static cache: { [ id: string ]: any } = {} | 279 | private static localNameCache: { [ id: string ]: any } = {} |
280 | private static localUrlCache: { [ id: string ]: any } = {} | ||
280 | 281 | ||
281 | static load (id: number): Bluebird<MActor> { | 282 | static load (id: number): Bluebird<MActor> { |
282 | return ActorModel.unscoped().findByPk(id) | 283 | return ActorModel.unscoped().findByPk(id) |
@@ -345,8 +346,8 @@ export class ActorModel extends Model<ActorModel> { | |||
345 | 346 | ||
346 | static loadLocalByName (preferredUsername: string, transaction?: Transaction): Bluebird<MActorFull> { | 347 | static loadLocalByName (preferredUsername: string, transaction?: Transaction): Bluebird<MActorFull> { |
347 | // The server actor never change, so we can easily cache it | 348 | // The server actor never change, so we can easily cache it |
348 | if (preferredUsername === SERVER_ACTOR_NAME && ActorModel.cache[preferredUsername]) { | 349 | if (preferredUsername === SERVER_ACTOR_NAME && ActorModel.localNameCache[preferredUsername]) { |
349 | return Bluebird.resolve(ActorModel.cache[preferredUsername]) | 350 | return Bluebird.resolve(ActorModel.localNameCache[preferredUsername]) |
350 | } | 351 | } |
351 | 352 | ||
352 | const query = { | 353 | const query = { |
@@ -361,7 +362,33 @@ export class ActorModel extends Model<ActorModel> { | |||
361 | .findOne(query) | 362 | .findOne(query) |
362 | .then(actor => { | 363 | .then(actor => { |
363 | if (preferredUsername === SERVER_ACTOR_NAME) { | 364 | if (preferredUsername === SERVER_ACTOR_NAME) { |
364 | ActorModel.cache[ preferredUsername ] = actor | 365 | ActorModel.localNameCache[ preferredUsername ] = actor |
366 | } | ||
367 | |||
368 | return actor | ||
369 | }) | ||
370 | } | ||
371 | |||
372 | static loadLocalUrlByName (preferredUsername: string, transaction?: Transaction): Bluebird<MActorUrl> { | ||
373 | // The server actor never change, so we can easily cache it | ||
374 | if (preferredUsername === SERVER_ACTOR_NAME && ActorModel.localUrlCache[preferredUsername]) { | ||
375 | return Bluebird.resolve(ActorModel.localUrlCache[preferredUsername]) | ||
376 | } | ||
377 | |||
378 | const query = { | ||
379 | attributes: [ 'url' ], | ||
380 | where: { | ||
381 | preferredUsername, | ||
382 | serverId: null | ||
383 | }, | ||
384 | transaction | ||
385 | } | ||
386 | |||
387 | return ActorModel.unscoped() | ||
388 | .findOne(query) | ||
389 | .then(actor => { | ||
390 | if (preferredUsername === SERVER_ACTOR_NAME) { | ||
391 | ActorModel.localUrlCache[ preferredUsername ] = actor | ||
365 | } | 392 | } |
366 | 393 | ||
367 | return actor | 394 | return actor |
diff --git a/server/models/server/server-blocklist.ts b/server/models/server/server-blocklist.ts index b88df4fd5..883ae47ab 100644 --- a/server/models/server/server-blocklist.ts +++ b/server/models/server/server-blocklist.ts | |||
@@ -81,7 +81,7 @@ export class ServerBlocklistModel extends Model<ServerBlocklistModel> { | |||
81 | attributes: [ 'accountId', 'id' ], | 81 | attributes: [ 'accountId', 'id' ], |
82 | where: { | 82 | where: { |
83 | accountId: { | 83 | accountId: { |
84 | [Op.in]: accountIds // FIXME: sequelize ANY seems broken | 84 | [Op.in]: accountIds |
85 | }, | 85 | }, |
86 | targetServerId | 86 | targetServerId |
87 | }, | 87 | }, |
diff --git a/server/models/video/video-caption.ts b/server/models/video/video-caption.ts index eeb2a4afd..6335d44e4 100644 --- a/server/models/video/video-caption.ts +++ b/server/models/video/video-caption.ts | |||
@@ -120,7 +120,7 @@ export class VideoCaptionModel extends Model<VideoCaptionModel> { | |||
120 | language | 120 | language |
121 | } | 121 | } |
122 | 122 | ||
123 | return (VideoCaptionModel.upsert<VideoCaptionModel>(values, { transaction, returning: true }) as any) // FIXME: typings | 123 | return VideoCaptionModel.upsert(values, { transaction, returning: true }) |
124 | .then(([ caption ]) => caption) | 124 | .then(([ caption ]) => caption) |
125 | } | 125 | } |
126 | 126 | ||
diff --git a/server/models/video/video-channel.ts b/server/models/video/video-channel.ts index e10adcb3a..4e98e7ba3 100644 --- a/server/models/video/video-channel.ts +++ b/server/models/video/video-channel.ts | |||
@@ -43,18 +43,6 @@ import { | |||
43 | MChannelSummaryFormattable | 43 | MChannelSummaryFormattable |
44 | } from '../../typings/models/video' | 44 | } from '../../typings/models/video' |
45 | 45 | ||
46 | // FIXME: Define indexes here because there is an issue with TS and Sequelize.literal when called directly in the annotation | ||
47 | const indexes: ModelIndexesOptions[] = [ | ||
48 | buildTrigramSearchIndex('video_channel_name_trigram', 'name'), | ||
49 | |||
50 | { | ||
51 | fields: [ 'accountId' ] | ||
52 | }, | ||
53 | { | ||
54 | fields: [ 'actorId' ] | ||
55 | } | ||
56 | ] | ||
57 | |||
58 | export enum ScopeNames { | 46 | export enum ScopeNames { |
59 | FOR_API = 'FOR_API', | 47 | FOR_API = 'FOR_API', |
60 | WITH_ACCOUNT = 'WITH_ACCOUNT', | 48 | WITH_ACCOUNT = 'WITH_ACCOUNT', |
@@ -176,7 +164,16 @@ export type SummaryOptions = { | |||
176 | })) | 164 | })) |
177 | @Table({ | 165 | @Table({ |
178 | tableName: 'videoChannel', | 166 | tableName: 'videoChannel', |
179 | indexes | 167 | indexes: [ |
168 | buildTrigramSearchIndex('video_channel_name_trigram', 'name'), | ||
169 | |||
170 | { | ||
171 | fields: [ 'accountId' ] | ||
172 | }, | ||
173 | { | ||
174 | fields: [ 'actorId' ] | ||
175 | } | ||
176 | ] | ||
180 | }) | 177 | }) |
181 | export class VideoChannelModel extends Model<VideoChannelModel> { | 178 | export class VideoChannelModel extends Model<VideoChannelModel> { |
182 | 179 | ||
diff --git a/server/models/video/video-playlist.ts b/server/models/video/video-playlist.ts index bcdda36e5..ba1fc23ea 100644 --- a/server/models/video/video-playlist.ts +++ b/server/models/video/video-playlist.ts | |||
@@ -369,7 +369,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> { | |||
369 | model: VideoPlaylistElementModel.unscoped(), | 369 | model: VideoPlaylistElementModel.unscoped(), |
370 | where: { | 370 | where: { |
371 | videoId: { | 371 | videoId: { |
372 | [Op.in]: videoIds // FIXME: sequelize ANY seems broken | 372 | [Op.in]: videoIds |
373 | } | 373 | } |
374 | }, | 374 | }, |
375 | required: true | 375 | required: true |
diff --git a/server/models/video/video.ts b/server/models/video/video.ts index eacffe186..20e1f1c4a 100644 --- a/server/models/video/video.ts +++ b/server/models/video/video.ts | |||
@@ -1,18 +1,7 @@ | |||
1 | import * as Bluebird from 'bluebird' | 1 | import * as Bluebird from 'bluebird' |
2 | import { maxBy, minBy } from 'lodash' | 2 | import { maxBy, minBy } from 'lodash' |
3 | import { join } from 'path' | 3 | import { join } from 'path' |
4 | import { | 4 | import { CountOptions, FindOptions, IncludeOptions, Op, QueryTypes, ScopeOptions, Sequelize, Transaction, WhereOptions } from 'sequelize' |
5 | CountOptions, | ||
6 | FindOptions, | ||
7 | IncludeOptions, | ||
8 | ModelIndexesOptions, | ||
9 | Op, | ||
10 | QueryTypes, | ||
11 | ScopeOptions, | ||
12 | Sequelize, | ||
13 | Transaction, | ||
14 | WhereOptions | ||
15 | } from 'sequelize' | ||
16 | import { | 5 | import { |
17 | AllowNull, | 6 | AllowNull, |
18 | BeforeDestroy, | 7 | BeforeDestroy, |
@@ -136,8 +125,7 @@ import { | |||
136 | MVideoThumbnailBlacklist, | 125 | MVideoThumbnailBlacklist, |
137 | MVideoWithAllFiles, | 126 | MVideoWithAllFiles, |
138 | MVideoWithFile, | 127 | MVideoWithFile, |
139 | MVideoWithRights, | 128 | MVideoWithRights |
140 | MStreamingPlaylistFiles | ||
141 | } from '../../typings/models' | 129 | } from '../../typings/models' |
142 | import { MVideoFile, MVideoFileStreamingPlaylistVideo } from '../../typings/models/video/video-file' | 130 | import { MVideoFile, MVideoFileStreamingPlaylistVideo } from '../../typings/models/video/video-file' |
143 | import { MThumbnail } from '../../typings/models/video/thumbnail' | 131 | import { MThumbnail } from '../../typings/models/video/thumbnail' |
@@ -145,74 +133,6 @@ import { VideoFile } from '@shared/models/videos/video-file.model' | |||
145 | import { getHLSDirectory, getTorrentFileName, getTorrentFilePath, getVideoFilename, getVideoFilePath } from '@server/lib/video-paths' | 133 | import { getHLSDirectory, getTorrentFileName, getTorrentFilePath, getVideoFilename, getVideoFilePath } from '@server/lib/video-paths' |
146 | import validator from 'validator' | 134 | import validator from 'validator' |
147 | 135 | ||
148 | // FIXME: Define indexes here because there is an issue with TS and Sequelize.literal when called directly in the annotation | ||
149 | const indexes: (ModelIndexesOptions & { where?: WhereOptions })[] = [ | ||
150 | buildTrigramSearchIndex('video_name_trigram', 'name'), | ||
151 | |||
152 | { fields: [ 'createdAt' ] }, | ||
153 | { | ||
154 | fields: [ | ||
155 | { name: 'publishedAt', order: 'DESC' }, | ||
156 | { name: 'id', order: 'ASC' } | ||
157 | ] | ||
158 | }, | ||
159 | { fields: [ 'duration' ] }, | ||
160 | { fields: [ 'views' ] }, | ||
161 | { fields: [ 'channelId' ] }, | ||
162 | { | ||
163 | fields: [ 'originallyPublishedAt' ], | ||
164 | where: { | ||
165 | originallyPublishedAt: { | ||
166 | [Op.ne]: null | ||
167 | } | ||
168 | } | ||
169 | }, | ||
170 | { | ||
171 | fields: [ 'category' ], // We don't care videos with an unknown category | ||
172 | where: { | ||
173 | category: { | ||
174 | [Op.ne]: null | ||
175 | } | ||
176 | } | ||
177 | }, | ||
178 | { | ||
179 | fields: [ 'licence' ], // We don't care videos with an unknown licence | ||
180 | where: { | ||
181 | licence: { | ||
182 | [Op.ne]: null | ||
183 | } | ||
184 | } | ||
185 | }, | ||
186 | { | ||
187 | fields: [ 'language' ], // We don't care videos with an unknown language | ||
188 | where: { | ||
189 | language: { | ||
190 | [Op.ne]: null | ||
191 | } | ||
192 | } | ||
193 | }, | ||
194 | { | ||
195 | fields: [ 'nsfw' ], // Most of the videos are not NSFW | ||
196 | where: { | ||
197 | nsfw: true | ||
198 | } | ||
199 | }, | ||
200 | { | ||
201 | fields: [ 'remote' ], // Only index local videos | ||
202 | where: { | ||
203 | remote: false | ||
204 | } | ||
205 | }, | ||
206 | { | ||
207 | fields: [ 'uuid' ], | ||
208 | unique: true | ||
209 | }, | ||
210 | { | ||
211 | fields: [ 'url' ], | ||
212 | unique: true | ||
213 | } | ||
214 | ] | ||
215 | |||
216 | export enum ScopeNames { | 136 | export enum ScopeNames { |
217 | AVAILABLE_FOR_LIST_IDS = 'AVAILABLE_FOR_LIST_IDS', | 137 | AVAILABLE_FOR_LIST_IDS = 'AVAILABLE_FOR_LIST_IDS', |
218 | FOR_API = 'FOR_API', | 138 | FOR_API = 'FOR_API', |
@@ -292,7 +212,7 @@ export type AvailableForListIDsOptions = { | |||
292 | if (options.ids) { | 212 | if (options.ids) { |
293 | query.where = { | 213 | query.where = { |
294 | id: { | 214 | id: { |
295 | [ Op.in ]: options.ids // FIXME: sequelize ANY seems broken | 215 | [ Op.in ]: options.ids |
296 | } | 216 | } |
297 | } | 217 | } |
298 | } | 218 | } |
@@ -760,7 +680,72 @@ export type AvailableForListIDsOptions = { | |||
760 | })) | 680 | })) |
761 | @Table({ | 681 | @Table({ |
762 | tableName: 'video', | 682 | tableName: 'video', |
763 | indexes | 683 | indexes: [ |
684 | buildTrigramSearchIndex('video_name_trigram', 'name'), | ||
685 | |||
686 | { fields: [ 'createdAt' ] }, | ||
687 | { | ||
688 | fields: [ | ||
689 | { name: 'publishedAt', order: 'DESC' }, | ||
690 | { name: 'id', order: 'ASC' } | ||
691 | ] | ||
692 | }, | ||
693 | { fields: [ 'duration' ] }, | ||
694 | { fields: [ 'views' ] }, | ||
695 | { fields: [ 'channelId' ] }, | ||
696 | { | ||
697 | fields: [ 'originallyPublishedAt' ], | ||
698 | where: { | ||
699 | originallyPublishedAt: { | ||
700 | [Op.ne]: null | ||
701 | } | ||
702 | } | ||
703 | }, | ||
704 | { | ||
705 | fields: [ 'category' ], // We don't care videos with an unknown category | ||
706 | where: { | ||
707 | category: { | ||
708 | [Op.ne]: null | ||
709 | } | ||
710 | } | ||
711 | }, | ||
712 | { | ||
713 | fields: [ 'licence' ], // We don't care videos with an unknown licence | ||
714 | where: { | ||
715 | licence: { | ||
716 | [Op.ne]: null | ||
717 | } | ||
718 | } | ||
719 | }, | ||
720 | { | ||
721 | fields: [ 'language' ], // We don't care videos with an unknown language | ||
722 | where: { | ||
723 | language: { | ||
724 | [Op.ne]: null | ||
725 | } | ||
726 | } | ||
727 | }, | ||
728 | { | ||
729 | fields: [ 'nsfw' ], // Most of the videos are not NSFW | ||
730 | where: { | ||
731 | nsfw: true | ||
732 | } | ||
733 | }, | ||
734 | { | ||
735 | fields: [ 'remote' ], // Only index local videos | ||
736 | where: { | ||
737 | remote: false | ||
738 | } | ||
739 | }, | ||
740 | { | ||
741 | fields: [ 'uuid' ], | ||
742 | unique: true | ||
743 | }, | ||
744 | { | ||
745 | fields: [ 'url' ], | ||
746 | unique: true | ||
747 | } | ||
748 | ] | ||
764 | }) | 749 | }) |
765 | export class VideoModel extends Model<VideoModel> { | 750 | export class VideoModel extends Model<VideoModel> { |
766 | 751 | ||