Cleanup video API SQL requests

This commit is contained in:
Chocobozzz 2018-08-31 11:44:48 +02:00
parent 288fe38590
commit b6314e3cee
No known key found for this signature in database
GPG Key ID: 583A612D890159BE

View File

@ -222,9 +222,13 @@ type AvailableForListIDsOptions = {
attributes: [ 'id' ], attributes: [ 'id' ],
where: { where: {
id: { id: {
[Sequelize.Op.notIn]: Sequelize.literal( [Sequelize.Op.and]: [
'(SELECT "videoBlacklist"."videoId" FROM "videoBlacklist")' {
) [ Sequelize.Op.notIn ]: Sequelize.literal(
'(SELECT "videoBlacklist"."videoId" FROM "videoBlacklist")'
)
}
]
}, },
// Always list public videos // Always list public videos
privacy: VideoPrivacy.PUBLIC, privacy: VideoPrivacy.PUBLIC,
@ -298,27 +302,30 @@ type AvailableForListIDsOptions = {
// Force actorId to be a number to avoid SQL injections // Force actorId to be a number to avoid SQL injections
const actorIdNumber = parseInt(options.actorId.toString(), 10) const actorIdNumber = parseInt(options.actorId.toString(), 10)
query.where['id'][ Sequelize.Op.in ] = Sequelize.literal( query.where['id'][Sequelize.Op.and].push({
'(' + [ Sequelize.Op.in ]: Sequelize.literal(
'SELECT "videoShare"."videoId" AS "id" FROM "videoShare" ' + '(' +
'INNER JOIN "actorFollow" ON "actorFollow"."targetActorId" = "videoShare"."actorId" ' + 'SELECT "videoShare"."videoId" AS "id" FROM "videoShare" ' +
'WHERE "actorFollow"."actorId" = ' + actorIdNumber + 'INNER JOIN "actorFollow" ON "actorFollow"."targetActorId" = "videoShare"."actorId" ' +
' UNION ALL ' + 'WHERE "actorFollow"."actorId" = ' + actorIdNumber +
'SELECT "video"."id" AS "id" FROM "video" ' + ' UNION ALL ' +
'INNER JOIN "videoChannel" ON "videoChannel"."id" = "video"."channelId" ' + 'SELECT "video"."id" AS "id" FROM "video" ' +
'INNER JOIN "account" ON "account"."id" = "videoChannel"."accountId" ' + 'INNER JOIN "videoChannel" ON "videoChannel"."id" = "video"."channelId" ' +
'INNER JOIN "actor" ON "account"."actorId" = "actor"."id" ' + 'INNER JOIN "account" ON "account"."id" = "videoChannel"."accountId" ' +
'INNER JOIN "actorFollow" ON "actorFollow"."targetActorId" = "actor"."id" ' + 'INNER JOIN "actor" ON "account"."actorId" = "actor"."id" ' +
'WHERE "actorFollow"."actorId" = ' + actorIdNumber + 'INNER JOIN "actorFollow" ON "actorFollow"."targetActorId" = "actor"."id" ' +
localVideosReq + 'WHERE "actorFollow"."actorId" = ' + actorIdNumber +
')' localVideosReq +
) ')'
)
})
} }
if (options.withFiles === true) { if (options.withFiles === true) {
query.include.push({ query.where['id'][Sequelize.Op.and].push({
model: VideoFileModel.unscoped(), [ Sequelize.Op.in ]: Sequelize.literal(
required: true '(SELECT "videoId" FROM "videoFile")'
)
}) })
} }
@ -330,24 +337,28 @@ type AvailableForListIDsOptions = {
} }
if (options.tagsOneOf) { if (options.tagsOneOf) {
query.where['id'][Sequelize.Op.in] = Sequelize.literal( query.where['id'][Sequelize.Op.and].push({
'(' + [Sequelize.Op.in]: Sequelize.literal(
'(' +
'SELECT "videoId" FROM "videoTag" ' + 'SELECT "videoId" FROM "videoTag" ' +
'INNER JOIN "tag" ON "tag"."id" = "videoTag"."tagId" ' + 'INNER JOIN "tag" ON "tag"."id" = "videoTag"."tagId" ' +
'WHERE "tag"."name" IN (' + createTagsIn(options.tagsOneOf) + ')' + 'WHERE "tag"."name" IN (' + createTagsIn(options.tagsOneOf) + ')' +
')' ')'
) )
})
} }
if (options.tagsAllOf) { if (options.tagsAllOf) {
query.where['id'][Sequelize.Op.in] = Sequelize.literal( query.where['id'][Sequelize.Op.and].push({
[Sequelize.Op.in]: Sequelize.literal(
'(' + '(' +
'SELECT "videoId" FROM "videoTag" ' + 'SELECT "videoId" FROM "videoTag" ' +
'INNER JOIN "tag" ON "tag"."id" = "videoTag"."tagId" ' + 'INNER JOIN "tag" ON "tag"."id" = "videoTag"."tagId" ' +
'WHERE "tag"."name" IN (' + createTagsIn(options.tagsAllOf) + ')' + 'WHERE "tag"."name" IN (' + createTagsIn(options.tagsAllOf) + ')' +
'GROUP BY "videoTag"."videoId" HAVING COUNT(*) = ' + options.tagsAllOf.length + 'GROUP BY "videoTag"."videoId" HAVING COUNT(*) = ' + options.tagsAllOf.length +
')' ')'
) )
})
} }
} }
@ -1162,7 +1173,14 @@ export class VideoModel extends Model<VideoModel> {
const apiScope = { const apiScope = {
method: [ ScopeNames.FOR_API, { ids, withFiles: options.withFiles } as ForAPIOptions ] method: [ ScopeNames.FOR_API, { ids, withFiles: options.withFiles } as ForAPIOptions ]
} }
const rows = await VideoModel.scope(apiScope).findAll(immutableAssign(query, { offset: 0 }))
const secondQuery = {
offset: 0,
limit: query.limit,
order: query.order,
attributes: query.attributes
}
const rows = await VideoModel.scope(apiScope).findAll(secondQuery)
return { return {
data: rows, data: rows,