UNPKG

@digigov-oss/auditrecord-postgresql-engine

Version:

PostgreSQL storage database for use with audit mechanism of GSIS

157 lines (140 loc) 6.03 kB
//To check this engine you have to have a PostgreSQL database installed and running. //The database must be configured to allow connections from the host that the application is running on. //The database must also have the following table: //table audit_records // auditUnit: varchar(255); // auditTransactionId: varchar(255); // auditProtocol: varchar(255); // auditTransactionDate: varchar(20); // auditUserIp: varchar(16); // auditUserId: varchar(255); // if you do not provide the table name, the engine will create it for you. //You can use Docker to run PostgreSQL for your tests. //`docker run -d --name audit-postgres -e POSTGRES_PASSWORD=audit --network host postgres` //`docker exec -it audit-postgres psql -U postgres -h localhost -c "CREATE DATABASE audit;"` //`docker exec -it audit-postgres psql -U postgres -h localhost -c "CREATE TABLE audit_log (auditUnit varchar(255), auditTransactionId varchar(255), auditProtocol varchar(255), auditTransactionDate varchar(20), auditUserIp varchar(16), auditUserId varchar(255));"` //You can also map the fields of already existent table to the fields in the audit log. import Client from 'pg-native'; import { AuditRecord, AuditEngine, DatabaseSettings, PNRESETTYPES } from '@digigov-oss/gsis-audit-record-db'; /** * @description AuditEngine implementation * @note This class is used to implement the methods that must be implemented by the AuditEngine * @class PostgreSqlEngine * @implements AuditEngine * @param {string} connectionString - connect to db via connection string * @param {DatabaseSettings} dbSettings - database settings */ export class PostgreSqlEngine implements AuditEngine { #table: string; #columnNames:AuditRecord; #client: any; /** * @description constructor * @param {string} connectionString - connect to db via connection string * @param {DatabaseSettings} settings - settings for the database * @param {AuditRecord} columnNames - column names * @memberof PostgreSqlEngine */ constructor(connectionString:string = "", dbSettings: DatabaseSettings={}) { const connection = connectionString!=""?{connectionString}:{}; this.#table = dbSettings.tableName || "audit_records"; this.#columnNames = dbSettings.columns || { auditUnit: "auditUnit", auditTransactionId: "auditTransactionId", auditProtocol: "auditProtocol", auditTransactionDate: "auditTransactionDate", auditUserIp: "auditUserIp", auditUserId: "auditUserId" } this.#client = new Client(connection); this.#client.connectSync(); if (!dbSettings.tableName) { this.#client.querySync("CREATE TABLE IF NOT EXISTS "+this.#table+" ("+this.#columnNames.auditUnit+" varchar(255), "+this.#columnNames.auditTransactionId+" varchar(255), "+this.#columnNames.auditProtocol+" varchar(255), "+this.#columnNames.auditTransactionDate+" varchar(20), "+this.#columnNames.auditUserIp+" varchar(16), "+this.#columnNames.auditUserId+" varchar(255));"); } } /** * @description Store a record in the database * @param {AuditRecord} record - record to be stored * @returns {AuditRecord} - the record stored * @memberof FileEngine * @method put */ put(record: AuditRecord): AuditRecord { const data = JSON.stringify(record, null, 2); try { this.#client.querySync("INSERT INTO "+this.#table+" ("+this.#columnNames.auditUnit+","+this.#columnNames.auditTransactionId+","+this.#columnNames.auditProtocol+","+this.#columnNames.auditTransactionDate+","+this.#columnNames.auditUserIp+","+this.#columnNames.auditUserId+") \ VALUES ('"+record.auditUnit+"','"+record.auditTransactionId+"','"+record.auditProtocol+"','"+record.auditTransactionDate+"','"+record.auditUserIp+"','"+record.auditUserId+"');"); return record; } catch (error) { throw error; } } /** * @description Get a record from the database * @param auditTransactionId: string - transaction id * @returns {AuditRecord} * @memberof FileEngine * @method get */ get(auditTransactionId: string): AuditRecord { try { let data = {} const res = this.#client.querySync("SELECT * FROM "+this.#table+" WHERE "+this.#columnNames.auditTransactionId+"='"+auditTransactionId+"';"); data = res[0]; return data; } catch (error) { throw error; } } /** * @description Generate a new sequence number * @param path * @returns number * @memberof FileEngine * @method seq */ seq():number { try { this.#client.querySync("CREATE SEQUENCE IF NOT EXISTS "+this.#table+"_seq START 1"); const res = this.#client.querySync("SELECT nextval('"+this.#table+"_seq');"); return res[0].nextval; } catch (error) { throw error; } } /** * @description Generate a new protocol number * @param path * @returns string * @memberof FileEngine * @method protocol */ pn(pnreset?:PNRESETTYPES): string { try { let protocol_split = "aion"; let protocol_date = new Date().toISOString().split('T')[0]; switch(pnreset){ case "daily": protocol_split = protocol_date; break; case "monthly": protocol_split = protocol_date.split('-')[0]+"-"+protocol_date.split('-')[1]; break; case "yearly": protocol_split = protocol_date.split('-')[0]; break; case "innumerable": protocol_split = "aion"; break; } const seqName = "prot"+protocol_split.replace(/-/g, ''); //create sequence for protocol_split if not exists this.#client.querySync("CREATE SEQUENCE IF NOT EXISTS "+seqName+"_seq START 1"); const res = this.#client.querySync("SELECT nextval('"+seqName+"_seq');"); return res[0].nextval+"/"+protocol_date; } catch (error) { throw error; } } } export default PostgreSqlEngine;