From d49d13c9db9d4374558217ee7af12a605313db5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ad=C3=A1mek?= Date: Thu, 28 Dec 2023 23:03:45 +0100 Subject: [PATCH] fix(postgres): respect column length in down migrations Closes #5048 --- .../knex/src/schema/SqlSchemaGenerator.ts | 1 + .../postgresql/src/PostgreSqlSchemaHelper.ts | 14 +- .../changing-pk-type.postgres.test.ts.snap | 2 +- .../length-diffing.mysql.test.ts.snap | 27 +++- .../length-diffing.postgres.test.ts.snap | 42 +++++ .../length-diffing.mysql.test.ts | 32 +++- .../length-diffing.postgres.test.ts | 148 ++++++++++++++++++ 7 files changed, 251 insertions(+), 15 deletions(-) create mode 100644 tests/features/schema-generator/__snapshots__/length-diffing.postgres.test.ts.snap create mode 100644 tests/features/schema-generator/length-diffing.postgres.test.ts diff --git a/packages/knex/src/schema/SqlSchemaGenerator.ts b/packages/knex/src/schema/SqlSchemaGenerator.ts index 9a97ce06a2f5..921390b3a2ab 100644 --- a/packages/knex/src/schema/SqlSchemaGenerator.ts +++ b/packages/knex/src/schema/SqlSchemaGenerator.ts @@ -177,6 +177,7 @@ export class SqlSchemaGenerator extends AbstractSchemaGenerator { @@ -106,26 +121,29 @@ describe('length diffing in mysql', () => { test('schema generator updates column types when length changes (varchar, decimal, ...)', async () => { orm.getMetadata().reset('Book0'); await orm.discoverEntity(Book1); - const diff1 = await orm.schema.getUpdateSchemaSQL({ wrap: false }); + const diff1 = await orm.schema.getUpdateSchemaMigrationSQL({ wrap: false }); expect(diff1).toMatchSnapshot(); - await orm.schema.execute(diff1); + await orm.schema.execute(diff1.up); orm.getMetadata().reset('Book1'); await orm.discoverEntity(Book2); - const diff2 = await orm.schema.getUpdateSchemaSQL({ wrap: false }); + const diff2 = await orm.schema.getUpdateSchemaMigrationSQL({ wrap: false }); expect(diff2).toMatchSnapshot(); - await orm.schema.execute(diff2); + await orm.schema.execute(diff2.up); orm.getMetadata().reset('Book2'); await orm.discoverEntity(Book3); - const diff3 = await orm.schema.getUpdateSchemaSQL({ wrap: false }); + const diff3 = await orm.schema.getUpdateSchemaMigrationSQL({ wrap: false }); expect(diff3).toMatchSnapshot(); - await orm.schema.execute(diff3); + await orm.schema.execute(diff3.up); orm.getMetadata().reset('Book3'); await orm.discoverEntity(Book4); - await expect(orm.schema.getUpdateSchemaSQL({ wrap: false })).resolves.toBe(''); + await expect(orm.schema.getUpdateSchemaMigrationSQL({ wrap: false })).resolves.toEqual({ + down: '', + up: '', + }); }); }); diff --git a/tests/features/schema-generator/length-diffing.postgres.test.ts b/tests/features/schema-generator/length-diffing.postgres.test.ts new file mode 100644 index 000000000000..f0bac7e8c3bb --- /dev/null +++ b/tests/features/schema-generator/length-diffing.postgres.test.ts @@ -0,0 +1,148 @@ +import { Entity, PrimaryKey, Property, t } from '@mikro-orm/core'; +import { MikroORM } from '@mikro-orm/postgresql'; + +@Entity({ tableName: 'book' }) +export class Book0 { + + @PrimaryKey() + id!: number; + + @Property() + name!: string; + + @Property() + length!: number; + + @Property({ type: t.decimal }) + price!: string; + + @Property({ length: 2 }) + createdAt!: Date; + +} + +@Entity({ tableName: 'book' }) +export class Book1 { + + @PrimaryKey({ type: t.bigint }) + id!: string; + + @Property({ length: 100 }) + name!: string; + + @Property({ unsigned: true }) + length!: number; + + @Property({ type: t.decimal, precision: 16 }) + price!: string; + + @Property({ length: 3 }) + createdAt!: Date; + +} + +@Entity({ tableName: 'book' }) +export class Book2 { + + @PrimaryKey({ type: t.bigint }) + id!: string; + + @Property({ length: 150 }) + name!: string; + + @Property({ unsigned: true }) + length!: number; + + @Property({ type: t.decimal, precision: 16, scale: 4 }) + price!: number; + + @Property({ length: 3 }) + createdAt!: Date; + +} + +@Entity({ tableName: 'book' }) +export class Book3 { + + @PrimaryKey({ type: t.bigint }) + id!: string; + + @Property({ length: 100 }) + name!: string; + + @Property({ unsigned: true }) + length!: number; + + @Property({ columnType: 'decimal(16,4)' }) + price!: number; + + @Property({ length: 3 }) + createdAt!: Date; + +} + +@Entity({ tableName: 'book' }) +export class Book4 { + + @PrimaryKey({ type: t.bigint }) + id!: string; + + @Property({ columnType: 'varchar(100)' }) + name!: string; + + @Property({ unsigned: true }) + length!: number; + + @Property({ columnType: 'decimal(16,4)' }) + price!: number; + + @Property({ length: 3 }) + createdAt!: Date; + +} + +describe('length diffing in postgres', () => { + + let orm: MikroORM; + + beforeAll(async () => { + orm = await MikroORM.init({ + entities: [Book0], + dbName: `mikro_orm_test_length_diffing`, + }); + await orm.schema.ensureDatabase(); + await orm.schema.execute('drop table if exists book'); + await orm.schema.createSchema(); + }); + + afterAll(() => orm.close(true)); + + test('schema orm.schema updates column types when length changes (varchar, decimal, ...)', async () => { + orm.getMetadata().reset('Book0'); + await orm.discoverEntity(Book1); + const diff1 = await orm.schema.getUpdateSchemaMigrationSQL({ wrap: false }); + expect(diff1).toMatchSnapshot(); + await orm.schema.execute(diff1.up); + + orm.getMetadata().reset('Book1'); + await orm.discoverEntity(Book2); + const diff2 = await orm.schema.getUpdateSchemaMigrationSQL({ wrap: false }); + expect(diff2).toMatchSnapshot(); + await orm.schema.execute(diff2.up); + + orm.getMetadata().reset('Book2'); + await orm.discoverEntity(Book3); + const diff3 = await orm.schema.getUpdateSchemaMigrationSQL({ wrap: false }); + expect(diff3).toMatchSnapshot(); + await orm.schema.execute(diff3.up); + + orm.getMetadata().reset('Book3'); + await orm.discoverEntity(Book4); + + await expect(orm.schema.getUpdateSchemaMigrationSQL({ wrap: false })).resolves.toEqual({ + down: '', + up: '', + }); + }); + +});