import type { Sequelize } from "sequelize"; import { DataTypes, QueryTypes } from "sequelize"; import { RelationshipValuesSchema } from "../../domain/value-objects/asset-relationship-values.vo"; import { LegacyJsonSchema } from "./asset-catalog-relational"; import { removeAssetColumn } from "./asset-relational-sql"; export const relationshipColumns = { name: { type: DataTypes.STRING(100), allowNull: false }, inverseName: { type: DataTypes.STRING(100), allowNull: false }, symmetric: { type: DataTypes.BOOLEAN, allowNull: false }, notes: { type: DataTypes.TEXT, allowNull: false }, }; export async function normalizeAssetRelationships(database: Sequelize) { const query = database.getQueryInterface(); const columns = await query.describeTable("asset_relationships"); if (!columns.values) { return; } for (const [column, definition] of Object.entries(relationshipColumns)) { if (!(column in columns)) { await query.addColumn("asset_relationships", column, { ...definition, allowNull: true }); } } await database.transaction(async (transaction) => { const rows = await database.query<{ id: string; sourceId: string; targetId: string; typeId: string; values: unknown; }>("SELECT id,sourceId,targetId,typeId,`values` FROM asset_relationships", { type: QueryTypes.SELECT, transaction, }); for (const row of rows) { const values = RelationshipValuesSchema.parse(LegacyJsonSchema.parse(row.values)); if ( values.sourceId !== row.sourceId || values.targetId !== row.targetId || values.typeId !== row.typeId ) { throw new Error("Referencias de relación incompatibles con la normalización."); } await database.query( "UPDATE asset_relationships SET name=:name,inverseName=:inverseName,symmetric=:symmetric,notes=:notes WHERE id=:id", { replacements: { id: row.id, name: values.name, inverseName: values.inverseName, symmetric: values.symmetric, notes: values.notes, }, transaction, } ); } }); for (const [column, definition] of Object.entries(relationshipColumns)) { await query.changeColumn("asset_relationships", column, definition); } await removeAssetColumn(database, "asset_relationships", "values"); }