UNPKG

mp-holistic

Version:

si prefigge l'umile compito di aiutare nella creazione di : - un server API REST mediante express - un semplice ORM per Postgres Questo tramite decoratori o classi particolari.

353 lines (321 loc) 14.9 kB
import { IMetaClasse, ListaMetadataClasse, MetadataClasse } from "../metadata/classe.metadata"; import { IGrant, typeGrantEvent } from "./grant"; import { ListaPolicy } from "./policy"; import { ListaPostgresProprieta, PostgresProprieta } from "./proprieta.postgres"; export interface IPostgresClasse extends IMetaClasse { queryPerVista?: string, nomeTabella?: string, like?: string, estende?: string, abilitaCreatedAt?: boolean, abilitaUpdatedAt?: boolean, abilitaDeletedAt?: boolean, creaId?: boolean, listaPolicy?: ListaPolicy, grants?: IGrant[], multiUnique?: { colonneDiRiferimento: string[] }[] } export class PostgresClasse extends MetadataClasse implements IPostgresClasse { queryPerVista?: string; listaProprieta: ListaPostgresProprieta = new ListaPostgresProprieta(); nomeTabella: string; like?: string; estende?: string; abilitaCreatedAt: boolean; abilitaUpdatedAt: boolean; abilitaDeletedAt: boolean; creaId: boolean; listaPolicy?: ListaPolicy; grants?: IGrant[] multiUnique?: { colonneDiRiferimento: string[] }[] = []; faxSimile_abilitaDeletedAt = `created_at timestamp with time zone NOT NULL DEFAULT current_timestamp`; faxSimile_abilitaCreatedAt = `updated_at timestamp with time zone NOT NULL DEFAULT current_timestamp`; faxSimile_abilitaUpdatedAt = `deleted_at timestamp with time zone`; faxsSimileIntestazione = 'CREATE TABLE IF NOT EXISTS '; faxsSimileIntestazioneView = 'CREATE OR REPLACE VIEW '; constructor(item: IPostgresClasse) { super(item); if ((this.nomeOriginale == '' || this.nomeOriginale == undefined) && item.nomeTabella) this.nomeOriginale = item.nomeTabella; this.creaId = item.creaId ?? true; this.nomeTabella = item.nomeTabella ?? this.nomeOriginale; //this.listaProprieta = new Lista(); this.abilitaCreatedAt = item.abilitaCreatedAt ?? true; this.abilitaDeletedAt = item.abilitaDeletedAt ?? true; this.abilitaUpdatedAt = item.abilitaUpdatedAt ?? true; if (item.grants) { this.grants = item.grants; } } CostruisciCreazioneDB(/* client: Client */elencoQuery: string[], padreEreditario: boolean) { let rigaDaInserire = ''; let ritornoTmp = ''; if (this.estende == undefined && this.like == undefined && padreEreditario == true) rigaDaInserire = '); \n'; else if (this.estende && padreEreditario == false) rigaDaInserire = ') INHERITS("' + this.estende + '");' + '\n'; else if (this.like && padreEreditario == false) rigaDaInserire = 'LIKE "' + this.like + '"' + '\n'; else { rigaDaInserire = '); \n'; } if (rigaDaInserire != undefined) { let checkTmp = false; if (this.queryPerVista == undefined || this.queryPerVista == '') { ritornoTmp = ritornoTmp + this.faxsSimileIntestazione + '"' + this.nomeTabella + '"' + ' (' + '\n'; if (this.abilitaCreatedAt) { ritornoTmp = ritornoTmp + this.faxSimile_abilitaCreatedAt + ',' + '\n'; } if (this.abilitaDeletedAt) { ritornoTmp = ritornoTmp + this.faxSimile_abilitaDeletedAt + ',' + '\n'; } if (this.abilitaUpdatedAt) { ritornoTmp = ritornoTmp + this.faxSimile_abilitaUpdatedAt; } if (this.listaProprieta.length) ritornoTmp = ritornoTmp + ',' + '\n'; else ritornoTmp = ritornoTmp + '\n'; for (let index = 0; index < this.listaProprieta.length; index++) { const element = <PostgresProprieta>this.listaProprieta[index]; ritornoTmp = ritornoTmp + element.CostruisciCreazioneDB(this.nomeTabella); if (index + 1 < this.listaProprieta.length) ritornoTmp = ritornoTmp + ',' + '\n'; else { if (this.creaId) { ritornoTmp = ritornoTmp + ',\n'; ritornoTmp = ritornoTmp + CreaID() + '\n'; checkTmp = true; } else { ritornoTmp = ritornoTmp + '\n'; } } } if (this.creaId == true && checkTmp == false) { if (this.listaProprieta.length > 0) { ritornoTmp = ritornoTmp + ',\n'; ritornoTmp = ritornoTmp + CreaID() + '\n'; } else if (this.abilitaUpdatedAt || this.abilitaCreatedAt || this.abilitaDeletedAt) { ritornoTmp = ritornoTmp + ',\n' + CreaID() + '\n'; } else { ritornoTmp = ritornoTmp + CreaID() + '\n'; } } if (this.multiUnique) { for (let index = 0; index < this.multiUnique.length; index++) { const element = this.multiUnique[index]; let ritornoTmp2 = 'UNIQUE ('; for (let ind = 0; ind < element.colonneDiRiferimento.length; ind++) { const variab = element.colonneDiRiferimento[ind]; ritornoTmp2 = ritornoTmp2 + ' ' + variab; if (ind + 1 < element.colonneDiRiferimento.length) ritornoTmp2 = ritornoTmp2 + ','; } ritornoTmp2 = ritornoTmp2 + ' )'; if (ritornoTmp2 != 'UNIQUE ( )') { ritornoTmp = ritornoTmp + ritornoTmp2; } } } ritornoTmp = ritornoTmp + rigaDaInserire; } else { ritornoTmp = ritornoTmp + this.faxsSimileIntestazioneView + '"' + this.nomeTabella + '"' + ' ('; for (let index = this.listaProprieta.length - 1; index >= 0; index--) { const element = <PostgresProprieta>this.listaProprieta[index]; ritornoTmp = ritornoTmp + " " + element.nome + " "; if (index - 1 >= 0) ritornoTmp = ritornoTmp + '\n '; } ritornoTmp = ritornoTmp + " )\n AS " + this.queryPerVista + '\n'; } elencoQuery.push(ritornoTmp); //CREAZIONE TABELLA :CREATE NEW TABLE ECC.. /* */ //elencoQuery.push(`ALTER TABLE ${this.nomeTabella} ENABLE ROW LEVEL SECURITY;`); ritornoTmp = ''; /* Ora che la tabella esiste vado ad eseguire i trigger */ for (let index = 0; index < this.listaProprieta.length; index++) { const element = <PostgresProprieta>this.listaProprieta[index]; element.CostruisceTrigger(this.nomeTabella, elencoQuery); } if (this.abilitaDeletedAt && this.abilitaUpdatedAt && this.queryPerVista == undefined) { elencoQuery.push(TriggerUpdate(this.nomeTabella)); } if (this.abilitaDeletedAt && this.abilitaUpdatedAt && this.queryPerVista == undefined) { elencoQuery.push(TriggerDeleted_at(this.nomeTabella)); } } return ritornoTmp; } CostruisciRelazioniDB(/* client: Client */elencoQuery: string[]) { let ritorno = ''; /* if (this.estende) { const query = `ALTER TABLE ${this.nomeTabella} INHERIT ${this.estende};` EseguiQueryControllata(client, query); } */ for (let index = 0; index < this.listaProprieta.length; index++) { const element = <PostgresProprieta>this.listaProprieta[index]; const tmp = element.CostruisciRelazioniDB(this.nomeTabella); ritorno = ritorno + '\n' + tmp; elencoQuery.push(tmp); } return ritorno; } CostruisceGrant(grants: IGrant[],/* client: Client */ elencoQuery: string[]) { let ritorno = ''; for (let index = 0; index < grants.length; index++) { const element = grants[index]; if (element.colonneRiferimento && element.colonneRiferimento.length > 0) { for (let index = 0; index < element.colonneRiferimento.length; index++) { const colonna = element.colonneRiferimento[index]; const eventitesto = CostruisciEvents(element.events, colonna); const ruolitesto = CostruisciRuoli(element.ruoli); const tmp = `GRANT ${eventitesto} ON public."${this.nomeTabella}" TO ${ruolitesto};`; elencoQuery.push(tmp); ritorno = ritorno + '\n' + tmp; } } else { const eventitesto = CostruisciEvents(element.events); const ruolitesto = CostruisciRuoli(element.ruoli); const tmp = `GRANT ${eventitesto} ON public."${this.nomeTabella}" TO ${ruolitesto};`; elencoQuery.push(tmp); ritorno = ritorno + '\n' + tmp; } } for (let index = 0; index < this.listaProprieta.length; index++) { const element = <PostgresProprieta>this.listaProprieta[index]; for (let index = 0; element.grants && index < element.grants.length; index++) { const element2 = element.grants[index]; const eventitesto = CostruisciEvents(element2.events, element.nome); const ruolitesto = CostruisciRuoli(element2.ruoli); const tmp = `GRANT ${eventitesto} ON public."${this.nomeTabella}" TO ${ruolitesto};`; elencoQuery.push(tmp); ritorno = ritorno + '\n' + tmp; } } return ritorno; } Mergia(item: PostgresClasse) { super.Mergia(item); this.creaId = item.creaId; this.nomeTabella = item.nomeTabella; //this.listaProprieta = new Lista(); this.abilitaCreatedAt = item.abilitaCreatedAt; this.abilitaDeletedAt = item.abilitaDeletedAt; this.abilitaUpdatedAt = item.abilitaUpdatedAt; if (item.grants) this.grants = item.grants; } } export class ListaPostgresClasse extends ListaMetadataClasse { constructor(item?: ListaPostgresClasse) { super(); if (item) for (let index = 0; index < item.length; index++) { const element = new PostgresClasse(<PostgresClasse>item[index]); const tmp = this.Cerca(element); if (tmp) tmp.Mergia(element); } } Mergia(item: ListaPostgresClasse) { const t = super.Mergia(item); return t; } CercaSeNoAggiungi(item: PostgresClasse) { const t = super.CercaSeNoAggiungi(item); return <PostgresClasse>t; } Cerca(item: PostgresClasse) { const t = super.CercaSeNoAggiungi(item); return <PostgresClasse>t; } AggiungiElemento(item: PostgresClasse) { const t = super.AggiungiElemento(item); return <PostgresClasse>t; } } export function TriggerDeleted_at(nomeTabella: string) { return `CREATE INDEX IF NOT EXISTS idx_somethings_deleted_at ON "${nomeTabella}" (deleted_at ASC);`; } export function TriggerUpdate(nomeTabella: string) { return `DROP TRIGGER IF EXISTS tr_somethings_updated_at ON "${nomeTabella}"; CREATE TRIGGER tr_somethings_updated_at BEFORE UPDATE ON "${nomeTabella}" FOR EACH ROW EXECUTE PROCEDURE update_updated_at_column();` } export function CostruisciFunzione(item: any, nomeFunzioneCheck: string, nomePolicy: string, typeFunctionCheck: string, carattere: string | 'CK' | 'US', /* client: Client */elencoQuery: string[]): string { let corpoFunzione = ''; if (item) { if (typeof item === 'function') { const strg = String(item); const tt = strg.indexOf('{'); const t1 = strg.substring(tt + 1, strg.length); const t2 = t1.lastIndexOf('}'); const t3 = t1.substring(0, t2 - 1); corpoFunzione = t3; console.log(strg); } else { corpoFunzione = String(item); } const tmp = ` CREATE OR REPLACE FUNCTION "${carattere}_FN_${nomeFunzioneCheck}_xTR_${nomePolicy}"() RETURNS boolean AS $$ ${corpoFunzione} $$ LANGUAGE "${typeFunctionCheck ?? 'plv8'}"; `; const ritorno = '' + carattere + '_FN_' + nomeFunzioneCheck + '_xTR_' + nomePolicy + ''; //await EseguiQueryControllata(client, tmp); elencoQuery.push(tmp); return ritorno; } return ''; } export function CostruisciRuoli(ruoli: string[]) { let ritorno = ''; for (let index = 0; index < ruoli.length; index++) { const element = ruoli[index]; ritorno = ritorno + element; if (ruoli.length >= 2 && index + 1 < ruoli.length) { ritorno = ritorno + ', '; } } return ritorno; } export function CostruisciEvents(events: typeGrantEvent[], nome?: string) { let ritorno = ' '; for (let index = 0; index < events.length; index++) { const element = events[index]; if (nome) { ritorno = ritorno + element + '("' + nome + '")'; } else { ritorno = ritorno + element; } if (events.length >= 2 && index + 1 < events.length) { ritorno = ritorno + ', '; } } return ritorno; } export function CreaID() { return "id SERIAL PRIMARY KEY"; } export function TriggerUpdate_updated_at_column() { return `CREATE OR REPLACE FUNCTION update_updated_at_column() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = now(); RETURN NEW; END; $$ language 'plpgsql';`; } export function CreateDataBase(nomeDB: string) { return `CREATE DATABASE ${nomeDB};`; } export function DropDataBase(nomeDB: string) { return `DROP DATABASE IF EXISTS "${nomeDB}";`; } export function DropAllTable() { return `DROP SCHEMA public CASCADE; CREATE SCHEMA public; GRANT ALL ON SCHEMA public TO postgres; GRANT ALL ON SCHEMA public TO public; COMMENT ON SCHEMA public IS 'standard public schema';`; }