From 8b60488020883c66d3831eacd030893ab184268f Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 28 Aug 2018 18:29:29 +0200 Subject: [PATCH] Refractor user quota SQL queries --- .../custom-validators/activitypub/misc.ts | 4 +- server/helpers/custom-validators/videos.ts | 3 - server/models/account/user.ts | 73 +++++++++---------- server/models/video/video-channel.ts | 2 +- 4 files changed, 37 insertions(+), 45 deletions(-) diff --git a/server/helpers/custom-validators/activitypub/misc.ts b/server/helpers/custom-validators/activitypub/misc.ts index 2dac8e1ad..6c5c7abca 100644 --- a/server/helpers/custom-validators/activitypub/misc.ts +++ b/server/helpers/custom-validators/activitypub/misc.ts @@ -41,12 +41,10 @@ function setValidAttributedTo (obj: any) { return true } - const newAttributesTo = obj.attributedTo.filter(a => { + obj.attributedTo = obj.attributedTo.filter(a => { return (a.type === 'Group' || a.type === 'Person') && isActivityPubUrlValid(a.id) }) - obj.attributedTo = newAttributesTo - return true } diff --git a/server/helpers/custom-validators/videos.ts b/server/helpers/custom-validators/videos.ts index 5e6cfe217..4b1f6c069 100644 --- a/server/helpers/custom-validators/videos.ts +++ b/server/helpers/custom-validators/videos.ts @@ -6,7 +6,6 @@ import * as validator from 'validator' import { UserRight, VideoPrivacy, VideoRateType } from '../../../shared' import { CONSTRAINTS_FIELDS, - VIDEO_ABUSE_STATES, VIDEO_CATEGORIES, VIDEO_LICENCES, VIDEO_MIMETYPE_EXT, @@ -19,10 +18,8 @@ import { exists, isArray, isFileValid } from './misc' import { VideoChannelModel } from '../../models/video/video-channel' import { UserModel } from '../../models/account/user' import * as magnetUtil from 'magnet-uri' -import { VideoAbuseModel } from '../../models/video/video-abuse' const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS -const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES function isVideoCategoryValid (value: any) { return value === null || VIDEO_CATEGORIES[ value ] !== undefined diff --git a/server/models/account/user.ts b/server/models/account/user.ts index a88ec244f..bae683b12 100644 --- a/server/models/account/user.ts +++ b/server/models/account/user.ts @@ -172,8 +172,8 @@ export class UserModel extends Model { [ Sequelize.literal( '(' + - 'SELECT COALESCE(SUM("size"), 0) FROM ' + - '(' + + 'SELECT COALESCE(SUM("size"), 0) ' + + 'FROM (' + 'SELECT MAX("videoFile"."size") AS "size" FROM "videoFile" ' + 'INNER JOIN "video" ON "videoFile"."videoId" = "video"."id" ' + 'INNER JOIN "videoChannel" ON "videoChannel"."id" = "video"."channelId" ' + @@ -267,48 +267,17 @@ export class UserModel extends Model { static getOriginalVideoFileTotalFromUser (user: UserModel) { // Don't use sequelize because we need to use a sub query - const query = 'SELECT SUM("size") AS "total" FROM ' + - '(SELECT MAX("videoFile"."size") AS "size" FROM "videoFile" ' + - 'INNER JOIN "video" ON "videoFile"."videoId" = "video"."id" ' + - 'INNER JOIN "videoChannel" ON "videoChannel"."id" = "video"."channelId" ' + - 'INNER JOIN "account" ON "videoChannel"."accountId" = "account"."id" ' + - 'WHERE "account"."userId" = $userId ' + - 'GROUP BY "video"."id") t' + const query = UserModel.generateUserQuotaBaseSQL() - const options = { - bind: { userId: user.id }, - type: Sequelize.QueryTypes.SELECT - } - return UserModel.sequelize.query(query, options) - .then(([ { total } ]) => { - if (total === null) return 0 - - return parseInt(total, 10) - }) + return UserModel.getTotalRawQuery(query, user.id) } - // Returns comulative size of all video files uploaded in the last 24 hours. + // Returns cumulative size of all video files uploaded in the last 24 hours. static getOriginalVideoFileTotalDailyFromUser (user: UserModel) { // Don't use sequelize because we need to use a sub query - const query = 'SELECT SUM("size") AS "total" FROM ' + - '(SELECT MAX("videoFile"."size") AS "size" FROM "videoFile" ' + - 'INNER JOIN "video" ON "videoFile"."videoId" = "video"."id" ' + - 'INNER JOIN "videoChannel" ON "videoChannel"."id" = "video"."channelId" ' + - 'INNER JOIN "account" ON "videoChannel"."accountId" = "account"."id" ' + - 'WHERE "account"."userId" = $userId ' + - 'AND "video"."createdAt" > now() - interval \'24 hours\'' + - 'GROUP BY "video"."id") t' + const query = UserModel.generateUserQuotaBaseSQL('"video"."createdAt" > now() - interval \'24 hours\'') - const options = { - bind: { userId: user.id }, - type: Sequelize.QueryTypes.SELECT - } - return UserModel.sequelize.query(query, options) - .then(([ { total } ]) => { - if (total === null) return 0 - - return parseInt(total, 10) - }) + return UserModel.getTotalRawQuery(query, user.id) } static async getStats () { @@ -388,4 +357,32 @@ export class UserModel extends Model { return (uploadedTotal < this.videoQuota) && (uploadedDaily < this.videoQuotaDaily) } + + private static generateUserQuotaBaseSQL (where?: string) { + const andWhere = where ? 'AND ' + where : '' + + return 'SELECT SUM("size") AS "total" ' + + 'FROM (' + + 'SELECT MAX("videoFile"."size") AS "size" FROM "videoFile" ' + + 'INNER JOIN "video" ON "videoFile"."videoId" = "video"."id" ' + + 'INNER JOIN "videoChannel" ON "videoChannel"."id" = "video"."channelId" ' + + 'INNER JOIN "account" ON "videoChannel"."accountId" = "account"."id" ' + + 'WHERE "account"."userId" = $userId ' + andWhere + + 'GROUP BY "video"."id"' + + ') t' + } + + private static getTotalRawQuery (query: string, userId: number) { + const options = { + bind: { userId }, + type: Sequelize.QueryTypes.SELECT + } + + return UserModel.sequelize.query(query, options) + .then(([ { total } ]) => { + if (total === null) return 0 + + return parseInt(total, 10) + }) + } } diff --git a/server/models/video/video-channel.ts b/server/models/video/video-channel.ts index e70e52515..475530daf 100644 --- a/server/models/video/video-channel.ts +++ b/server/models/video/video-channel.ts @@ -71,7 +71,7 @@ type AvailableForListOptions = { const inQueryInstanceFollow = '(' + 'SELECT "actor"."serverId" FROM "actorFollow" ' + 'INNER JOIN "actor" ON actor.id= "actorFollow"."targetActorId" ' + - 'WHERE "actor"."id" = ' + actorIdNumber + + 'WHERE "actorFollow"."actorId" = ' + actorIdNumber + ')' return {