110 lines
5.0 KiB
JavaScript
110 lines
5.0 KiB
JavaScript
const ApiError = require('../errorClass');
|
||
|
||
async function isAuthorExists (authorId) {
|
||
if (!authorId) return false;
|
||
return (await global.database.authors.promiseMode().get({ where : { id : authorId } })).length !== 0;
|
||
}
|
||
|
||
async function isAuthorsExists (authorsId) {
|
||
if (!Array.isArray(authorsId)) return false;
|
||
const authors = (await global.database.authors.promiseMode().get()).map(i => i.id);
|
||
return authorsId.map(authorId => authors.includes(authorId));
|
||
}
|
||
|
||
async function checkSyntaxArgs (req, res) {
|
||
return !!(
|
||
( // Проверка поля author.
|
||
req.query.author === undefined ? true : await isAuthorExists(+req.query.author)
|
||
) &&
|
||
( // Проверка поля authors.
|
||
req.query.authors === undefined ? true : await isAuthorsExists(req.query.authors.split(',').map(i => +i))
|
||
) &&
|
||
( // Проверка поля offset
|
||
req.query.offset === undefined ? true : Number.isInteger(+req.query.offset)
|
||
) &&
|
||
( // Проверка поля count
|
||
req.query.count === undefined ? true : Number.isInteger(+req.query.count)
|
||
) &&
|
||
( // Проверка поля min_date
|
||
req.query.min_date === undefined ? true : Number.isInteger(+req.query.min_date)
|
||
) &&
|
||
( // Проверка поля max_date
|
||
req.query.max_date === undefined ? true : Number.isInteger(+req.query.max_date)
|
||
) &&
|
||
( // Проверка поля q. (Ключевые слова для поиска)
|
||
true // (Проверки нет, query всегда строка, необязательный параметр)
|
||
) &&
|
||
( // Проверка поля searchByAuthor (Флаг для 'q'. 0 - отключить)
|
||
true // (Проверки нет, query всегда строка, необязательный параметр)
|
||
) &&
|
||
( // Проверка поля searchByName (Флаг для 'q'. 0 - отключить)
|
||
true // (Проверки нет, query всегда строка, необязательный параметр)
|
||
)
|
||
)
|
||
}
|
||
|
||
module.exports = async (req, res) => {
|
||
if (req.method !== 'GET') {
|
||
throw new ApiError("METHOD_MUST_BE_GET", {
|
||
request_method : req.method
|
||
});
|
||
}
|
||
if (!await checkSyntaxArgs(req, res)) {
|
||
throw new ApiError("INVALID_OR_UNSYNTAX_PARAMS", {
|
||
request_method : req.method,
|
||
params : {
|
||
author : req.query?.author === undefined ? null : req.query.author,
|
||
authors : req.query?.authors === undefined ? null : req.query.authors,
|
||
q : req.query?.q === undefined ? null : req.query.q,
|
||
offset : req.query?.offset === undefined ? null : req.query.offset,
|
||
count : req.query?.count === undefined ? null : req.query.count,
|
||
searchByAuthor : req.query?.searchByAuthor === undefined ? null : req.query.searchByAuthor,
|
||
searchByName : req.query?.searchByName === undefined ? null : req.query.searchByName,
|
||
min_date : req.query?.min_date === undefined ? null : req.query.min_date,
|
||
max_date : req.query?.max_date === undefined ? null : req.query.max_date
|
||
}
|
||
});
|
||
}
|
||
|
||
// Оптимизация: флаг searchByAuthor выставится на 0, если была запрошена выборка по музыке определённого автора
|
||
// Тем самым, мы ускоряем время ответа, поскольку мы не перебираем массив searchedAuthors с целью поиска совпадений
|
||
let searchByAuthor = req.query.author === undefined ? req.query.searchByAuthor : '0';
|
||
|
||
const offset = req.query.offset === undefined ? 0 : +req.query.offset;
|
||
const countFromNull = req.query.count === undefined ? undefined : offset + (+req.query.count);
|
||
|
||
let result = (await global.database.muzic.promiseMode().get(req.query?.author === undefined
|
||
? {} : { where: {
|
||
author_id : +req.query.author
|
||
}})).map(i => ({ id : i.id, name : i.name, author_id : i.author_id, is_data_exists : i.data !== null, date : i.time }));
|
||
// Если просят выборку по authors
|
||
if (req.query.authors) {
|
||
let authors = req.query.authors.split(',').map(author => +author);
|
||
result = result.filter(res => authors.includes(res.author_id));
|
||
}
|
||
// Если просят выборку по времени
|
||
if (req.query.min_date || req.query.max_date) {
|
||
const minDate = req.query.min_date === undefined ? 0 : +req.query.min_date;
|
||
const maxDate = req.query.max_date === undefined ? 1e+32 : +req.query.max_date;
|
||
|
||
result = result.filter((res) => minDate <= res.date && res.date <= maxDate);
|
||
}
|
||
|
||
if (req.query?.q !== undefined) {
|
||
let authors = await global.database.authors.promiseMode().get();
|
||
let searchedAuthors = result.map(i => {
|
||
let author_id = i.author_id;
|
||
return authors.filter(a => a.id === author_id)[0];
|
||
});
|
||
result = result.filter(i => {
|
||
const search = req.query.q.toLowerCase();
|
||
return (req.query.searchByName !== '0' && i.name.toLowerCase().includes(search)) ||
|
||
!!(searchByAuthor !== '0' && searchedAuthors.filter(a => a.id === i.author_id)[0]?.name.toLowerCase().includes(search));
|
||
});
|
||
}
|
||
result = result.slice(offset, countFromNull);
|
||
return {
|
||
count : result.length,
|
||
items : result
|
||
};
|
||
} |