diff options
author | Chocobozzz <me@florianbigard.com> | 2021-06-10 16:57:13 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2021-06-11 09:31:59 +0200 |
commit | 1d43c3a613c72d69f7360fee9e5bfe6f662d62f7 (patch) | |
tree | d4ba891ffdb1182e39620c06feff1503365d66b5 /server/models/video/sql/video-model-get-query-builder.ts | |
parent | d9bf974f5df787bbeaab5b04949ca91a2b3ca2a3 (diff) | |
download | PeerTube-1d43c3a613c72d69f7360fee9e5bfe6f662d62f7.tar.gz PeerTube-1d43c3a613c72d69f7360fee9e5bfe6f662d62f7.tar.zst PeerTube-1d43c3a613c72d69f7360fee9e5bfe6f662d62f7.zip |
Use separate queries for video files
Diffstat (limited to 'server/models/video/sql/video-model-get-query-builder.ts')
-rw-r--r-- | server/models/video/sql/video-model-get-query-builder.ts | 87 |
1 files changed, 54 insertions, 33 deletions
diff --git a/server/models/video/sql/video-model-get-query-builder.ts b/server/models/video/sql/video-model-get-query-builder.ts index 0a3723e63..1a921d802 100644 --- a/server/models/video/sql/video-model-get-query-builder.ts +++ b/server/models/video/sql/video-model-get-query-builder.ts | |||
@@ -1,6 +1,14 @@ | |||
1 | import { Sequelize, Transaction } from 'sequelize' | 1 | import { Sequelize, Transaction } from 'sequelize' |
2 | import validator from 'validator' | ||
3 | import { AbstractVideosModelQueryBuilder } from './shared/abstract-videos-model-query-builder' | 2 | import { AbstractVideosModelQueryBuilder } from './shared/abstract-videos-model-query-builder' |
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 | */ | ||
4 | 12 | ||
5 | export type BuildVideoGetQueryOptions = { | 13 | export type BuildVideoGetQueryOptions = { |
6 | id: number | string | 14 | id: number | string |
@@ -9,31 +17,57 @@ export type BuildVideoGetQueryOptions = { | |||
9 | forGetAPI?: boolean | 17 | forGetAPI?: boolean |
10 | } | 18 | } |
11 | 19 | ||
12 | export class VideosModelGetQueryBuilder extends AbstractVideosModelQueryBuilder { | 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 { | ||
13 | protected attributes: { [key: string]: string } | 54 | protected attributes: { [key: string]: string } |
14 | protected joins: string[] = [] | 55 | protected joins: string[] = [] |
15 | protected where: string | 56 | |
57 | protected webtorrentFilesQuery: string | ||
58 | protected streamingPlaylistFilesQuery: string | ||
16 | 59 | ||
17 | constructor (protected readonly sequelize: Sequelize) { | 60 | constructor (protected readonly sequelize: Sequelize) { |
18 | super('get') | 61 | super('get') |
19 | } | 62 | } |
20 | 63 | ||
21 | queryVideos (options: BuildVideoGetQueryOptions) { | 64 | queryVideos (options: BuildVideoGetQueryOptions) { |
22 | this.buildGetQuery(options) | 65 | this.buildMainGetQuery(options) |
23 | |||
24 | return this.runQuery(options.transaction, true).then(rows => { | ||
25 | const videos = this.videoModelBuilder.buildVideosFromRows(rows) | ||
26 | |||
27 | if (videos.length > 1) { | ||
28 | throw new Error('Video results is more than ') | ||
29 | } | ||
30 | 66 | ||
31 | if (videos.length === 0) return null | 67 | return this.runQuery(options.transaction, true) |
32 | return videos[0] | ||
33 | }) | ||
34 | } | 68 | } |
35 | 69 | ||
36 | private buildGetQuery (options: BuildVideoGetQueryOptions) { | 70 | private buildMainGetQuery (options: BuildVideoGetQueryOptions) { |
37 | this.attributes = { | 71 | this.attributes = { |
38 | '"video".*': '' | 72 | '"video".*': '' |
39 | } | 73 | } |
@@ -45,8 +79,6 @@ export class VideosModelGetQueryBuilder extends AbstractVideosModelQueryBuilder | |||
45 | 79 | ||
46 | this.includeThumbnails() | 80 | this.includeThumbnails() |
47 | 81 | ||
48 | this.includeFiles() | ||
49 | |||
50 | this.includeBlacklisted() | 82 | this.includeBlacklisted() |
51 | 83 | ||
52 | this.includeScheduleUpdate() | 84 | this.includeScheduleUpdate() |
@@ -59,28 +91,17 @@ export class VideosModelGetQueryBuilder extends AbstractVideosModelQueryBuilder | |||
59 | 91 | ||
60 | if (options.forGetAPI === true) { | 92 | if (options.forGetAPI === true) { |
61 | this.includeTrackers() | 93 | this.includeTrackers() |
62 | this.includeRedundancies() | ||
63 | } | 94 | } |
64 | 95 | ||
65 | this.whereId(options.id) | 96 | this.whereId(options.id) |
66 | 97 | ||
67 | const select = this.buildSelect() | 98 | this.query = this.buildQuery() |
68 | const order = this.buildOrder() | ||
69 | |||
70 | this.query = `${select} FROM "video" ${this.joins.join(' ')} ${this.where} ${order}` | ||
71 | } | 99 | } |
72 | 100 | ||
73 | private whereId (id: string | number) { | 101 | private buildQuery () { |
74 | if (validator.isInt('' + id)) { | 102 | const order = 'ORDER BY "Tags"."name" ASC' |
75 | this.where = 'WHERE "video".id = :videoId' | 103 | const from = `SELECT * FROM "video" ${this.where} LIMIT 1` |
76 | } else { | ||
77 | this.where = 'WHERE uuid = :videoId' | ||
78 | } | ||
79 | |||
80 | this.replacements.videoId = id | ||
81 | } | ||
82 | 104 | ||
83 | private buildOrder () { | 105 | return `${this.buildSelect()} FROM (${from}) AS "video" ${this.joins.join(' ')} ${this.where} ${order}` |
84 | return 'ORDER BY "Tags"."name" ASC' | ||
85 | } | 106 | } |
86 | } | 107 | } |