UNPKG

@wmfs/tymly-pg-plugin

Version:

Replace Tymly's out-the-box memory storage with PostgreSQL

90 lines (73 loc) 2.86 kB
'use strict' const _ = require('lodash') const path = require('path') const schema = require('./schema.json') const generateTriggerStatement = require('./generate-trigger-statement') const debug = require('debug')('@wmfs/tymly-pg-plugin') const pgInfo = require('@wmfs/pg-info') class AuditService { boot (options, callback) { this.models = options.blueprintComponents.models || {} this.client = options.bootedServices.storage.client this.schemaNames = options.bootedServices.storage.schemaNames const pgScripts = options.blueprintComponents.pgScripts || {} this.auditFunctions = Object.keys(pgScripts) .map(script => path.parse(pgScripts[script].filename).name) .filter(filename => filename.split('-')[0] === 'audit') .map(filename => { debug(`Found audit function: ${filename.substring(filename.indexOf('-') + 1)}`) return filename.substring(filename.indexOf('-') + 1) }) this.updateTriggers(options.messages) .then(() => callback(null)) .catch(err => callback(err)) } // boot async updateTriggers (messages) { const currentDbStructure = await pgInfo({ client: this.client, schemas: this.schemaNames }) const allInstallers = this.auditFunctions .map(func => { messages.info(`Applying ${func} function`) const installers = Object.keys(this.models) .map(model => this.installTrigger(func, model, currentDbStructure, messages)) .filter(p => !!p) if (installers.length === 0) { messages.detail('Already in place') return } return Promise.all(installers) }) return Promise.all(allInstallers) } // updateTriggers installTrigger (func, model, currentDbStructure, messages) { const audit = this.models[model].audit !== false const namespace = _.snakeCase(this.models[model].namespace) const name = _.snakeCase(this.models[model].name) const triggerName = `${namespace}_${name}_auditor` const modelTriggers = currentDbStructure.schemas[namespace].tables[name].triggers const hasTrigger = Object.keys(modelTriggers).includes(triggerName) const action = (!hasTrigger && audit) ? 'ADD' : ((hasTrigger && !audit) ? 'REMOVE' : '') debug(`Model: ${model}, Wants to audit: ${audit}, Already has trigger: ${hasTrigger}, Action: ${action}`) const triggerSQL = generateTriggerStatement({ model: this.models[model], function: func, action: action }) if (!triggerSQL) { return null } messages.detail( action === 'ADD' ? `Adding trigger to ${model}` : `Removing trigger from ${model}` ) return this.client.query(triggerSQL) } // installTrigger } module.exports = { schema: schema, serviceClass: AuditService, bootAfter: ['storage', 'statebox'] }