fix: Migration generator and generated migrations (#8090)

This commit is contained in:
Adrien de Peretti
2024-07-11 18:21:09 +02:00
committed by GitHub
parent eebae37287
commit 79ec2bcfe2
5 changed files with 92 additions and 113 deletions

View File

@@ -1,14 +1,14 @@
import { TSMigrationGenerator } from "../mikro-orm-create-connection"
import { CustomTsMigrationGenerator } from "../mikro-orm-create-connection"
function unwrapSql(sql: string) {
return sql.match(/this.addSql\('(.*?)'\)/)?.[1]
}
describe("TSMigrationGenerator", () => {
describe("CustomTsMigrationGenerator", () => {
it('should add "if not exists" to "create table" statements', () => {
const sql = "create table my_table (id int)"
const result = unwrapSql(
TSMigrationGenerator.prototype.createStatement(sql, 0)
CustomTsMigrationGenerator.prototype.createStatement(sql, 0)
)
expect(result).toBe("create table if not exists my_table (id int)")
})
@@ -16,7 +16,7 @@ describe("TSMigrationGenerator", () => {
it('should add "if exists" to "alter table" statements as well as to the add column', () => {
const sql = "alter table my_table add column name varchar(100)"
const result = unwrapSql(
TSMigrationGenerator.prototype.createStatement(sql, 0)
CustomTsMigrationGenerator.prototype.createStatement(sql, 0)
)
expect(result).toBe(
"alter table if exists my_table add column if not exists name varchar(100)"
@@ -26,27 +26,17 @@ describe("TSMigrationGenerator", () => {
it('should add "if exists" to "alter table" statements as well as to the drop column', () => {
const sql = "alter table my_table drop column name"
const result = unwrapSql(
TSMigrationGenerator.prototype.createStatement(sql, 0)
CustomTsMigrationGenerator.prototype.createStatement(sql, 0)
)
expect(result).toBe(
"alter table if exists my_table drop column if exists name"
)
})
it('should add "if exists" to "alter table" statements as well as to the alter column', () => {
const sql = "alter table my_table alter column name"
const result = unwrapSql(
TSMigrationGenerator.prototype.createStatement(sql, 0)
)
expect(result).toBe(
"alter table if exists my_table alter column if exists name"
)
})
it('should add "if not exists" to "create index" statements', () => {
const sql = "create index idx_name on my_table(name)"
const result = unwrapSql(
TSMigrationGenerator.prototype.createStatement(sql, 0)
CustomTsMigrationGenerator.prototype.createStatement(sql, 0)
)
expect(result).toBe("create index if not exists idx_name on my_table(name)")
})
@@ -54,7 +44,7 @@ describe("TSMigrationGenerator", () => {
it('should add "if exists" to "drop index" statements', () => {
const sql = "drop index idx_name"
const result = unwrapSql(
TSMigrationGenerator.prototype.createStatement(sql, 0)
CustomTsMigrationGenerator.prototype.createStatement(sql, 0)
)
expect(result).toBe("drop index if exists idx_name")
})
@@ -62,7 +52,7 @@ describe("TSMigrationGenerator", () => {
it('should add "if not exists" to "create unique index" statements', () => {
const sql = "create unique index idx_unique_name on my_table(name)"
const result = unwrapSql(
TSMigrationGenerator.prototype.createStatement(sql, 0)
CustomTsMigrationGenerator.prototype.createStatement(sql, 0)
)
expect(result).toBe(
"create unique index if not exists idx_unique_name on my_table(name)"
@@ -72,7 +62,7 @@ describe("TSMigrationGenerator", () => {
it('should add "if exists" to "drop unique index" statements', () => {
const sql = "drop unique index idx_unique_name"
const result = unwrapSql(
TSMigrationGenerator.prototype.createStatement(sql, 0)
CustomTsMigrationGenerator.prototype.createStatement(sql, 0)
)
expect(result).toBe("drop unique index if exists idx_unique_name")
})
@@ -80,7 +70,7 @@ describe("TSMigrationGenerator", () => {
it('should add "if not exists" to "add column" statements', () => {
const sql = "add column name varchar(100)"
const result = unwrapSql(
TSMigrationGenerator.prototype.createStatement(sql, 0)
CustomTsMigrationGenerator.prototype.createStatement(sql, 0)
)
expect(result).toBe("add column if not exists name varchar(100)")
})
@@ -88,23 +78,15 @@ describe("TSMigrationGenerator", () => {
it('should add "if exists" to "drop column" statements', () => {
const sql = "drop column name"
const result = unwrapSql(
TSMigrationGenerator.prototype.createStatement(sql, 0)
CustomTsMigrationGenerator.prototype.createStatement(sql, 0)
)
expect(result).toBe("drop column if exists name")
})
it('should add "if exists" to "alter column" statements', () => {
const sql = "alter column name"
const result = unwrapSql(
TSMigrationGenerator.prototype.createStatement(sql, 0)
)
expect(result).toBe("alter column if exists name")
})
it('should add "if exists" to "drop constraint" statements', () => {
const sql = "drop constraint fk_name"
const result = unwrapSql(
TSMigrationGenerator.prototype.createStatement(sql, 0)
CustomTsMigrationGenerator.prototype.createStatement(sql, 0)
)
expect(result).toBe("drop constraint if exists fk_name")
})

View File

@@ -3,71 +3,42 @@ import { TSMigrationGenerator } from "@mikro-orm/migrations"
import { isString } from "../../common"
import { FilterDef } from "@mikro-orm/core/typings"
// Monkey patch due to the compilation version issue which prevents us from creating a proper class that extends the TSMigrationGenerator
const originalCreateStatement = TSMigrationGenerator.prototype.createStatement
/**
* Safe migration generation for MikroORM
*
* @param sql The sql statement
* @param padLeft The padding
*
* @example see test file
*/
TSMigrationGenerator.prototype.createStatement = function (
sql: string,
padLeft: number
) {
if (isString(sql)) {
if (!sql.includes("create table if not exists")) {
sql = sql.replace("create table", "create table if not exists")
}
if (!sql.includes("alter table if exists")) {
sql = sql.replace("alter table", "alter table if exists")
}
if (!sql.includes("create index if not exists")) {
sql = sql.replace("create index", "create index if not exists")
}
if (!sql.includes("drop index if exists")) {
sql = sql.replace("drop index", "drop index if exists")
}
if (!sql.includes("create unique index if not exists")) {
export class CustomTsMigrationGenerator extends TSMigrationGenerator {
createStatement(sql: string, padLeft: number): string {
if (isString(sql)) {
sql = sql.replace(
"create unique index",
"create unique index if not exists"
/create table (?!if not exists)/g,
"create table if not exists "
)
sql = sql.replace(/alter table (?!if exists)/g, "alter table if exists ")
sql = sql.replace(
/create index (?!if not exists)/g,
"create index if not exists "
)
sql = sql.replace(/drop index (?!if exists)/g, "drop index if exists ")
sql = sql.replace(
/create unique index (?!if not exists)/g,
"create unique index if not exists "
)
sql = sql.replace(
/drop unique index (?!if exists)/g,
"drop unique index if exists "
)
sql = sql.replace(
/add column (?!if not exists)/g,
"add column if not exists "
)
sql = sql.replace(/drop column (?!if exists)/g, "drop column if exists ")
sql = sql.replace(
/drop constraint (?!if exists)/g,
"drop constraint if exists "
)
}
if (!sql.includes("drop unique index if exists")) {
sql = sql.replace("drop unique index", "drop unique index if exists")
}
if (!sql.includes("add column if not exists")) {
sql = sql.replace("add column", "add column if not exists")
}
if (!sql.includes("alter column if exists exists")) {
sql = sql.replace("alter column", "alter column if exists")
}
if (!sql.includes("drop column if exists")) {
sql = sql.replace("drop column", "drop column if exists")
}
if (!sql.includes("drop constraint if exists")) {
sql = sql.replace("drop constraint", "drop constraint if exists")
}
return super.createStatement(sql, padLeft)
}
return originalCreateStatement(sql, padLeft)
}
export { TSMigrationGenerator }
export type Filter = {
name?: string
} & Omit<FilterDef, "name">
@@ -99,7 +70,7 @@ export async function mikroOrmCreateConnection(
const { MikroORM } = await import("@mikro-orm/postgresql")
return await MikroORM.init({
discovery: { disableDynamicFileAccess: true, warnWhenNoEntities: false, },
discovery: { disableDynamicFileAccess: true, warnWhenNoEntities: false },
entities,
debug: database.debug ?? process.env.NODE_ENV?.startsWith("dev") ?? false,
baseDir: process.cwd(),
@@ -112,7 +83,7 @@ export async function mikroOrmCreateConnection(
migrations: {
disableForeignKeys: false,
path: pathToMigrations,
generator: TSMigrationGenerator,
generator: CustomTsMigrationGenerator,
silent: !(
database.debug ??
process.env.NODE_ENV?.startsWith("dev") ??
@@ -120,7 +91,7 @@ export async function mikroOrmCreateConnection(
),
},
schemaGenerator: {
disableForeignKeys: false
disableForeignKeys: false,
},
pool: database.pool as any,
})

View File

@@ -2,7 +2,7 @@ import { MetadataStorage, MikroORM } from "@mikro-orm/core"
import { model } from "../entity-builder"
import { toMikroOrmEntities } from "../helpers/create-mikro-orm-entity"
import { createDatabase, dropDatabase } from "pg-god"
import { mikroOrmSerializer, TSMigrationGenerator } from "../../dal"
import { CustomTsMigrationGenerator, mikroOrmSerializer } from "../../dal"
import { FileSystem } from "../../common"
import { join } from "path"
import { EntityConstructor } from "@medusajs/types"
@@ -70,7 +70,7 @@ describe("manyToMany - manyToMany", () => {
debug: true,
type: "postgresql",
migrations: {
generator: TSMigrationGenerator,
generator: CustomTsMigrationGenerator,
},
})

View File

@@ -1,6 +1,6 @@
import { MikroORMOptions } from "@mikro-orm/core/utils/Configuration"
import { DmlEntity, toMikroOrmEntities } from "../dml"
import { TSMigrationGenerator } from "../dal"
import { CustomTsMigrationGenerator } from "../dal"
import type {
AnyEntity,
EntityClass,
@@ -59,7 +59,7 @@ export function defineMikroOrmCliConfig(
...options,
entities,
migrations: {
generator: TSMigrationGenerator,
generator: CustomTsMigrationGenerator,
...options.migrations,
},
}

View File

@@ -1,30 +1,56 @@
import { Migration } from '@mikro-orm/migrations';
import { Migration } from "@mikro-orm/migrations"
export class Migration20240529080336 extends Migration {
async up(): Promise<void> {
this.addSql('create table if not exists "provider_identity" ("id" text not null, "entity_id" text not null, "provider" text not null, "auth_identity_id" text not null, "user_metadata" jsonb null, "provider_metadata" jsonb null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), constraint "provider_identity_pkey" primary key ("id"));');
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_provider_identity_auth_identity_id" ON "provider_identity" (auth_identity_id);');
this.addSql('CREATE UNIQUE INDEX IF NOT EXISTS "IDX_provider_identity_provider_entity_id" ON "provider_identity" (entity_id, provider);');
this.addSql(
'create table if not exists "provider_identity" ("id" text not null, "entity_id" text not null, "provider" text not null, "auth_identity_id" text not null, "user_metadata" jsonb null, "provider_metadata" jsonb null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), constraint "provider_identity_pkey" primary key ("id"));'
)
this.addSql(
'CREATE INDEX IF NOT EXISTS "IDX_provider_identity_auth_identity_id" ON "provider_identity" (auth_identity_id);'
)
this.addSql(
'CREATE UNIQUE INDEX IF NOT EXISTS "IDX_provider_identity_provider_entity_id" ON "provider_identity" (entity_id, provider);'
)
this.addSql('alter table if exists "provider_identity" add constraint "provider_identity_auth_identity_id_foreign" foreign key ("auth_identity_id") references "auth_identity" ("id") on update cascade on delete cascade;');
this.addSql(
'alter table if exists "provider_identity" add constraint "provider_identity_auth_identity_id_foreign" foreign key ("auth_identity_id") references "auth_identity" ("id") on update cascade on delete cascade;'
)
this.addSql('alter table if exists "auth_identity" add column if not exists "created_at" timestamptz not null default now(), add column "updated_at" timestamptz not null default now();');
this.addSql(
'alter table if exists "auth_identity" add column if not exists "created_at" timestamptz not null default now(), add column "updated_at" timestamptz not null default now();'
)
this.addSql('alter table if exists "auth_identity" drop constraint if exists "IDX_auth_identity_provider_entity_id";');
this.addSql('alter table if exists "auth_identity" drop column if exists "entity_id";');
this.addSql('alter table if exists "auth_identity" drop column if exists "provider";');
this.addSql('alter table if exists "auth_identity" drop column if exists "user_metadata";');
this.addSql('alter table if exists "auth_identity" drop column if exists "provider_metadata";');
this.addSql(
'alter table if exists "auth_identity" drop constraint if exists "IDX_auth_identity_provider_entity_id";'
)
this.addSql(
'alter table if exists "auth_identity" drop column if exists "entity_id";'
)
this.addSql(
'alter table if exists "auth_identity" drop column if exists "provider";'
)
this.addSql(
'alter table if exists "auth_identity" drop column if exists "user_metadata";'
)
this.addSql(
'alter table if exists "auth_identity" drop column if exists "provider_metadata";'
)
}
async down(): Promise<void> {
this.addSql('drop table if exists "provider_identity" cascade;');
this.addSql('drop table if exists "provider_identity" cascade;')
this.addSql('alter table if exists "auth_identity" add column if not exists "entity_id" text not null, add column "provider" text not null, add column "user_metadata" jsonb null, add column "provider_metadata" jsonb null;');
this.addSql('alter table if exists "auth_identity" alter column if exists "app_metadata" type jsonb using ("app_metadata"::jsonb);');
this.addSql('alter table if exists "auth_identity" alter column if exists "app_metadata" set not null;');
this.addSql('alter table if exists "auth_identity" add constraint "IDX_auth_identity_provider_entity_id" unique ("provider", "entity_id");');
this.addSql(
'alter table if exists "auth_identity" add column if not exists "entity_id" text not null, add column "provider" text not null, add column "user_metadata" jsonb null, add column "provider_metadata" jsonb null;'
)
this.addSql(
'alter table if exists "auth_identity" alter column "app_metadata" type jsonb using ("app_metadata"::jsonb);'
)
this.addSql(
'alter table if exists "auth_identity" alter column "app_metadata" set not null;'
)
this.addSql(
'alter table if exists "auth_identity" add constraint "IDX_auth_identity_provider_entity_id" unique ("provider", "entity_id");'
)
}
}