92 lines
3.3 KiB
TypeScript
92 lines
3.3 KiB
TypeScript
import type { Sequelize } from "sequelize";
|
|
import { DataTypes, QueryTypes } from "sequelize";
|
|
|
|
export async function migrateInfrastructure(database: Sequelize) {
|
|
const query = database.getQueryInterface();
|
|
const tables = await database.query<{ name: string }>(
|
|
"SELECT TABLE_NAME AS name FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE()",
|
|
{ type: QueryTypes.SELECT }
|
|
);
|
|
const id = { type: DataTypes.UUID, primaryKey: true };
|
|
|
|
const fk = (table: string) => ({
|
|
type: DataTypes.UUID,
|
|
allowNull: false,
|
|
references: { model: table, key: "id" },
|
|
onDelete: "RESTRICT",
|
|
});
|
|
|
|
const revision = () => ({ ...fk("asset_infrastructure_revisions"), primaryKey: true });
|
|
|
|
const definitions = [
|
|
[
|
|
"asset_infrastructure",
|
|
{ id, companyId: fk("companies"), assetId: { ...fk("assets"), unique: true } },
|
|
],
|
|
[
|
|
"asset_infrastructure_revisions",
|
|
{
|
|
id,
|
|
infrastructureId: fk("asset_infrastructure"),
|
|
actorId: fk("users"),
|
|
recordedAt: { type: DataTypes.STRING(30), allowNull: false },
|
|
position: { type: DataTypes.INTEGER, allowNull: false },
|
|
},
|
|
],
|
|
[
|
|
"asset_infrastructure_roles",
|
|
{ revisionId: revision(), role: { type: DataTypes.STRING(30), primaryKey: true } },
|
|
],
|
|
[
|
|
"asset_interface_snapshots",
|
|
{
|
|
revisionId: revision(),
|
|
id,
|
|
name: { type: DataTypes.STRING(100), allowNull: false },
|
|
kind: { type: DataTypes.STRING(12), allowNull: false },
|
|
mac: { type: DataTypes.STRING(17), allowNull: false },
|
|
notes: { type: DataTypes.TEXT, allowNull: false },
|
|
position: { type: DataTypes.INTEGER, allowNull: false },
|
|
},
|
|
],
|
|
[
|
|
"asset_interface_address_snapshots",
|
|
{
|
|
revisionId: revision(),
|
|
id,
|
|
interfaceId: { type: DataTypes.UUID, allowNull: false },
|
|
address: { type: DataTypes.STRING(45), allowNull: false },
|
|
position: { type: DataTypes.INTEGER, allowNull: false },
|
|
},
|
|
],
|
|
] as const;
|
|
|
|
for (const [table, columns] of definitions) {
|
|
if (!tables.some((row) => row.name === table)) {
|
|
await query.createTable(table, columns);
|
|
}
|
|
}
|
|
const constraints = await database.query<{ name: string }>(
|
|
"SELECT CONSTRAINT_NAME AS name FROM information_schema.TABLE_CONSTRAINTS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME IN ('asset_infrastructure','asset_interface_address_snapshots','asset_infrastructure_revisions')",
|
|
{ type: QueryTypes.SELECT }
|
|
);
|
|
|
|
if (!constraints.some((row) => row.name === "infrastructure_asset_company")) {
|
|
await database.query(
|
|
"ALTER TABLE asset_infrastructure ADD CONSTRAINT infrastructure_asset_company FOREIGN KEY (companyId,assetId) REFERENCES assets(companyId,id)"
|
|
);
|
|
}
|
|
if (!constraints.some((row) => row.name === "interface_address_owner")) {
|
|
await database.query(
|
|
"ALTER TABLE asset_interface_address_snapshots ADD CONSTRAINT interface_address_owner FOREIGN KEY (revisionId,interfaceId) REFERENCES asset_interface_snapshots(revisionId,id)"
|
|
);
|
|
}
|
|
if (!constraints.some((row) => row.name === "infrastructure_revision_position")) {
|
|
await query.addConstraint("asset_infrastructure_revisions", {
|
|
fields: ["infrastructureId", "position"],
|
|
type: "unique",
|
|
name: "infrastructure_revision_position",
|
|
});
|
|
}
|
|
}
|