const { Op } = require("sequelize"); const ApiError = require("../errorClass"); const database = require("../../../database"); const apiTypes = require("../typeChecker"); const router = require('express').Router(); async function checkSyntaxArgs(req, res) { const checker = new apiTypes.TypeChecker(false); await checker.checkAdditional(req.query.id, apiTypes.MusicType, 'id'); await checker.checkAdditional(req.query.author, apiTypes.AuthorType, 'author'); await checker.checkAdditional(req.query.authors, apiTypes.AuthorsType, 'authors'); await checker.checkAdditional(req.query.offset, apiTypes.IntType, 'offset'); await checker.checkAdditional(req.query.count, apiTypes.IntType, 'count'); await checker.checkAdditional(req.query.min_date, apiTypes.IntType, 'min_date'); await checker.checkAdditional(req.query.max_date, apiTypes.IntType, 'max_date'); await checker.checkAdditional(req.query.q, apiTypes.StrType, 'q'); await checker.checkAdditional(req.query.searchByAuthor, apiTypes.StrType, 'searchByAuthor'); await checker.checkAdditional(req.query.searchByName, apiTypes.StrType, 'searchByName'); const result = await checker.calculate(); if (!result.success) { throw new ApiError("UNSYNTAX_PARAMS_OR_MISSED_REQUIRED_PARAMS", result); } } router.get('/get-music', async (req, res, next) => { try { await checkSyntaxArgs(req, res); // Оптимизация: флаг 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; const searchAuthors = !req.query.authors ? [] : [...req.query.authors.split(',').map(i => +i)]; if (req.query.author) searchAuthors.push(+req.query.author); const minDate = req.query.min_date === undefined ? 0 : +req.query.min_date; const maxDate = req.query.max_date === undefined ? 9999999999 : +req.query.max_date; let searchedParams = []; if (searchAuthors > 0) { searchAuthors.forEach(author_id => { console.log(author_id); searchedParams.push({ [Op.and] : [ req.query.id !== undefined ? {id : +req.query.id} : undefined, { author_id }, {time : { [Op.gte]: minDate, [Op.lte]: maxDate, }}, ] }); }); } else { searchedParams.push({ [Op.and] : [ req.query.id !== undefined ? {id : +req.query.id} : undefined, {time : { [Op.gte]: minDate, [Op.lte]: maxDate, }}, ] }); } console.log('searchedParams', searchedParams); let result = ( await database.music.findAll({ where : { [Op.or]: searchedParams }, raws : true }) ).map((i) => ({ id: i.id, name: i.name, author_id: i.author_id, is_data_exists: i.data !== null && i.data.length > 0, date: i.time, })); if (req.query?.q !== undefined) { let authors = await database.authors.findAll({raws : true}); 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); res.result({ count: result.length, items: result, }); } catch (err) { return next(err); } }); router.use('/get-music', async (req, res, next) => { try { return next(new ApiError("METHOD_MUST_BE_GET", { method : 'get-music' })); } catch (err) { return next(err); } }); module.exports = router;