X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Fmodels%2Futils.ts;h=50c865e758de9f5113a66a5f5554a83b55618d68;hb=7ad9b9846c44d198a736183fb186c2039f5236b5;hp=1606453e0e45212e04cf9591dc119415ea0f1816;hpb=3fd3ab2d34d512b160a5e6084d7609be7b4f4452;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/models/utils.ts b/server/models/utils.ts index 1606453e0..50c865e75 100644 --- a/server/models/utils.ts +++ b/server/models/utils.ts @@ -1,24 +1,42 @@ -// Translate for example "-name" to [ 'name', 'DESC' ] -function getSort (value: string) { - let field: string - let direction: 'ASC' | 'DESC' +import { Sequelize } from 'sequelize-typescript' - if (value.substring(0, 1) === '-') { - direction = 'DESC' - field = value.substring(1) - } else { - direction = 'ASC' - field = value +type SortType = { sortModel: any, sortValue: string } + +// Translate for example "-name" to [ [ 'name', 'DESC' ], [ 'id', 'ASC' ] ] +function getSort (value: string, lastSort: string[] = [ 'id', 'ASC' ]) { + let { direction, field } = buildDirectionAndField(value) + + if (field.toLowerCase() === 'match') { // Search + field = Sequelize.col('similarity') } - return [ field, direction ] + return [ [ field, direction ], lastSort ] } -function getSortOnModel (model: any, value: string) { - let sort = getSort(value) +function getVideoSort (value: string, lastSort: string[] = [ 'id', 'ASC' ]) { + let { direction, field } = buildDirectionAndField(value) - if (model) return [ model, sort[0], sort[1] ] - return sort + // Alias + if (field.toLowerCase() === 'match') { // Search + field = Sequelize.col('similarity') + } else if (field.toLowerCase() === 'trending') { // Sort by aggregation + return [ + [ Sequelize.fn('COALESCE', Sequelize.fn('SUM', Sequelize.col('VideoViews.views')), '0'), direction ], + + [ Sequelize.col('VideoModel.views'), direction ], + + lastSort + ] + } + + return [ [ field, direction ], lastSort ] +} + +function getSortOnModel (model: any, value: string, lastSort: string[] = [ 'id', 'ASC' ]) { + let [ firstSort ] = getSort(value) + + if (model) return [ [ model, firstSort[0], firstSort[1] ], lastSort ] + return [ firstSort, lastSort ] } function throwIfNotValid (value: any, validator: (value: any) => boolean, fieldName = 'value') { @@ -27,10 +45,76 @@ function throwIfNotValid (value: any, validator: (value: any) => boolean, fieldN } } +function buildTrigramSearchIndex (indexName: string, attribute: string) { + return { + name: indexName, + fields: [ Sequelize.literal('lower(immutable_unaccent(' + attribute + '))') as any ], + using: 'gin', + operator: 'gin_trgm_ops' + } +} + +function createSimilarityAttribute (col: string, value: string) { + return Sequelize.fn( + 'similarity', + + searchTrigramNormalizeCol(col), + + searchTrigramNormalizeValue(value) + ) +} + +function buildBlockedAccountSQL (serverAccountId: number, userAccountId?: number) { + const blockerIds = [ serverAccountId ] + if (userAccountId) blockerIds.push(userAccountId) + + const blockerIdsString = blockerIds.join(', ') + + const query = 'SELECT "targetAccountId" AS "id" FROM "accountBlocklist" WHERE "accountId" IN (' + blockerIdsString + ')' + + ' UNION ALL ' + + // 'SELECT "accountId" FROM "accountBlocklist" WHERE "targetAccountId" = user.account.id + // UNION ALL + 'SELECT "account"."id" AS "id" FROM account INNER JOIN "actor" ON account."actorId" = actor.id ' + + 'INNER JOIN "serverBlocklist" ON "actor"."serverId" = "serverBlocklist"."targetServerId" ' + + 'WHERE "serverBlocklist"."accountId" IN (' + blockerIdsString + ')' + + return query +} + // --------------------------------------------------------------------------- export { + buildBlockedAccountSQL, + SortType, getSort, + getVideoSort, getSortOnModel, - throwIfNotValid + createSimilarityAttribute, + throwIfNotValid, + buildTrigramSearchIndex +} + +// --------------------------------------------------------------------------- + +function searchTrigramNormalizeValue (value: string) { + return Sequelize.fn('lower', Sequelize.fn('immutable_unaccent', value)) +} + +function searchTrigramNormalizeCol (col: string) { + return Sequelize.fn('lower', Sequelize.fn('immutable_unaccent', Sequelize.col(col))) +} + +function buildDirectionAndField (value: string) { + let field: any + let direction: 'ASC' | 'DESC' + + if (value.substring(0, 1) === '-') { + direction = 'DESC' + field = value.substring(1) + } else { + direction = 'ASC' + field = value + } + + return { direction, field } }