UNPKG

tuain-dbpool-mysql

Version:

Database pool class to perform standard database operations on MySQL databases using a common interface for simple operations as part of the Tuain Application Development Framework

152 lines (140 loc) 5.2 kB
const mysql = require('mysql'); const DatabasePool = require('tuain-dbpool-generic'); const modErrs = { mysql: { procedureError: ['04', 'Error en ejecución de procedimiento'], generalError: ['99', 'Error general de base de datos'], }, }; const legacyModErrs = { moduleName: 'dbpool-lib-mysql', moduleCode: '01', defaultLanguage: 'es', contexts: { mysql: { contextCode: '01', items: { procedureError: { errorCode: '04', defaultMessage: 'Error en ejecución de procedimiento', }, generalError: { errorCode: '99', defaultMessage: 'Error general de base de datos', }, }, }, }, }; class DatabasePoolMySQL extends DatabasePool { constructor(poolAttributes, logger, errors) { super(logger, errors); if (this.legacyErrors) { this.legacyErrors = true; this.errors.addModuleSet(legacyModErrs); } else { this.errors.addModuleSet('dbpool-lib-mysql', modErrs); } this.parameters = poolAttributes; this.engineName = 'mysql'; this.knexParameters = { client: this.engineName, connection: { user: poolAttributes.user, password: poolAttributes.password, host: poolAttributes.host, port: poolAttributes.port, database: poolAttributes.database, }, pool: { min: poolAttributes.pool.min, max: poolAttributes.pool.max }, }; } async open() { const { knex, setupPaginator } = this; this.knexPool = knex(this.knexParameters); if (!this.parameters?.avoidPaginator) { setupPaginator(this.knexPool); } } async executeRawQuery(sql) { const rawQueryResult = await this.knexPool.raw(sql); return rawQueryResult[0]; } async getPool() { return this.knexPool; } async executeProcedure(queryObject, recordFields) { const sentenceInsertsOutParams = []; const sentenceInsertsInParams = []; let setOutputVarSentence = ''; let procedureFieldsSentence = ''; let getOutputVarSentence = ''; queryObject.procedureFields.forEach((parameterName) => { let procedureFieldsSegment = ''; let setOutputVarSegment = ''; let fieldValue = ''; if (parameterName[0] === '@') { const fieldAlias = parameterName.substring(1); // Es una variable de salida, se incluye en la asignación inicial setOutputVarSegment = `SET ${parameterName} = ?; `; if (recordFields && recordFields[fieldAlias] != null) { fieldValue = recordFields[fieldAlias]; } sentenceInsertsOutParams.push(fieldValue); procedureFieldsSegment += parameterName; getOutputVarSentence += getOutputVarSentence ? ', ' : ''; getOutputVarSentence += parameterName; } else { const requiredFields = queryObject.requiredFields || queryObject.procedureFields; if (requiredFields.indexOf(parameterName) >= 0 && (!recordFields || recordFields[parameterName] == null)) { throw new Error(`Parametros insuficientes ${parameterName}`); } fieldValue = recordFields[parameterName]; // Es una variable solamente de entrada procedureFieldsSegment += '?'; sentenceInsertsInParams.push(fieldValue); } procedureFieldsSentence += procedureFieldsSentence ? ', ' : ''; procedureFieldsSentence += procedureFieldsSegment; setOutputVarSentence += setOutputVarSegment; }); getOutputVarSentence = getOutputVarSentence ? `SELECT ${getOutputVarSentence}` : ''; setOutputVarSentence = setOutputVarSentence ? ` ${setOutputVarSentence}` : ''; let sqlSentence = `${setOutputVarSentence}CALL ${queryObject.procedureName}`; sqlSentence += `( ${procedureFieldsSentence} ); ${getOutputVarSentence}`; // Se formatea la sentencia que se va a ejecutar en la base de datos const finalSql = mysql.format(sqlSentence, sentenceInsertsOutParams.concat(sentenceInsertsInParams)); try { this.logger.log({ level: 'silly', message: `Ejecución procedimiento: ${finalSql}`, }); const resp = await this.knexPool.raw(finalSql); const resultData = resp[0][0]; this.logger.log({ level: 'silly', message: `Respuesta del procedimiento: ${JSON.stringify(resultData)}`, }); const [procResult] = resultData; if (procResult.errorCode !== 0) { const errorDetail = `${procResult.errorCode}`; const errorObj = (this.legacyErrors) ? this.errors.get(legacyModErrs.contexts.mysql.items.procedureError, errorDetail) : this.errors.get(modErrs.mysql.procedureError, errorDetail); return [errorObj, null]; } return [null, procResult]; } catch (err) { this.logger.log({ level: 'error', message: err, }); const errorDetail = `${err.message}/${err.stack}`; const errorObj = (this.legacyErrors) ? this.errors.get(legacyModErrs.contexts.mysql.items.procedureError, errorDetail) : this.errors.get(modErrs.mysql.procedureError, errorDetail); return [errorObj, null]; } } } module.exports = DatabasePoolMySQL;