From c4454a292c132da20a48f5f548f160c508846b1e Mon Sep 17 00:00:00 2001 From: simoleo89 Date: Sat, 11 Jul 2026 21:27:18 +0200 Subject: [PATCH] fix: parse SQL migration comments safely --- scripts/apply-migrations.ts | 6 ++---- scripts/sql-statements.test.ts | 18 ++++++++++++++++++ scripts/sql-statements.ts | 10 ++++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 scripts/sql-statements.test.ts create mode 100644 scripts/sql-statements.ts diff --git a/scripts/apply-migrations.ts b/scripts/apply-migrations.ts index 5597f28d..0fb46926 100644 --- a/scripts/apply-migrations.ts +++ b/scripts/apply-migrations.ts @@ -1,6 +1,7 @@ import { readFileSync, readdirSync } from "node:fs"; import { resolve, dirname } from "node:path"; import { fileURLToPath } from "node:url"; +import { splitSqlStatements } from "./sql-statements"; const __dirname = dirname(fileURLToPath(import.meta.url)); const MIGRATIONS_DIR = resolve(__dirname, "../prisma/migrations"); @@ -68,10 +69,7 @@ async function apply(migration: MigrationFile): Promise { const mysql = await import("mysql2/promise"); const conn = await mysql.createConnection(url); try { - const statements = migration.sql - .split(";") - .map((s) => s.trim()) - .filter((s) => s.length > 0 && !s.startsWith("--")); + const statements = splitSqlStatements(migration.sql); for (const stmt of statements) { await conn.execute(stmt); diff --git a/scripts/sql-statements.test.ts b/scripts/sql-statements.test.ts new file mode 100644 index 00000000..a9e5543d --- /dev/null +++ b/scripts/sql-statements.test.ts @@ -0,0 +1,18 @@ +import { describe, expect, it } from "vitest"; +import { splitSqlStatements } from "./sql-statements"; + +describe("splitSqlStatements", () => { + it("ignores semicolons inside line comments", () => { + const sql = [ + "-- Existing installs have this; new installs need it.", + "ALTER TABLE users ADD COLUMN IF NOT EXISTS example TEXT NULL;", + "-- next statement", + "CREATE TABLE IF NOT EXISTS example_table (id INT PRIMARY KEY);", + ].join("\n"); + + expect(splitSqlStatements(sql)).toEqual([ + "ALTER TABLE users ADD COLUMN IF NOT EXISTS example TEXT NULL", + "CREATE TABLE IF NOT EXISTS example_table (id INT PRIMARY KEY)", + ]); + }); +}); diff --git a/scripts/sql-statements.ts b/scripts/sql-statements.ts new file mode 100644 index 00000000..223ddb96 --- /dev/null +++ b/scripts/sql-statements.ts @@ -0,0 +1,10 @@ +export function splitSqlStatements(sql: string): string[] { + const withoutComments = sql + .replace(/\/\*[\s\S]*?\*\//g, "") + .replace(/^\s*--.*$/gm, ""); + + return withoutComments + .split(";") + .map((statement) => statement.trim()) + .filter(Boolean); +}