You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
4.0 KiB
108 lines
4.0 KiB
import * as api from '../../client/src/api'; |
|
import { EndpointError, EndpointHandler, catchUnhandledErrors } from './types'; |
|
import Knex from 'knex'; |
|
|
|
export const ModifyArtistEndpointHandler: EndpointHandler = async (req: any, res: any, knex: Knex) => { |
|
if (!api.checkModifyArtistRequest(req)) { |
|
const e: EndpointError = { |
|
internalMessage: 'Invalid ModifyArtist request: ' + JSON.stringify(req.body), |
|
httpStatus: 400 |
|
}; |
|
throw e; |
|
} |
|
const reqObject: api.ModifyArtistRequest = req.body; |
|
const { id: userId } = req.user; |
|
|
|
console.log("User ", userId, ": Modify Artist ", reqObject); |
|
|
|
await knex.transaction(async (trx) => { |
|
try { |
|
const artistId = parseInt(req.params.id); |
|
|
|
// Start retrieving the artist itself. |
|
const artistPromise = trx.select('id') |
|
.from('artists') |
|
.where({ 'user': userId }) |
|
.where({ id: artistId }) |
|
.then((r: any) => (r && r[0]) ? r[0]['id'] : undefined) |
|
|
|
// Start retrieving tags. |
|
const tagIdsPromise = reqObject.tagIds ? |
|
trx.select('id') |
|
.from('artists_tags') |
|
.whereIn('id', reqObject.tagIds) |
|
.then((ts: any) => ts.map((t: any) => t['tagId'])) : |
|
(async () => { return undefined })(); |
|
|
|
// Wait for the requests to finish. |
|
var [artist, tags] = await Promise.all([artistPromise, tagIdsPromise]);; |
|
|
|
// Check that we found all objects we need. |
|
if ((reqObject.tagIds && tags.length !== reqObject.tagIds.length) || |
|
!artist) { |
|
const e: EndpointError = { |
|
internalMessage: 'Not all artists and/or tags exist for ModifyArtist request: ' + JSON.stringify(req.body), |
|
httpStatus: 400 |
|
}; |
|
throw e; |
|
} |
|
|
|
// Modify the artist. |
|
var update: any = {}; |
|
if ("name" in reqObject) { update["name"] = reqObject.name; } |
|
if ("storeLinks" in reqObject) { update["storeLinks"] = JSON.stringify(reqObject.storeLinks || []); } |
|
const modifyArtistPromise = trx('artists') |
|
.where({ 'user': userId }) |
|
.where({ 'id': artistId }) |
|
.update(update) |
|
|
|
// Remove unlinked tags. |
|
// TODO: test this! |
|
const removeUnlinkedTags = tags ? |
|
trx('artists_tags') |
|
.where({ 'artistId': artistId }) |
|
.whereNotIn('tagId', reqObject.tagIds || []) |
|
.delete() : |
|
undefined; |
|
|
|
// Link new tags. |
|
// TODO: test this! |
|
const addTags = tags ? trx('artists_tags') |
|
.where({ 'artistId': artistId }) |
|
.then((ts: any) => ts.map((t: any) => t['tagId'])) |
|
.then((doneTagIds: number[]) => { |
|
// Get the set of tags that are not yet linked |
|
const toLink = tags.filter((id: number) => { |
|
return !doneTagIds.includes(id); |
|
}); |
|
const insertObjects = toLink.map((tagId: number) => { |
|
return { |
|
tagId: tagId, |
|
artistId: artistId, |
|
} |
|
}) |
|
|
|
// Link them |
|
return Promise.all( |
|
insertObjects.map((obj: any) => |
|
trx('artists_tags').insert(obj) |
|
) |
|
); |
|
}) : undefined; |
|
|
|
// Wait for all operations to finish. |
|
await Promise.all([ |
|
modifyArtistPromise, |
|
removeUnlinkedTags, |
|
addTags |
|
]); |
|
|
|
// Respond to the request. |
|
res.status(200).send(); |
|
|
|
} catch (e) { |
|
catchUnhandledErrors(e); |
|
trx.rollback(); |
|
} |
|
}) |
|
} |