aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models/video/sql
diff options
context:
space:
mode:
Diffstat (limited to 'server/models/video/sql')
-rw-r--r--server/models/video/sql/shared/abstract-run-query.ts26
-rw-r--r--server/models/video/sql/video/index.ts3
-rw-r--r--server/models/video/sql/video/shared/abstract-video-query-builder.ts (renamed from server/models/video/sql/shared/abstract-video-query-builder.ts)27
-rw-r--r--server/models/video/sql/video/shared/video-file-query-builder.ts (renamed from server/models/video/sql/shared/video-file-query-builder.ts)2
-rw-r--r--server/models/video/sql/video/shared/video-model-builder.ts (renamed from server/models/video/sql/shared/video-model-builder.ts)57
-rw-r--r--server/models/video/sql/video/shared/video-table-attributes.ts (renamed from server/models/video/sql/shared/video-table-attributes.ts)6
-rw-r--r--server/models/video/sql/video/video-model-get-query-builder.ts (renamed from server/models/video/sql/video-model-get-query-builder.ts)2
-rw-r--r--server/models/video/sql/video/videos-id-list-query-builder.ts (renamed from server/models/video/sql/videos-id-list-query-builder.ts)4
-rw-r--r--server/models/video/sql/video/videos-model-list-query-builder.ts (renamed from server/models/video/sql/videos-model-list-query-builder.ts)2
9 files changed, 67 insertions, 62 deletions
diff --git a/server/models/video/sql/shared/abstract-run-query.ts b/server/models/video/sql/shared/abstract-run-query.ts
deleted file mode 100644
index 8e7a7642d..000000000
--- a/server/models/video/sql/shared/abstract-run-query.ts
+++ /dev/null
@@ -1,26 +0,0 @@
1import { QueryTypes, Sequelize, Transaction } from 'sequelize'
2
3/**
4 *
5 * Abstact builder to run video SQL queries
6 *
7 */
8
9export class AbstractRunQuery {
10 protected sequelize: Sequelize
11
12 protected query: string
13 protected replacements: any = {}
14
15 protected runQuery (options: { transaction?: Transaction, logging?: boolean } = {}) {
16 const queryOptions = {
17 transaction: options.transaction,
18 logging: options.logging,
19 replacements: this.replacements,
20 type: QueryTypes.SELECT as QueryTypes.SELECT,
21 nest: false
22 }
23
24 return this.sequelize.query<any>(this.query, queryOptions)
25 }
26}
diff --git a/server/models/video/sql/video/index.ts b/server/models/video/sql/video/index.ts
new file mode 100644
index 000000000..e9132d5e1
--- /dev/null
+++ b/server/models/video/sql/video/index.ts
@@ -0,0 +1,3 @@
1export * from './video-model-get-query-builder'
2export * from './videos-id-list-query-builder'
3export * from './videos-model-list-query-builder'
diff --git a/server/models/video/sql/shared/abstract-video-query-builder.ts b/server/models/video/sql/video/shared/abstract-video-query-builder.ts
index a6afb04e4..b79d20ade 100644
--- a/server/models/video/sql/shared/abstract-video-query-builder.ts
+++ b/server/models/video/sql/video/shared/abstract-video-query-builder.ts
@@ -1,7 +1,9 @@
1import { Sequelize } from 'sequelize'
2import validator from 'validator'
1import { createSafeIn } from '@server/models/utils' 3import { createSafeIn } from '@server/models/utils'
2import { MUserAccountId } from '@server/types/models' 4import { MUserAccountId } from '@server/types/models'
3import validator from 'validator' 5import { ActorImageType } from '@shared/models'
4import { AbstractRunQuery } from './abstract-run-query' 6import { AbstractRunQuery } from '../../../../shared/abstract-run-query'
5import { VideoTableAttributes } from './video-table-attributes' 7import { VideoTableAttributes } from './video-table-attributes'
6 8
7/** 9/**
@@ -18,8 +20,11 @@ export class AbstractVideoQueryBuilder extends AbstractRunQuery {
18 20
19 protected tables: VideoTableAttributes 21 protected tables: VideoTableAttributes
20 22
21 constructor (protected readonly mode: 'list' | 'get') { 23 constructor (
22 super() 24 protected readonly sequelize: Sequelize,
25 protected readonly mode: 'list' | 'get'
26 ) {
27 super(sequelize)
23 28
24 this.tables = new VideoTableAttributes(this.mode) 29 this.tables = new VideoTableAttributes(this.mode)
25 } 30 }
@@ -42,8 +47,9 @@ export class AbstractVideoQueryBuilder extends AbstractRunQuery {
42 ) 47 )
43 48
44 this.addJoin( 49 this.addJoin(
45 'LEFT OUTER JOIN "actorImage" AS "VideoChannel->Actor->Avatar" ' + 50 'LEFT OUTER JOIN "actorImage" AS "VideoChannel->Actor->Avatars" ' +
46 'ON "VideoChannel->Actor"."avatarId" = "VideoChannel->Actor->Avatar"."id"' 51 'ON "VideoChannel->Actor"."id" = "VideoChannel->Actor->Avatars"."actorId" ' +
52 `AND "VideoChannel->Actor->Avatars"."type" = ${ActorImageType.AVATAR}`
47 ) 53 )
48 54
49 this.attributes = { 55 this.attributes = {
@@ -51,7 +57,7 @@ export class AbstractVideoQueryBuilder extends AbstractRunQuery {
51 57
52 ...this.buildAttributesObject('VideoChannel', this.tables.getChannelAttributes()), 58 ...this.buildAttributesObject('VideoChannel', this.tables.getChannelAttributes()),
53 ...this.buildActorInclude('VideoChannel->Actor'), 59 ...this.buildActorInclude('VideoChannel->Actor'),
54 ...this.buildAvatarInclude('VideoChannel->Actor->Avatar'), 60 ...this.buildAvatarInclude('VideoChannel->Actor->Avatars'),
55 ...this.buildServerInclude('VideoChannel->Actor->Server') 61 ...this.buildServerInclude('VideoChannel->Actor->Server')
56 } 62 }
57 } 63 }
@@ -68,8 +74,9 @@ export class AbstractVideoQueryBuilder extends AbstractRunQuery {
68 ) 74 )
69 75
70 this.addJoin( 76 this.addJoin(
71 'LEFT OUTER JOIN "actorImage" AS "VideoChannel->Account->Actor->Avatar" ' + 77 'LEFT OUTER JOIN "actorImage" AS "VideoChannel->Account->Actor->Avatars" ' +
72 'ON "VideoChannel->Account->Actor"."avatarId" = "VideoChannel->Account->Actor->Avatar"."id"' 78 'ON "VideoChannel->Account"."actorId"= "VideoChannel->Account->Actor->Avatars"."actorId" ' +
79 `AND "VideoChannel->Account->Actor->Avatars"."type" = ${ActorImageType.AVATAR}`
73 ) 80 )
74 81
75 this.attributes = { 82 this.attributes = {
@@ -77,7 +84,7 @@ export class AbstractVideoQueryBuilder extends AbstractRunQuery {
77 84
78 ...this.buildAttributesObject('VideoChannel->Account', this.tables.getAccountAttributes()), 85 ...this.buildAttributesObject('VideoChannel->Account', this.tables.getAccountAttributes()),
79 ...this.buildActorInclude('VideoChannel->Account->Actor'), 86 ...this.buildActorInclude('VideoChannel->Account->Actor'),
80 ...this.buildAvatarInclude('VideoChannel->Account->Actor->Avatar'), 87 ...this.buildAvatarInclude('VideoChannel->Account->Actor->Avatars'),
81 ...this.buildServerInclude('VideoChannel->Account->Actor->Server') 88 ...this.buildServerInclude('VideoChannel->Account->Actor->Server')
82 } 89 }
83 } 90 }
diff --git a/server/models/video/sql/shared/video-file-query-builder.ts b/server/models/video/sql/video/shared/video-file-query-builder.ts
index 3eb3dc07d..50c12f627 100644
--- a/server/models/video/sql/shared/video-file-query-builder.ts
+++ b/server/models/video/sql/video/shared/video-file-query-builder.ts
@@ -12,7 +12,7 @@ export class VideoFileQueryBuilder extends AbstractVideoQueryBuilder {
12 protected attributes: { [key: string]: string } 12 protected attributes: { [key: string]: string }
13 13
14 constructor (protected readonly sequelize: Sequelize) { 14 constructor (protected readonly sequelize: Sequelize) {
15 super('get') 15 super(sequelize, 'get')
16 } 16 }
17 17
18 queryWebTorrentVideos (options: BuildVideoGetQueryOptions) { 18 queryWebTorrentVideos (options: BuildVideoGetQueryOptions) {
diff --git a/server/models/video/sql/shared/video-model-builder.ts b/server/models/video/sql/video/shared/video-model-builder.ts
index 7751d8e68..0a2beb7db 100644
--- a/server/models/video/sql/shared/video-model-builder.ts
+++ b/server/models/video/sql/video/shared/video-model-builder.ts
@@ -9,15 +9,15 @@ import { ServerBlocklistModel } from '@server/models/server/server-blocklist'
9import { TrackerModel } from '@server/models/server/tracker' 9import { TrackerModel } from '@server/models/server/tracker'
10import { UserVideoHistoryModel } from '@server/models/user/user-video-history' 10import { UserVideoHistoryModel } from '@server/models/user/user-video-history'
11import { VideoInclude } from '@shared/models' 11import { VideoInclude } from '@shared/models'
12import { ScheduleVideoUpdateModel } from '../../schedule-video-update' 12import { ScheduleVideoUpdateModel } from '../../../schedule-video-update'
13import { TagModel } from '../../tag' 13import { TagModel } from '../../../tag'
14import { ThumbnailModel } from '../../thumbnail' 14import { ThumbnailModel } from '../../../thumbnail'
15import { VideoModel } from '../../video' 15import { VideoModel } from '../../../video'
16import { VideoBlacklistModel } from '../../video-blacklist' 16import { VideoBlacklistModel } from '../../../video-blacklist'
17import { VideoChannelModel } from '../../video-channel' 17import { VideoChannelModel } from '../../../video-channel'
18import { VideoFileModel } from '../../video-file' 18import { VideoFileModel } from '../../../video-file'
19import { VideoLiveModel } from '../../video-live' 19import { VideoLiveModel } from '../../../video-live'
20import { VideoStreamingPlaylistModel } from '../../video-streaming-playlist' 20import { VideoStreamingPlaylistModel } from '../../../video-streaming-playlist'
21import { VideoTableAttributes } from './video-table-attributes' 21import { VideoTableAttributes } from './video-table-attributes'
22 22
23type SQLRow = { [id: string]: string | number } 23type SQLRow = { [id: string]: string | number }
@@ -34,6 +34,7 @@ export class VideoModelBuilder {
34 private videoFileMemo: { [ id: number ]: VideoFileModel } 34 private videoFileMemo: { [ id: number ]: VideoFileModel }
35 35
36 private thumbnailsDone: Set<any> 36 private thumbnailsDone: Set<any>
37 private actorImagesDone: Set<any>
37 private historyDone: Set<any> 38 private historyDone: Set<any>
38 private blacklistDone: Set<any> 39 private blacklistDone: Set<any>
39 private accountBlocklistDone: Set<any> 40 private accountBlocklistDone: Set<any>
@@ -50,8 +51,8 @@ export class VideoModelBuilder {
50 private readonly buildOpts = { raw: true, isNewRecord: false } 51 private readonly buildOpts = { raw: true, isNewRecord: false }
51 52
52 constructor ( 53 constructor (
53 readonly mode: 'get' | 'list', 54 private readonly mode: 'get' | 'list',
54 readonly tables: VideoTableAttributes 55 private readonly tables: VideoTableAttributes
55 ) { 56 ) {
56 57
57 } 58 }
@@ -69,11 +70,21 @@ export class VideoModelBuilder {
69 for (const row of rows) { 70 for (const row of rows) {
70 this.buildVideoAndAccount(row) 71 this.buildVideoAndAccount(row)
71 72
72 const videoModel = this.videosMemo[row.id] 73 const videoModel = this.videosMemo[row.id as number]
73 74
74 this.setUserHistory(row, videoModel) 75 this.setUserHistory(row, videoModel)
75 this.addThumbnail(row, videoModel) 76 this.addThumbnail(row, videoModel)
76 77
78 const channelActor = videoModel.VideoChannel?.Actor
79 if (channelActor) {
80 this.addActorAvatar(row, 'VideoChannel.Actor', channelActor)
81 }
82
83 const accountActor = videoModel.VideoChannel?.Account?.Actor
84 if (accountActor) {
85 this.addActorAvatar(row, 'VideoChannel.Account.Actor', accountActor)
86 }
87
77 if (!rowsWebTorrentFiles) { 88 if (!rowsWebTorrentFiles) {
78 this.addWebTorrentFile(row, videoModel) 89 this.addWebTorrentFile(row, videoModel)
79 } 90 }
@@ -113,6 +124,7 @@ export class VideoModelBuilder {
113 this.videoFileMemo = {} 124 this.videoFileMemo = {}
114 125
115 this.thumbnailsDone = new Set() 126 this.thumbnailsDone = new Set()
127 this.actorImagesDone = new Set()
116 this.historyDone = new Set() 128 this.historyDone = new Set()
117 this.blacklistDone = new Set() 129 this.blacklistDone = new Set()
118 this.liveDone = new Set() 130 this.liveDone = new Set()
@@ -195,13 +207,8 @@ export class VideoModelBuilder {
195 207
196 private buildActor (row: SQLRow, prefix: string) { 208 private buildActor (row: SQLRow, prefix: string) {
197 const actorPrefix = `${prefix}.Actor` 209 const actorPrefix = `${prefix}.Actor`
198 const avatarPrefix = `${actorPrefix}.Avatar`
199 const serverPrefix = `${actorPrefix}.Server` 210 const serverPrefix = `${actorPrefix}.Server`
200 211
201 const avatarModel = row[`${avatarPrefix}.id`] !== null
202 ? new ActorImageModel(this.grab(row, this.tables.getAvatarAttributes(), avatarPrefix), this.buildOpts)
203 : null
204
205 const serverModel = row[`${serverPrefix}.id`] !== null 212 const serverModel = row[`${serverPrefix}.id`] !== null
206 ? new ServerModel(this.grab(row, this.tables.getServerAttributes(), serverPrefix), this.buildOpts) 213 ? new ServerModel(this.grab(row, this.tables.getServerAttributes(), serverPrefix), this.buildOpts)
207 : null 214 : null
@@ -209,8 +216,8 @@ export class VideoModelBuilder {
209 if (serverModel) serverModel.BlockedBy = [] 216 if (serverModel) serverModel.BlockedBy = []
210 217
211 const actorModel = new ActorModel(this.grab(row, this.tables.getActorAttributes(), actorPrefix), this.buildOpts) 218 const actorModel = new ActorModel(this.grab(row, this.tables.getActorAttributes(), actorPrefix), this.buildOpts)
212 actorModel.Avatar = avatarModel
213 actorModel.Server = serverModel 219 actorModel.Server = serverModel
220 actorModel.Avatars = []
214 221
215 return actorModel 222 return actorModel
216 } 223 }
@@ -226,6 +233,20 @@ export class VideoModelBuilder {
226 this.historyDone.add(id) 233 this.historyDone.add(id)
227 } 234 }
228 235
236 private addActorAvatar (row: SQLRow, actorPrefix: string, actor: ActorModel) {
237 const avatarPrefix = `${actorPrefix}.Avatars`
238 const id = row[`${avatarPrefix}.id`]
239 const key = `${row.id}${id}`
240
241 if (!id || this.actorImagesDone.has(key)) return
242
243 const attributes = this.grab(row, this.tables.getAvatarAttributes(), avatarPrefix)
244 const avatarModel = new ActorImageModel(attributes, this.buildOpts)
245 actor.Avatars.push(avatarModel)
246
247 this.actorImagesDone.add(key)
248 }
249
229 private addThumbnail (row: SQLRow, videoModel: VideoModel) { 250 private addThumbnail (row: SQLRow, videoModel: VideoModel) {
230 const id = row['Thumbnails.id'] 251 const id = row['Thumbnails.id']
231 if (!id || this.thumbnailsDone.has(id)) return 252 if (!id || this.thumbnailsDone.has(id)) return
diff --git a/server/models/video/sql/shared/video-table-attributes.ts b/server/models/video/sql/video/shared/video-table-attributes.ts
index 8a8d2073a..f4d9e99fd 100644
--- a/server/models/video/sql/shared/video-table-attributes.ts
+++ b/server/models/video/sql/video/shared/video-table-attributes.ts
@@ -6,7 +6,7 @@
6 */ 6 */
7export class VideoTableAttributes { 7export class VideoTableAttributes {
8 8
9 constructor (readonly mode: 'get' | 'list') { 9 constructor (private readonly mode: 'get' | 'list') {
10 10
11 } 11 }
12 12
@@ -186,8 +186,7 @@ export class VideoTableAttributes {
186 'id', 186 'id',
187 'preferredUsername', 187 'preferredUsername',
188 'url', 188 'url',
189 'serverId', 189 'serverId'
190 'avatarId'
191 ] 190 ]
192 191
193 if (this.mode === 'get') { 192 if (this.mode === 'get') {
@@ -212,6 +211,7 @@ export class VideoTableAttributes {
212 getAvatarAttributes () { 211 getAvatarAttributes () {
213 let attributeKeys = [ 212 let attributeKeys = [
214 'id', 213 'id',
214 'width',
215 'filename', 215 'filename',
216 'type', 216 'type',
217 'fileUrl', 217 'fileUrl',
diff --git a/server/models/video/sql/video-model-get-query-builder.ts b/server/models/video/sql/video/video-model-get-query-builder.ts
index a65c96097..b0879c9ac 100644
--- a/server/models/video/sql/video-model-get-query-builder.ts
+++ b/server/models/video/sql/video/video-model-get-query-builder.ts
@@ -110,7 +110,7 @@ export class VideosModelGetQuerySubBuilder extends AbstractVideoQueryBuilder {
110 ]) 110 ])
111 111
112 constructor (protected readonly sequelize: Sequelize) { 112 constructor (protected readonly sequelize: Sequelize) {
113 super('get') 113 super(sequelize, 'get')
114 } 114 }
115 115
116 queryVideos (options: BuildVideoGetQueryOptions) { 116 queryVideos (options: BuildVideoGetQueryOptions) {
diff --git a/server/models/video/sql/videos-id-list-query-builder.ts b/server/models/video/sql/video/videos-id-list-query-builder.ts
index 098e15359..19aff631d 100644
--- a/server/models/video/sql/videos-id-list-query-builder.ts
+++ b/server/models/video/sql/video/videos-id-list-query-builder.ts
@@ -5,7 +5,7 @@ import { WEBSERVER } from '@server/initializers/constants'
5import { buildDirectionAndField, createSafeIn } from '@server/models/utils' 5import { buildDirectionAndField, createSafeIn } from '@server/models/utils'
6import { MUserAccountId, MUserId } from '@server/types/models' 6import { MUserAccountId, MUserId } from '@server/types/models'
7import { VideoInclude, VideoPrivacy, VideoState } from '@shared/models' 7import { VideoInclude, VideoPrivacy, VideoState } from '@shared/models'
8import { AbstractRunQuery } from './shared/abstract-run-query' 8import { AbstractRunQuery } from '../../../shared/abstract-run-query'
9 9
10/** 10/**
11 * 11 *
@@ -93,7 +93,7 @@ export class VideosIdListQueryBuilder extends AbstractRunQuery {
93 private offset = '' 93 private offset = ''
94 94
95 constructor (protected readonly sequelize: Sequelize) { 95 constructor (protected readonly sequelize: Sequelize) {
96 super() 96 super(sequelize)
97 } 97 }
98 98
99 queryVideoIds (options: BuildVideosListQueryOptions) { 99 queryVideoIds (options: BuildVideosListQueryOptions) {
diff --git a/server/models/video/sql/videos-model-list-query-builder.ts b/server/models/video/sql/video/videos-model-list-query-builder.ts
index b15b29ec3..2a4afc389 100644
--- a/server/models/video/sql/videos-model-list-query-builder.ts
+++ b/server/models/video/sql/video/videos-model-list-query-builder.ts
@@ -19,7 +19,7 @@ export class VideosModelListQueryBuilder extends AbstractVideoQueryBuilder {
19 private readonly videoModelBuilder: VideoModelBuilder 19 private readonly videoModelBuilder: VideoModelBuilder
20 20
21 constructor (protected readonly sequelize: Sequelize) { 21 constructor (protected readonly sequelize: Sequelize) {
22 super('list') 22 super(sequelize, 'list')
23 23
24 this.videoModelBuilder = new VideoModelBuilder(this.mode, this.tables) 24 this.videoModelBuilder = new VideoModelBuilder(this.mode, this.tables)
25 } 25 }