Files
dbx/apps/desktop/src/lib/table/mysqlEventSql.ts
T

49 lines
2.1 KiB
TypeScript

export type MysqlEventSchedule = { mode: "at"; executeAt: string } | { mode: "every"; intervalValue: string; intervalUnit: string };
export type MysqlEventDraft = {
name: string;
schema?: string;
schedule: MysqlEventSchedule;
starts?: string;
ends?: string;
preserve?: boolean;
enabled?: boolean;
comment?: string;
body: string;
};
function ident(value: string): string {
const trimmed = value.trim();
if (!trimmed) throw new Error("Event name is required");
return `\`${trimmed.replaceAll("`", "``")}\``;
}
function literal(value: string): string {
return `'${value.replaceAll("\\", "\\\\").replaceAll("'", "\\'")}'`;
}
const units = new Set(["SECOND", "MINUTE", "HOUR", "DAY", "WEEK", "MONTH", "QUARTER", "YEAR"]);
export function buildMysqlEventSql(draft: MysqlEventDraft, operation: "CREATE" | "ALTER" = "ALTER"): string {
const name = ident(draft.name);
if (!draft.body.trim()) throw new Error("Event body is required");
let schedule: string;
if (draft.schedule.mode === "at") {
if (!draft.schedule.executeAt.trim()) throw new Error("AT schedule requires an execution time");
schedule = `AT ${literal(draft.schedule.executeAt)}`;
} else {
const unit = draft.schedule.intervalUnit.trim().toUpperCase();
const intervalValue = draft.schedule.intervalValue.trim();
if (!/^\d+$/.test(intervalValue) || /^0+$/.test(intervalValue)) {
throw new Error("EVERY schedule requires a positive integer interval value");
}
if (!units.has(unit)) throw new Error(`Invalid interval unit: ${draft.schedule.intervalUnit}`);
schedule = `EVERY ${intervalValue} ${unit}`;
}
let sql = `${operation} EVENT ${name} ON SCHEDULE ${schedule}`;
if (draft.starts?.trim()) sql += ` STARTS ${literal(draft.starts)}`;
if (draft.ends?.trim()) sql += ` ENDS ${literal(draft.ends)}`;
if (draft.preserve !== undefined) sql += draft.preserve ? " ON COMPLETION PRESERVE" : " ON COMPLETION NOT PRESERVE";
if (draft.enabled !== undefined) sql += draft.enabled ? " ENABLE" : " DISABLE";
if (draft.comment !== undefined) sql += ` COMMENT ${literal(draft.comment)}`;
return `${sql} DO ${draft.body.trim()}`;
}