UNPKG

ddl-manager

Version:

store postgres procedures and triggers in files

178 lines (156 loc) 4.87 kB
import { Spaces } from "../Spaces"; import { Expression } from "./Expression"; import { AbstractExpressionElement } from "./AbstractExpressionElement"; import { flatMap } from "lodash"; import { IExpressionElement } from "./interface"; import { TableReference } from "../../database/schema/TableReference"; import { TableID } from "../../database/schema/TableID"; import { ColumnReference } from "./ColumnReference"; import { FuncCall } from "./FuncCall"; interface ICase { when: Expression; then: Expression; } export class CaseWhen extends AbstractExpressionElement { readonly cases: ICase[]; readonly else?: Expression; constructor(params: {cases: ICase[], else?: Expression}) { super(); this.cases = params.cases; this.else = params.else; } children() { const children: IExpressionElement[] = []; for (const caseElem of this.cases) { children.push( ...caseElem.when.children() ); children.push( ...caseElem.then.children() ); } if ( this.else ) { children.push(...this.else.children()); } return children; } clone(changes: { cases?: ICase[]; else?: Expression; } = {}) { return new CaseWhen({ cases: changes.cases || this.cloneCases(), else: ( "else" in changes ? changes.else : this.cloneElse() ) }); } replaceTable( replaceTable: TableReference | TableID, toTable: TableReference ) { const changes: { cases?: ICase[]; else?: Expression; } = {}; changes.cases = this.cases.map(caseElem => { const newWhen = caseElem.when.replaceTable( replaceTable, toTable ); const newThen = caseElem.then.replaceTable( replaceTable, toTable ); return {when: newWhen, then: newThen}; }); if ( this.else ) { changes.else = this.else.replaceTable(replaceTable, toTable); } return this.clone(changes); } replaceColumn(replaceColumn: ColumnReference, toSql: IExpressionElement) { const changes: { cases?: ICase[]; else?: Expression; } = {}; changes.cases = this.cases.map(caseElem => { const newWhen = caseElem.when.replaceColumn( replaceColumn, toSql ); const newThen = caseElem.then.replaceColumn( replaceColumn, toSql ); return {when: newWhen, then: newThen}; }); if ( this.else ) { changes.else = this.else.replaceColumn(replaceColumn, toSql); } return this.clone(changes); } replaceFuncCall(replaceFunc: FuncCall, toSql: string) { const changes: { cases?: ICase[]; else?: Expression; } = {}; changes.cases = this.cases.map(caseElem => { const newWhen = caseElem.when.replaceFuncCall( replaceFunc, toSql ); const newThen = caseElem.then.replaceFuncCall( replaceFunc, toSql ); return {when: newWhen, then: newThen}; }); if ( this.else ) { changes.else = this.else.replaceFuncCall(replaceFunc, toSql); } return this.clone(changes); } private cloneElse() { if ( this.else ) { return this.else.clone(); } } private cloneCases() { return this.cases.map(someCase => ({ when: someCase.when.clone(), then: someCase.then.clone() })); } template(spaces: Spaces): string[] { return [ spaces + "case", ...flatMap(this.cases, someCase => this.printCase(someCase, spaces) ), ...this.printElse(spaces), spaces + "end" ]; } private printCase(someCase: ICase, spaces: Spaces) { return [ spaces.plusOneLevel() + "when", someCase.when.toSQL( spaces .plusOneLevel() .plusOneLevel() ), spaces.plusOneLevel() + "then", someCase.then.toSQL( spaces .plusOneLevel() .plusOneLevel() ) ]; } private printElse(spaces: Spaces) { if ( !this.else ) { return []; } return [ spaces.plusOneLevel() + "else", ...this.else.template( spaces .plusOneLevel() .plusOneLevel() ) ]; } }