UNPKG

sequelize-mv-support

Version:
138 lines (121 loc) 3.71 kB
import { DropOptions, Model as ModelOrig, ModelOptions, SyncOptions, } from 'sequelize'; import type { Sequelize, QueryInterfaceWithViews } from './SequelizeWithViews'; /** * Interface describing the options property on a model * * @export * @interface ModelOptionsWithViews * @extends {ModelOptions} */ export interface ModelOptionsWithViews<M extends ModelOrig> extends ModelOptions<M> { treatAsView?: boolean; treatAsMaterializedView?: boolean; viewDefinition?: string; materializedViewDefinition?: string; } export type DropOptionsType = DropOptions & { treatAsView?: boolean; treatAsMaterializedView?: boolean; viewDefinition?: string; }; export type OptionsType = ModelOptionsWithViews<ModelOrig> & { sequelize: Sequelize; }; /** * Model with view support added * * @export * @class Model * @extends {ModelOrig} */ export class Model< /* eslint-disable @typescript-eslint/ban-types */ TModelAttributes extends {} = any, TCreationAttributes extends {} = TModelAttributes /* eslint-enable @typescript-eslint/ban-types */ > extends ModelOrig<TModelAttributes, TCreationAttributes> { /** @inheritdoc */ public static override readonly options: OptionsType; /** @inheritdoc */ public static queryInterface: QueryInterfaceWithViews; /** @inheritdoc */ public static override drop(options: DropOptionsType = {}): any { const method = this.options.treatAsView ? 'dropView' : this.options.treatAsMaterializedView ? 'dropMaterializedView' : 'dropTable'; return this.queryInterface[method](this.getTableName(), options); } /** @inheritdoc */ public static override sync(options: SyncOptions): any { if (this.options.treatAsView || this.options.treatAsMaterializedView) return Promise.resolve(); return super.sync(options); } /** * Executes the query to create a view * * @static * @returns {Promise<[unknown[], unknown]>} Result of the create view request * @memberof Model */ public static syncView(): Promise<[unknown[], unknown]> { const definition = this.getViewDefinition(); if (!definition) throw new Error('cannot sync view with no definition'); return this.queryInterface.createView(this.getTableName(), definition); } /** * Executes the query to create a materialized view * * @static * @returns {Promise<[unknown[], unknown]>} Result of the create materialized view request * @memberof Model */ public static syncMaterializedView(): Promise<[unknown[], unknown]> { const definition = this.getMaterializedViewDefinition(); if (!definition) throw new Error('cannot sync materialised view with no definition'); return this.queryInterface.createMaterializedView( this.getTableName(), definition ); } /** * Gets the sql definition for this view * * @static * @returns {string} SQL query string to create a view * @memberof Model */ public static getViewDefinition(): string | undefined { return this.options.viewDefinition; } /** * Gets the sql definition for this materialized view * * @static * @returns {string} SQL query string to create the materialized view * @memberof Model */ public static getMaterializedViewDefinition(): string | undefined { return this.options.materializedViewDefinition; } /** * Refreshes the materialized view in the database * * @static * @returns {Promise<[unknown[], unknown]>} * @memberof Model */ public static refreshMaterializedView(): Promise<[unknown[], unknown]> { return this.queryInterface.refreshMaterializedView(this.getTableName()); } } export default Model;