59 lines
2.0 KiB
TypeScript
59 lines
2.0 KiB
TypeScript
import type { Sequelize, Transaction } from "sequelize";
|
|
import { QueryTypes } from "sequelize";
|
|
|
|
/** Identificadores internos; los valores externos siempre se parametrizan. */
|
|
export function sqlIdentifier(value: string) {
|
|
return `\`${value.replaceAll("`", "``")}\``;
|
|
}
|
|
|
|
export async function writeResourceRow(
|
|
database: Sequelize,
|
|
table: string,
|
|
row: Record<string, string | number | boolean | null>,
|
|
transaction: Transaction
|
|
) {
|
|
const columns = Object.keys(row);
|
|
|
|
await database.query(
|
|
`INSERT INTO ${sqlIdentifier(table)} (${columns.map(sqlIdentifier).join(",")}) VALUES (${columns.map((key) => `:${key}`).join(",")}) ON DUPLICATE KEY UPDATE ${columns.map((key) => `${sqlIdentifier(key)}=VALUES(${sqlIdentifier(key)})`).join(",")}`,
|
|
{ replacements: row, transaction }
|
|
);
|
|
}
|
|
|
|
export async function readResourceRows<T extends object>(
|
|
database: Sequelize,
|
|
table: string,
|
|
column: string,
|
|
ids: readonly string[],
|
|
transaction: Transaction
|
|
) {
|
|
if (!ids.length) {
|
|
return [];
|
|
}
|
|
|
|
return database.query<T>(
|
|
`SELECT * FROM ${sqlIdentifier(table)} WHERE ${sqlIdentifier(column)} IN (:ids)`,
|
|
{ replacements: { ids }, type: QueryTypes.SELECT, transaction }
|
|
);
|
|
}
|
|
|
|
export async function removeResourceColumn(database: Sequelize, table: string, column: string) {
|
|
const columns = await database.getQueryInterface().describeTable(table);
|
|
|
|
if (!(column in columns)) {
|
|
return;
|
|
}
|
|
const constraints = await database.query<{ name: string }>(
|
|
"SELECT CONSTRAINT_NAME AS name FROM information_schema.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=:table AND COLUMN_NAME=:column AND REFERENCED_TABLE_NAME IS NOT NULL",
|
|
{ replacements: { table, column }, type: QueryTypes.SELECT }
|
|
);
|
|
|
|
for (const { name } of constraints) {
|
|
await database.query(
|
|
`ALTER TABLE ${sqlIdentifier(table)} DROP FOREIGN KEY ${sqlIdentifier(name)}`
|
|
);
|
|
}
|
|
// Evita el fallo de QueryInterface.removeColumn con Sequelize 6 y mariadb 3.
|
|
await database.query(`ALTER TABLE ${sqlIdentifier(table)} DROP COLUMN ${sqlIdentifier(column)}`);
|
|
}
|