Skip to content

Commit

Permalink
feat(sql): ensure correct table order in schema generator (#617)
Browse files Browse the repository at this point in the history
Use `CommitOrderCalculator` to calculate correct order for defining tables.
  • Loading branch information
B4nan committed Aug 9, 2020
1 parent 54ce064 commit b3949cf
Show file tree
Hide file tree
Showing 2 changed files with 565 additions and 535 deletions.
38 changes: 34 additions & 4 deletions packages/knex/src/schema/SchemaGenerator.ts
@@ -1,5 +1,5 @@
import { ColumnBuilder, SchemaBuilder, TableBuilder } from 'knex';
import { Cascade, EntityMetadata, EntityProperty, ReferenceType, Utils } from '@mikro-orm/core';
import { Cascade, CommitOrderCalculator, EntityMetadata, EntityProperty, ReferenceType, Utils } from '@mikro-orm/core';
import { Column, DatabaseSchema, DatabaseTable, IsSame } from '../index';
import { SqlEntityManager } from '../SqlEntityManager';

Expand Down Expand Up @@ -42,7 +42,7 @@ export class SchemaGenerator {
}

async getCreateSchemaSQL(wrap = true): Promise<string> {
const metadata = Object.values(this.metadata.getAll()).filter(meta => !meta.discriminatorValue && !meta.embeddable);
const metadata = this.getOrderedMetadata();
let ret = '';

for (const meta of metadata) {
Expand All @@ -67,9 +67,10 @@ export class SchemaGenerator {
}

async getDropSchemaSQL(wrap = true, dropMigrationsTable = false): Promise<string> {
const metadata = this.getOrderedMetadata().reverse();
let ret = '';

for (const meta of Object.values(this.metadata.getAll()).filter(meta => !meta.discriminatorValue && !meta.embeddable)) {
for (const meta of metadata) {
ret += this.dump(this.dropTable(meta.collection), '\n');
}

Expand All @@ -86,7 +87,7 @@ export class SchemaGenerator {
}

async getUpdateSchemaSQL(wrap = true, safe = false, dropTables = true): Promise<string> {
const metadata = Object.values(this.metadata.getAll()).filter(meta => !meta.discriminatorValue && !meta.embeddable);
const metadata = this.getOrderedMetadata();
const schema = await DatabaseSchema.create(this.connection, this.helper, this.config);
let ret = '';

Expand Down Expand Up @@ -466,6 +467,35 @@ export class SchemaGenerator {
return renamed;
}

private getOrderedMetadata(): EntityMetadata[] {
const metadata = Object.values(this.metadata.getAll()).filter(meta => !meta.discriminatorValue && !meta.embeddable);
const calc = new CommitOrderCalculator();
metadata.forEach(meta => calc.addNode(meta.name));
let meta = metadata.pop();

while (meta) {
for (const prop of Object.values(meta.properties)) {
if (!calc.hasNode(prop.type)) {
continue;
}

this.addCommitDependency(calc, prop, meta.name);
}

meta = metadata.pop();
}

return calc.sort().map(cls => this.metadata.get(cls));
}

private addCommitDependency(calc: CommitOrderCalculator, prop: EntityProperty, entityName: string): void {
if (!(prop.reference === ReferenceType.ONE_TO_ONE && prop.owner) && prop.reference !== ReferenceType.MANY_TO_ONE) {
return;
}

calc.addDependency(prop.type, entityName, prop.nullable ? 0 : 1);
}

private dump(builder: SchemaBuilder, append = '\n\n'): string {
const sql = builder.toQuery();
return sql.length > 0 ? `${sql};${append}` : '';
Expand Down

0 comments on commit b3949cf

Please sign in to comment.