import * as api from '../../client/src/api'; import { EndpointError, EndpointHandler, catchUnhandledErrors } from './types'; import Knex from 'knex'; export const MergeTagEndpointHandler: EndpointHandler = async (req: any, res: any, knex: Knex) => { if (!api.checkMergeTagRequest(req)) { const e: EndpointError = { internalMessage: 'Invalid MergeTag request: ' + JSON.stringify(req.body), httpStatus: 400 }; throw e; } const reqObject: api.DeleteTagRequest = req.body; const { id: userId } = req.user; console.log("User ", userId, ": Merge Tag ", reqObject); const fromId = req.params.id; const toId = req.params.toId; await knex.transaction(async (trx) => { try { // Start retrieving the "from" tag. const fromTagPromise = trx.select('id') .from('tags') .where({ 'user': userId }) .where({ id: fromId }) .then((r: any) => (r && r[0]) ? r[0]['id'] : undefined) // Start retrieving the "to" tag. const toTagPromise = trx.select('id') .from('tags') .where({ 'user': userId }) .where({ id: toId }) .then((r: any) => (r && r[0]) ? r[0]['id'] : undefined) // Wait for the requests to finish. var [fromTag, toTag] = await Promise.all([fromTagPromise, toTagPromise]); // Check that we found all objects we need. if (!fromTag || !toTag) { const e: EndpointError = { internalMessage: 'Source or target tag does not exist for MergeTag request: ' + JSON.stringify(req.body), httpStatus: 400 }; throw e; } // Assign new tag ID to any objects referencing the to-be-merged tag. const cPromise = trx('tags') .where({ 'user': userId }) .where({ 'parentId': fromId }) .update({ 'parentId': toId }); const sPromise = trx('songs_tags') .where({ 'tagId': fromId }) .update({ 'tagId': toId }); const arPromise = trx('artists_tags') .where({ 'tagId': fromId }) .update({ 'tagId': toId }); const alPromise = trx('albums_tags') .where({ 'tagId': fromId }) .update({ 'tagId': toId }); await Promise.all([sPromise, arPromise, alPromise, cPromise]); // Delete the original tag. await trx('tags') .where({ 'user': userId }) .where({ 'id': fromId }) .del(); // Respond to the request. res.status(200).send(); } catch (e) { catchUnhandledErrors(e); trx.rollback(); } }) }