UNPKG

@digigov-oss/auditrecord-couchdb-engine

Version:

CouchDB storage database for use with audit mechanism of GSIS

168 lines (156 loc) 4.94 kB
import Nano from "nano"; 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 CouchDBEngine * @implements AuditEngine * @param {string} connectionString - connect to db via connection string `http://user:pass@$dbHost:dbPort` * @param {DatabaseSettings} dbSettings - database settings (please note the tableName is actualy a DB name for couchdb) */ export class CouchDBEngine implements AuditEngine { #dbname: string; #connection:string; #client: any; #pnreset:PNRESETTYPES; private async couch(): Promise<any> { const nano = Nano(this.#connection); const dbList = await nano.db.list(); // list all databases try { if (!dbList.includes(this.#dbname)) { // create a new DB if database doesn't exist. await nano.db.create(this.#dbname); const db = nano.use(this.#dbname); console.log("database created successfully"); return db; } else { const db = nano.use(this.#dbname); return db; } } catch (err: any) { throw new Error(err); } }; /** * @description constructor * @param {string} connectionString - connect to couchdb via connection string * @param {DatabaseSettings} settings - settings for the database * @memberof CouchDBEngine */ constructor(connectionString:string = "", dbSettings: DatabaseSettings={},pnreset:PNRESETTYPES="innumerable") { this.#connection = connectionString!=""?connectionString:"http://admin:admin@localhost:5984"; this.#dbname = dbSettings.tableName || "audit_records"; //this is actualy a DB name const init = async () => { return await this.couch(); } this.#client = init(); this.#pnreset = pnreset; } /** * @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 { return this.#client.then(async (db:any) => { try { const doc = { _id: record.auditTransactionId, ...record }; const _rdoc = await db.insert(doc); 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 { return this.#client.then(async (db:any) => { try { const rdoc = await db.get(auditTransactionId); return rdoc; } catch (error) { throw error; } }); } /** * @description Generate a new sequence number * @param path * @returns number * @memberof CouchDBEngine * @method seq */ seq():number { // from update_seq get the numeric part and add 1 return this.#client.then(async (db:any) => { try { const rdoc = await db.info(); //get integer part from 1-xxxx const seq = parseInt(rdoc.update_seq.split("-")[0]); return seq+1; } catch (error) { throw error; } }); } /** * @description Generate a new protocol number * @param path * @returns string * @memberof CouchDBEngine * @method protocol */ pn():string { return this.#client.then(async (db:any) => { const pnreset = this.#pnreset; 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; } //Create indexes based on pnreset daily, monthly, yearly, innumerable const seqName = "prot_"+protocol_split.replace(/-/g, ''); //create document in couchdb let doc = { _id: seqName, rev: "1" }; //get the document try { doc = await db.get(seqName); } catch (error) { //document doesn't exist } doc = await db.insert(doc); const protocol = parseInt((doc as any)['rev'].split("-")[0]); return protocol+"/"+protocol_date; } catch (error) { throw error; } }); } } export default CouchDBEngine;