Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | import { Logger } from '@nestjs/common';
import { Table, type DataSource, type ObjectType, type QueryRunner, type TableIndex } from 'typeorm';
// Cannot import Query nor PostgresQueryRunner directly because they are not exposed in typeorm's module.
type Query = { query: string; parameters?: unknown[] };
interface PostgresQueryRunnerLike extends QueryRunner {
createTableSql: (table: Table) => Query;
createIndexSql: (table: Table, index: TableIndex) => Query;
executeQueries: (queries: Query[], _?: unknown) => Promise<void>;
}
export class AmaliaPostgresQueryRunner {
private readonly logger = new Logger(AmaliaPostgresQueryRunner.name);
private readonly queryRunner: PostgresQueryRunnerLike;
public constructor(private readonly currentConnection: DataSource) {
this.queryRunner = currentConnection.driver.createQueryRunner('master') as PostgresQueryRunnerLike;
}
private generateTable(entity: ObjectType<unknown>, schema: string) {
const table = Table.create(this.currentConnection.getMetadata(entity), this.currentConnection.driver);
table.schema = schema;
return table;
}
protected generateSqlForTable(table: Table): Query[] {
const queries: Query[] = [this.queryRunner.createTableSql(table)];
table.indices.forEach((index) => {
index.name ||= this.queryRunner.connection.namingStrategy.indexName(table, index.columnNames, index.where);
queries.push(this.queryRunner.createIndexSql(table, index));
});
return queries;
}
public async createTableInCompanySchema(
targetDataSource: DataSource,
entity: ObjectType<unknown>,
schema: string,
options: { dropExistingFirst?: boolean } = {},
) {
const table = this.generateTable(entity, schema);
if (options.dropExistingFirst) {
// CASCADE is mandatory here because views are based on it.
await targetDataSource.query(`DROP TABLE IF EXISTS "${schema}"."${table.name}" CASCADE;`);
}
const queries = this.generateSqlForTable(table);
this.logger.debug({
sql: queries.map(({ query }) => query),
});
await this.queryRunner.executeQueries(queries, []);
}
}
|