UNPKG

ddl-manager

Version:

store postgres procedures and triggers in files

147 lines (128 loc) 5.07 kB
import { CacheParser } from "../parser"; import { Cache, Select } from "../ast"; import { findDependencies, findDependenciesToCacheTable } from "./processor/findDependencies"; import { Database } from "../database/schema/Database"; import { DatabaseFunction } from "../database/schema/DatabaseFunction"; import { DatabaseTrigger } from "../database/schema/DatabaseTrigger"; import { TableID } from "../database/schema/TableID"; import { TriggerBuilderFactory } from "./trigger-builder/TriggerBuilderFactory"; import { SelfUpdateByOtherTablesTriggerBuilder } from "./trigger-builder/SelfUpdateByOtherTablesTriggerBuilder"; import { CacheContext } from "./trigger-builder/CacheContext"; import { SelfUpdateBySelfRowTriggerBuilder } from "./trigger-builder/SelfUpdateBySelfRowTriggerBuilder"; import { TableReference } from "../database/schema/TableReference"; import { FilesState } from "../fs/FilesState"; import { CacheColumnGraph } from "../Comparator/graph/CacheColumnGraph"; export interface ISelectForUpdate { for: TableReference; select: Select; } export interface IOutputTrigger { name: string; trigger: DatabaseTrigger; function: DatabaseFunction; }; export class CacheTriggersBuilder { private readonly allCache: Cache[]; private readonly cache: Cache; private readonly builderFactory: TriggerBuilderFactory; private readonly database: Database; private readonly fs: FilesState; private readonly graph: CacheColumnGraph; constructor( allCache: Cache[], cacheOrSQL: string | Cache, database: Database = new Database(), graph: CacheColumnGraph = new CacheColumnGraph([]), fs: FilesState = new FilesState() ) { this.graph = graph; this.allCache = allCache; let cache: Cache = cacheOrSQL as Cache; if ( typeof cacheOrSQL === "string" ) { cache = CacheParser.parse(cacheOrSQL); } this.database = database; this.fs = fs; this.cache = cache; this.builderFactory = new TriggerBuilderFactory( this.allCache, cache, database, this.fs, this.graph ); } createTriggers() { const output: IOutputTrigger[] = []; const allDeps = findDependencies(this.cache, false); for (const schemaTable of this.cache.withoutTriggers) { if ( !(schemaTable in allDeps) ) { throw new Error(`unknown table to ignore triggers: ${schemaTable}`); } } const needIgnoreTriggerOnCacheTable = this.cache.withoutTriggers.includes( this.cache.for.table.toString() ); if ( !needIgnoreTriggerOnCacheTable ) { const cacheTableDeps = findDependenciesToCacheTable(this.cache); const mutableColumns = cacheTableDeps.columns.filter(col => col != "id" ); const context = new CacheContext( this.cache, this.cache.for.table, mutableColumns, this.database, this.fs, this.graph, false ); let TriggerBuilderConstructor: ( typeof SelfUpdateBySelfRowTriggerBuilder | typeof SelfUpdateByOtherTablesTriggerBuilder | undefined ); if ( !this.cache.hasForeignTablesDeps() ) { TriggerBuilderConstructor = SelfUpdateBySelfRowTriggerBuilder; } else { TriggerBuilderConstructor = SelfUpdateByOtherTablesTriggerBuilder; } if ( TriggerBuilderConstructor ) { const builder = new TriggerBuilderConstructor(context); const triggers = builder.createTriggers(); for (const {trigger, procedure} of triggers) { output.push({ name: trigger.name, trigger: trigger, function: procedure }); } } } for (const schemaTable in allDeps) { const needIgnore = this.cache.withoutTriggers.includes(schemaTable); if ( needIgnore ) { continue; } const [schemaName, tableName] = schemaTable.split("."); const tableDeps = allDeps[ schemaTable ]; const triggerBuilder = this.builderFactory.tryCreateBuilder( new TableID(schemaName, tableName), tableDeps.columns ); if ( !triggerBuilder ) { continue; } const triggers = triggerBuilder.createTriggers(); for (const {trigger, procedure} of triggers) { output.push({ name: trigger.name, trigger: trigger, function: procedure }); } } return output; } }