fix: parse SQL migration comments safely
This commit is contained in:
1 parent
8d37ae9ae0
commit
c4454a292c
3 files changed
+30
-4
No files matched your search
@@ -1,6 +1,7 @@
|
|||||||
import { readFileSync, readdirSync } from "node:fs";
|
import { readFileSync, readdirSync } from "node:fs";
|
||||||
import { resolve, dirname } from "node:path";
|
import { resolve, dirname } from "node:path";
|
||||||
import { fileURLToPath } from "node:url";
|
import { fileURLToPath } from "node:url";
|
||||||
|
import { splitSqlStatements } from "./sql-statements";
|
||||||
|
|
||||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||||
const MIGRATIONS_DIR = resolve(__dirname, "../prisma/migrations");
|
const MIGRATIONS_DIR = resolve(__dirname, "../prisma/migrations");
|
||||||
@@ -68,10 +69,7 @@ async function apply(migration: MigrationFile): Promise<void> {
|
|||||||
const mysql = await import("mysql2/promise");
|
const mysql = await import("mysql2/promise");
|
||||||
const conn = await mysql.createConnection(url);
|
const conn = await mysql.createConnection(url);
|
||||||
try {
|
try {
|
||||||
const statements = migration.sql
|
const statements = splitSqlStatements(migration.sql);
|
||||||
.split(";")
|
|
||||||
.map((s) => s.trim())
|
|
||||||
.filter((s) => s.length > 0 && !s.startsWith("--"));
|
|
||||||
|
|
||||||
for (const stmt of statements) {
|
for (const stmt of statements) {
|
||||||
await conn.execute(stmt);
|
await conn.execute(stmt);
|
||||||
|
|||||||
@@ -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)",
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
Reference in new issue
Block a user