Reputation: 69
My problem is the next:
When I try to chain promises Q within a connection pool with Oracle oracledb driver not running in the correct order.
Paste the code to explain better:
var Q = require('q');
var oracledb = require("oracledb");
oracledb.autoCommit = true;
var deferedPool;
/**
* @function ejecutaPool
* @param {Object} pool Objeto que contiene el pool de conexiones a base de datos.
* @param {String} sql Cadena de texto con la consulta SQL.
* @param {Array} parametros Array con los parámetros que se bindean en la consulta SQL.
* @description Crea una promesa en la cual se recupera un Pool de conexiones a base de datos en las cuales se conecta a la base de * datos y devuelve el mensaje de conexión creada o un error en el caso en el que se produzca un error. Ejecuta la consulta SQL y * devuelve el resultado de la misma o un error en el caso en el que se produzca un error. Se desconecta de la base de datos y * devuelve el mensaje de conexión terminada o un error en el caso en el que se produzca un error. La promesa devuelve el resultado * de la ejecución de la consulta SQL.
*/
exports.ejecutaPool = function(pool,sql,parametros) {
deferedPool = Q.defer();
pool.getConnection(function(err, connection) {
console.log("1.- Obteniendo conexion");
if (err) {
console.log("ERROR: No se puede obtener la conexion: ", err);
deferedPool.reject(err);
return;
}else{
console.log("Conexion realizada");
}
if (typeof pool !== "undefined") {
console.log("INFO: Conexiones abiertas: " + pool.connectionsOpen);
console.log("INFO: Conexiones en uso: " + pool.connectionsInUse);
}
connection.execute(
sql,
parametros,
{outFormat: oracledb.ARRAY},
function (err, result){
console.log("2.- Ejecutando consulta");
if (err){
console.log(err.message);
deferedPool.reject(err);
} else {
console.log('2.1.- Resultado consulta: ' + JSON.stringify(result));
deferedPool.resolve(result); //result.ejecuta;
}
connection.release(function(err) {
console.log('3.- Liberando conexion');
if (err) {
deferedPool.reject(err);
}else {
console.log("Conexion terminada"); //result.libera;
}
});
});
});
return deferedPool.promise;
}
This is the file: apiOraclePool.js
And the bellow is the file: pruebasApiOracle.js
var db = require('./apiOraclePool.js');
var dbconfig = require('./dbconfig.js');
var oracledb = require('oracledb');
var Q = require('q');
var sqlSelect = "SELECT * FROM CERTS";
console.log(sqlSelect);
var sqlInsert = "begin insert into CERTS (ID, NOMBRE, APELLIDOS, NIF) values (:id, :nm, :ap, :nif); commit; exception when DUP_VAL_ON_INDEX then ROLLBACK; end;";
console.log(sqlInsert);
var parametrosSelect = [];
var parametrosInsert = ['7','ooo','ppp ttt','01928364R'];
var sqlUpdate = "UPDATE CERTS SET NOMBRE = 'Jose' WHERE NOMBRE = 'Pepe'";
console.log(sqlUpdate);
var parametrosUpdate = [];
var sqlDelete = "DELETE FROM CERTS WHERE NOMBRE = 'Jose'";
console.log(sqlDelete);
var parametrosDelete = [];
var sqlProcedure = "BEGIN testproc(:i, :io, :o); END;";
console.log(sqlProcedure);
var parametrosProcedure = {
i: 'Chris', // bind type is determined from the data type
io: { val: 'Jones', dir : oracledb.BIND_INOUT },
o: { type: oracledb.NUMBER, dir : oracledb.BIND_OUT },
};
/*var promesaInsert = db.ejecutaInsert(sqlInsert,parametrosInsert);
promesaInsert.then(tratarResultadoInsert).done();
var promesaSelect = db.ejecutaSelect(sqlSelect,parametrosSelect);
promesaSelect.then(tratarResultadoSelect).done();
var promesaUpdate = db.ejecutaUpdate(sqlUpdate,parametrosUpdate);
promesaUpdate.then(tratarResultadoUpdate).done();
var promesaDelete = db.ejecutaDelete(sqlDelete,parametrosDelete);
promesaDelete.then(tratarResultadoDelete).done();*/
oracledb.createPool({
user: dbconfig.user,
password: dbconfig.password,
connectString: dbconfig.connectString,
poolMax: 44,
poolMin: 1,
poolIncrement: 1,
poolTimeout: 4
}, function(err, pool) {
console.log(pool);
if (err) {
console.log("ERROR: ", new Date(), ": createPool() callback: " + err.message);
return;
}
var promesaUpdate = db.ejecutaPool(pool,sqlUpdate,parametrosUpdate);
var promesaSelect = db.ejecutaPool(pool,sqlSelect,parametrosSelect);
var promesaInsert = db.ejecutaPool(pool,sqlInsert,parametrosInsert);
var promesaDelete = db.ejecutaPool(pool,sqlDelete,parametrosDelete);
var promesaProcedure = db.ejecutaPool(pool,sqlProcedure,parametrosProcedure);
/*
var promesa= Q();
var promesaUpdate = Q().then(function(){ console.log('1. Update ejecutado'); } );
var promesaSelect = Q().then(function(){ console.log('2. Select ejecutado '); } );
var promesaInsert = Q().then(function(){ console.log('3. Insert ejecutado '); } );
var promesaDelete = Q().then(function(){ console.log('4. Delete ejecutado '); } );
var promesaProcedure = Q().then(function(){ console.log('5. Procedure ejecutado '); } );
*/
//promesa.then(promesaUpdate).then(promesaSelect).then(promesaInsert).then(promesaDelete).then(promesaProcedure);//.done();
promesaUpdate.then(tratarResultadoUpdate).then(promesaSelect).then(tratarResulta doSelect).then(promesaInsert).then(tratarResultadoInsert).then(promesaDelete).then(tratarResultadoDelete).then(promesaProcedure).then(tratarResultadoProcedure);
var promesa = Q.defer();
var resultadoUpdate = function (texto){
promesa.resolve(console.log(texto));
return promesa.promise;
}
var resultadoSelect = function (texto){
promesa.resolve(console.log(texto));
return promesa.promise;
}
var resultadoInsert = function (texto){
promesa.resolve(console.log(texto));
return promesa.promise;
}
var resultadoDelete = function (texto){
promesa.resolve(console.log(texto));
return promesa.promise;
}
var resultadoProcedure = function (texto){
promesa.resolve(console.log(texto));
return promesa.promise;
}
/*
promesaUpdate("1. Estoy en la consulta Update").then(promesaSelect("2. Estoy en la consulta Select")).then(promesaInsert("3. Estoy en la consulta Insert")).then(promesaDelete("4. Estoy en la consulta Delete"));
*/
/*
var promesaSelect = Q().then(function(){ console.log('2. Select ejecutado '); } );
var promesaInsert = Q().then(function(){ console.log('3. Insert ejecutado '); } );
var promesaDelete = Q().then(function(){ console.log('4. Delete ejecutado '); } );
var promesaProcedure = Q().then(function(){ console.log('5. Procedure ejecutado '); } );
*/
});
function tratarResultadoUpdate (resultadoUpdate){
console.log("Filas actualizadas: " + resultadoUpdate.rowsAffected);
}
function tratarResultadoSelect (resultadoSelect){
console.log("Respuesta de la base de datos:" + resultadoSelect.rows.length);
if(resultadoSelect.rows.length > 0){
for (var i=0;i < resultadoSelect.rows.length; i++){
console.log(resultadoSelect.rows[i]);
}
}
}
function tratarResultadoInsert (resultadoInsert){
console.log(resultadoInsert.outBinds);
}
function tratarResultadoDelete (resultadoDelete){
console.log("Filas eliminadas: " + resultadoDelete.rowsAffected);
}
function tratarResultadoProcedure (resultadoProcedure){
console.log(resultadoProcedure.outBinds);
}
Thank you in advance.
Upvotes: 0
Views: 526
Reputation: 41
I suspect you're running into trouble mixing promises with callbacks. I do something similar with Bluebird:
var Oracle = require('oracledb');
var Promise = require('bluebird');
function createPool(config) {
return new Promise(function(resolve, reject) {
console.log('creating pool ' + JSON.stringify(config));
Oracle.createPool(config,
function(err, pool) {
if (err) {
return reject(err);
}
resolve(pool);
});
});
}
function getConnection(pool) {
return new Promise(function(resolve, reject) {
pool.getConnection(function(err, connection) {
if (err) {
return reject(err);
}
resolve(connection);
});
});
}
function _innerExecute(sql, bindParams, options, connection) {
return new Promise(function(resolve, reject) {
connection.execute(sql, bindParams, options, function(err, results) {
if (err) {
reject(err);
}
resolve(results);
});
});
}
function execute(sql, bindParams, options, pool) {
return using (getConnection(pool), function(connection) {
return _innerExecute(sql, bindParams, options, connection);
});
}
function testSelect() {
var config = {
connectString: '//localhost:1521/test',
user: 'test',
password: 'test'
};
var pool;
createPool(config)
.then(function(p) { pool = p; })
.catch(function(e) { console.log(e); });
execute('SELECT * FROM EMPLOYEES', {}, {}, pool)
.then(function(results) {
console.log('results = ' + results);
})
.catch(function(error) { console.log(e); });
}
This is a simplified example, but it should give an idea of an approach that works. It also adds the benefit of automatically releasing connections.
You might want to take a look at https://jsao.io/2015/03/making-a-wrapper-module-for-the-node-js-driver-for-oracle-database/ for a similar but somewhat more comprehensive approach to wrap oracledb with promises using es6-promises.
Upvotes: 1