Skip to content
This repository has been archived by the owner on Mar 18, 2022. It is now read-only.

Commit

Permalink
feat: add materialized View support for Postgres (typeorm#4478)
Browse files Browse the repository at this point in the history
feat: add option to synchronize or not to synchronize ViewEntity

Fixes typeorm#4317
Fixes  typeorm#3996
  • Loading branch information
Ginden authored and pleerock committed Sep 5, 2019
1 parent db8074a commit dacac83
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 5 deletions.
2 changes: 2 additions & 0 deletions src/decorator/entity-view/ViewEntity.ts
Expand Up @@ -30,6 +30,8 @@ export function ViewEntity(nameOrOptions?: string|ViewEntityOptions, maybeOption
type: "view",
database: options.database ? options.database : undefined,
schema: options.schema ? options.schema : undefined,
synchronize: options.synchronize === false ? false : true,
materialized: !!options.materialized
} as TableMetadataArgs);
};
}
13 changes: 13 additions & 0 deletions src/decorator/options/ViewEntityOptions.ts
Expand Up @@ -25,4 +25,17 @@ export interface ViewEntityOptions {
* Schema name. Used in Postgres and Sql Server.
*/
schema?: string;

/**
* Indicates if schema synchronization is enabled or disabled for this entity.
* If it will be set to false then schema sync will and migrations ignore this entity.
* By default schema synchronization is enabled for all entities.
*/
synchronize?: boolean;

/**
* Indicates if view should be materialized view.
* It's supported by Postgres and Oracle.
*/
materialized?: boolean;
}
5 changes: 3 additions & 2 deletions src/driver/oracle/OracleQueryRunner.ts
Expand Up @@ -1385,10 +1385,11 @@ export class OracleQueryRunner extends BaseQueryRunner implements QueryRunner {
}

protected createViewSql(view: View): Query {
const materializedClause = view.materialized ? "" : "MATERIALIZED ";
if (typeof view.expression === "string") {
return new Query(`CREATE VIEW "${view.name}" AS ${view.expression}`);
return new Query(`CREATE ${materializedClause}VIEW "${view.name}" AS ${view.expression}`);
} else {
return new Query(`CREATE VIEW "${view.name}" AS ${view.expression(this.connection).getQuery()}`);
return new Query(`CREATE ${materializedClause}VIEW "${view.name}" AS ${view.expression(this.connection).getQuery()}`);
}
}

Expand Down
6 changes: 6 additions & 0 deletions src/metadata-args/TableMetadataArgs.ts
Expand Up @@ -56,4 +56,10 @@ export interface TableMetadataArgs {
*/
expression?: string|((connection: Connection) => SelectQueryBuilder<any>);

/**
* Indicates if view is materialized
*/

materialized?: boolean;

}
2 changes: 1 addition & 1 deletion src/schema-builder/RdbmsSchemaBuilder.ts
Expand Up @@ -139,7 +139,7 @@ export class RdbmsSchemaBuilder implements SchemaBuilder {
* Returns only entities that should be synced in the database.
*/
protected get viewEntityToSyncMetadatas(): EntityMetadata[] {
return this.connection.entityMetadatas.filter(metadata => metadata.tableType === "view");
return this.connection.entityMetadatas.filter(metadata => metadata.tableType === "view" && metadata.synchronize);
}

/**
Expand Down
5 changes: 5 additions & 0 deletions src/schema-builder/options/ViewOptions.ts
Expand Up @@ -19,4 +19,9 @@ export interface ViewOptions {
*/
expression: string|((connection: Connection) => SelectQueryBuilder<any>);

/**
* Indicates if view is materialized
*/

materialized?: boolean;
}
13 changes: 11 additions & 2 deletions src/schema-builder/view/View.ts
Expand Up @@ -17,10 +17,16 @@ export class View {
*/
name: string;


/**
* Indicates if view is materialized.
*/
materialized: boolean;

/**
* View definition.
*/
expression: string|((connection: Connection) => SelectQueryBuilder<any>);
expression: string | ((connection: Connection) => SelectQueryBuilder<any>);

// -------------------------------------------------------------------------
// Constructor
Expand All @@ -30,6 +36,7 @@ export class View {
if (options) {
this.name = options.name;
this.expression = options.expression;
this.materialized = !!options.materialized;
}
}

Expand All @@ -41,9 +48,10 @@ export class View {
* Clones this table to a new table with all properties cloned.
*/
clone(): View {
return new View(<ViewOptions> {
return new View(<ViewOptions>{
name: this.name,
expression: this.expression,
materialized: this.materialized,
});
}

Expand All @@ -58,6 +66,7 @@ export class View {
const options: ViewOptions = {
name: driver.buildTableName(entityMetadata.tableName, entityMetadata.schema, entityMetadata.database),
expression: entityMetadata.expression!,
materialized: false
};

return new View(options);
Expand Down

0 comments on commit dacac83

Please sign in to comment.