2015-09-21 11 views
0

我的問題是下一個:Q承諾不正確的順序連接池裏面有OracleDB的驅動程序運行的NodeJS

當我試圖鏈的承諾Q隨甲骨文OracleDB的驅動程序以正確的順序沒有運行連接池內。

粘貼代碼,以更好地解釋:

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; 
} 

這是文件:apiOraclePool.js

而且波紋管的文件: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); 
} 

感謝您在提前。

回答

1

我懷疑你遇到了混淆承諾和回調的麻煩。我做藍鳥類似的事情:

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); }); 
} 

這是一個簡單的例子,但它應該給的作品的方法的想法。它還增加了自動釋放連接的好處。

你可能想看看https://jsao.io/2015/03/making-a-wrapper-module-for-the-node-js-driver-for-oracle-database/的一個類似的,但有點更全面的方法來使用es6-promises包裝帶有promise的oracledb。

+0

儘管此鏈接可能會回答問題,但最好在此處包含答案的基本部分,並提供供參考的鏈接。如果鏈接頁面更改,則僅鏈接答案可能會失效。 –

+0

增加了一個例子 – jeffm13

+0

在'execute'函數中'return using'做了什麼?我從來沒有在JavaScript中看到過,而且在查找任何有關其用法的文檔時遇到困難。 –