'use strict'; const knex = require('./knex'); const slugify = require('./utils/slugify'); const bulkInsert = require('./utils/bulk-insert'); async function matchReleaseTags(releases) { const rawTags = releases .map(release => release.tags).flat() .filter(Boolean); const casedTags = [...new Set( rawTags .concat(rawTags.map(tag => tag.toLowerCase())) .concat(rawTags.map(tag => tag.toUpperCase())), )]; const tagEntries = await knex('tags') .select('tags.id', 'tags.name', 'tags.alias_for') .whereIn('tags.name', casedTags); const tagIdsBySlug = tagEntries .reduce((acc, tag) => ({ ...acc, [slugify(tag.name)]: tag.alias_for || tag.id, }), {}); return tagIdsBySlug; } async function getEntityTags(releases) { const entityIds = releases.map(release => release.entity?.id).filter(Boolean); const entityTags = await knex('entities_tags').whereIn('entity_id', entityIds); const entityTagIdsByEntityId = entityTags.reduce((acc, entityTag) => { if (!acc[entityTag.entity_id]) { acc[entityTag.entity_id] = []; } acc[entityTag.entity_id].push(entityTag.tag_id); return acc; }, {}); return entityTagIdsByEntityId; } function buildReleaseTagAssociations(releases, tagIdsBySlug, entityTagIdsByEntityId, type) { const tagAssociations = releases .map((release) => { const entityTagIds = entityTagIdsByEntityId[release.entity?.id] || []; const releaseTags = release.tags || []; const releaseTagIds = releaseTags.every(tag => typeof tag === 'number') ? releaseTags // obsolete scraper returned pre-matched tags : releaseTags.map(tag => tagIdsBySlug[slugify(tag)]); const tags = [...new Set( // filter duplicates and empties releaseTagIds .concat(entityTagIds) .filter(Boolean), )] .map(tagId => ({ [`${type}_id`]: release.id, tag_id: tagId, })); return tags; }) .flat(); return tagAssociations; } async function associateReleaseTags(releases, type = 'release') { const tagIdsBySlug = await matchReleaseTags(releases); const EntityTagIdsByEntityId = await getEntityTags(releases); const tagAssociations = buildReleaseTagAssociations(releases, tagIdsBySlug, EntityTagIdsByEntityId, type); await bulkInsert(`${type}s_tags`, tagAssociations, false); } module.exports = { associateReleaseTags, };