ibm_db = function (options)
{
return new Database(options);
}n/a
function Database(options)
{
var self = this;
options = options || {};
self.odbc = (options.odbc) ? options.odbc : ((ENV) ? ENV : new odbc.ODBC());
if(!ENV) ENV = self.odbc;
self.queue = new SimpleQueue();
self.fetchMode = options.fetchMode || null;
self.connected = false;
self.connectTimeout = options.connectTimeout || null;
self.systemNaming = options.systemNaming;
}...
### Using node < v0.10 on Linux
Be aware that through node v0.9 the uv_queue_work function, which is used to
execute the ODBC functions on a separate thread, uses libeio for its thread
pool. This thread pool by default is limited to 4 threads.
This means that if you have long running queries spread across multiple
instances of ibmdb.Database() or using odbc.Pool(), you will only be able to
have 4 concurrent queries.
You can increase the thread pool size by using @developmentseed's [node-eio]
(https://github.com/developmentseed/node-eio).
#### install:
```bash
...function ODBC() { [native code] }...
var odbc = require("bindings")("odbc_bindings")
, SimpleQueue = require("./simple-queue")
, util = require("util")
, Readable = require('stream').Readable
, Q = require('q');
// Call of odbc.ODBC() loads odbc library and allocate environment handle.
// All calls of new Database() should use this same odbc unless passed as
// options.odbc. ENV will keep value of this odbc after first call of Database.
var ENV;
module.exports = function (options)
{
return new Database(options);
...function ODBCConnection() { [native code] }n/a
function ODBCResult() { [native code] }n/a
function ODBCStatement() { [native code] }n/a
function Pool(_options) {
var self = this;
self.options = {};
self.maxPoolSize = 0;
if(_options)
{
if(_options.idleTimeout && !isNaN(_options.idleTimeout))
self.options.idleTimeout = _options.idleTimeout;
if(_options.autoCleanIdle)
self.options.autoCleanIdle = _options.autoCleanIdle;
if(_options.maxPoolSize)
self.maxPoolSize = _options.maxPoolSize;
if(_options.connectTimeout)
self.options.connectTimeout = _options.connectTimeout;
if(_options.systemNaming)
self.options.systemNaming=_options.systemNaming;
}
self.index = Pool.count++;
self.availablePool = {};
self.usedPool = {};
self.poolSize = 0;
if(!ENV) ENV = new odbc.ODBC();
self.odbc = ENV;
self.options.connectTimeout = self.options.connectTimeout || 60;
}...
### Using node < v0.10 on Linux
Be aware that through node v0.9 the uv_queue_work function, which is used to
execute the ODBC functions on a separate thread, uses libeio for its thread
pool. This thread pool by default is limited to 4 threads.
This means that if you have long running queries spread across multiple
instances of ibmdb.Database() or using odbc.Pool(), you will only be able to
have 4 concurrent queries.
You can increase the thread pool size by using @developmentseed's [node-eio]
(https://github.com/developmentseed/node-eio).
#### install:
```bash
...close = function (db)
{
if(db && typeof(db) === "object")
{
for(key in db)
{
delete db[key];
}
delete db;
db = undefined;
}
}...
* Update build.zip and defautl connection timeout. (Bimal Jha)
* Exit with error code on installation errors, to allow failure detection by automated build tools (Michael Szlapa)
* Add pool related test files. (Bimal Jha)
* Update conn.close() for Pool to avoid reconnection before moving to available pool.
Add pool related test files and update existing test files. (Bimal Jha)
* update examples (Bimal Jha)
* Updating the new build.zip for windows (Bimal Jha)
* delete build.zip file on ntx64 after unzip (bimaljha)
...debug = function (x) {
if(x) {
exports.debug = true;
console.log("node-ibm_db logs enabled.");
}
else {
exports.debug = false;
console.log("node-ibm_db logs disabled.");
}
}...
14. [.bindSync(bindingParameters)](#bindSyncApi)
15. [.beginTransaction(callback)](#beginTransactionApi)
16. [.beginTransactionSync()](#beginTransactionSyncApi)
17. [.commitTransaction(callback)](#commitTransactionApi)
18. [.commitTransactionSync()](#commitTransactionSyncApi)
19. [.rollbackTransaction(callback)](#rollbackTransactionApi)
20. [.rollbackTransactionSync()](#rollbackTransactionSyncApi)
21. [.debug(value)](#enableDebugLogs)
* [**Connection Pooling APIs**](#PoolAPIs)
* [**bindingParameters**](#bindParameters)
* [**CALL Statement**](#callStmt)
* [**Build Options**](#buildOptions)
...getElapsedTime = function (){
var tstamp = (new Date() - ibmdbStartTime)/1000.0;
//process.stdout.write(tstamp + " :: ");
return (tstamp + " :: ");
}n/a
open = function (connStr, options, cb)
{
var db, deferred;
var DBFactory = function(options) {
return new Database(options);
};
if (!cb && typeof options !== 'function')
{
if(!options)
{
options = null;
}
db = DBFactory(options);
deferred = Q.defer();
db.open(connStr, function(err) {
if (err)
{
deferred.reject(err);
}
else
{
deferred.resolve(db);
}
});
return deferred.promise;
}
else if (typeof options === 'function')
{
cb = options;
options = null;
}
db = DBFactory(options);
db.open(connStr, function (err) {
cb(err, db);
});
}...
## Quick Example
------------------
```javascript
var ibmdb = require('ibm_db');
ibmdb.open("DATABASE=<dbname>;HOSTNAME=<myhost>;UID=db2user;
PWD=password;PORT=<dbport>;PROTOCOL=TCPIP", function (err,conn) {
if (err) return console.log(err);
conn.query('select 1 from sysibm.sysdummy1', function (err, data) {
if (err) console.log(err);
else console.log(data);
conn.close(function () {
...openSync = function (connStr, options)
{
var db = new Database(options);
db.openSync(connStr);
return db;
}...
```javascript
var Database = require("ibm_db").Database
, ibmdb = new Database();
```
1. [.open(connectionString, [options,] callback)](#openApi)
2. [.openSync(connectionString)](#openSyncApi)
3. [.query(sqlQuery [, bindingParameters], callback)](#queryApi)
4. [.querySync(sqlQuery [, bindingParameters])](#querySyncApi)
5. [.queryStream(sqlQuery [, bindingParameters])](#queryStreamApi)
6. [.close(callback)](#closeApi)
7. [.closeSync()](#closeSyncApi)
8. [.prepare(sql, callback)](#prepareApi)
9. [.prepareSync(sql)](#prepareSyncApi)
...function SimpleQueue() {
var self = this;
self.fifo = [];
self.executing = false;
}n/a
function Database(options)
{
var self = this;
options = options || {};
self.odbc = (options.odbc) ? options.odbc : ((ENV) ? ENV : new odbc.ODBC());
if(!ENV) ENV = self.odbc;
self.queue = new SimpleQueue();
self.fetchMode = options.fetchMode || null;
self.connected = false;
self.connectTimeout = options.connectTimeout || null;
self.systemNaming = options.systemNaming;
}...
### Using node < v0.10 on Linux
Be aware that through node v0.9 the uv_queue_work function, which is used to
execute the ODBC functions on a separate thread, uses libeio for its thread
pool. This thread pool by default is limited to 4 threads.
This means that if you have long running queries spread across multiple
instances of ibmdb.Database() or using odbc.Pool(), you will only be able to
have 4 concurrent queries.
You can increase the thread pool size by using @developmentseed's [node-eio]
(https://github.com/developmentseed/node-eio).
#### install:
```bash
...beginTransaction = function (cb)
{
var self = this
, deferred = null
, onBeginTransaction;
if(!cb)
{
deferred = Q.defer();
onBeginTransaction = function(err)
{
if(err)
{
deferred.reject(err);
}
else
{
deferred.resolve(true);
}
};
}
self.conn.beginTransaction(deferred ? onBeginTransaction : cb);
self.conn.inTransaction = true;
return deferred ? deferred.promise : self;
}...
8. [.prepare(sql, callback)](#prepareApi)
9. [.prepareSync(sql)](#prepareSyncApi)
10. [.execute([bindingParameters], callback)](#executeApi)
11. [.executeSync([bindingParameters])](#executeSyncApi)
12. [.executeNonQuery([bindingParameters], callback)](#executeNonQueryApi)
13. [.bind(bindingParameters, callback)](#bindApi)
14. [.bindSync(bindingParameters)](#bindSyncApi)
15. [.beginTransaction(callback)](#beginTransactionApi)
16. [.beginTransactionSync()](#beginTransactionSyncApi)
17. [.commitTransaction(callback)](#commitTransactionApi)
18. [.commitTransactionSync()](#commitTransactionSyncApi)
19. [.rollbackTransaction(callback)](#rollbackTransactionApi)
20. [.rollbackTransactionSync()](#rollbackTransactionSyncApi)
21. [.debug(value)](#enableDebugLogs)
...beginTransactionSync = function ()
{
var self = this;
self.conn.beginTransactionSync();
self.conn.inTransaction = true;
return self;
}...
9. [.prepareSync(sql)](#prepareSyncApi)
10. [.execute([bindingParameters], callback)](#executeApi)
11. [.executeSync([bindingParameters])](#executeSyncApi)
12. [.executeNonQuery([bindingParameters], callback)](#executeNonQueryApi)
13. [.bind(bindingParameters, callback)](#bindApi)
14. [.bindSync(bindingParameters)](#bindSyncApi)
15. [.beginTransaction(callback)](#beginTransactionApi)
16. [.beginTransactionSync()](#beginTransactionSyncApi)
17. [.commitTransaction(callback)](#commitTransactionApi)
18. [.commitTransactionSync()](#commitTransactionSyncApi)
19. [.rollbackTransaction(callback)](#rollbackTransactionApi)
20. [.rollbackTransactionSync()](#rollbackTransactionSyncApi)
21. [.debug(value)](#enableDebugLogs)
* [**Connection Pooling APIs**](#PoolAPIs)
...close = function (cb)
{
var self = this, deferred;
if(!cb)
{
deferred = Q.defer();
}
self.queue.push(function (next) {
if(self.conn)
{
self.conn.close(function (err) {
self.connected = false;
delete self.conn;
if (cb)
{
cb(err);
} else
{
deferred.resolve(err);
}
return next();
});
}
else
{
self.connected = false;
}
}); // self.queue.push
return deferred ? deferred.promise : false;
}...
* Update build.zip and defautl connection timeout. (Bimal Jha)
* Exit with error code on installation errors, to allow failure detection by automated build tools (Michael Szlapa)
* Add pool related test files. (Bimal Jha)
* Update conn.close() for Pool to avoid reconnection before moving to available pool.
Add pool related test files and update existing test files. (Bimal Jha)
* update examples (Bimal Jha)
* Updating the new build.zip for windows (Bimal Jha)
* delete build.zip file on ntx64 after unzip (bimaljha)
...closeSync = function ()
{
var self = this;
var result;
if(self.conn) result = self.conn.closeSync();
self.connected = false;
delete self.conn;
return result
}...
1. [.open(connectionString, [options,] callback)](#openApi)
2. [.openSync(connectionString)](#openSyncApi)
3. [.query(sqlQuery [, bindingParameters], callback)](#queryApi)
4. [.querySync(sqlQuery [, bindingParameters])](#querySyncApi)
5. [.queryStream(sqlQuery [, bindingParameters])](#queryStreamApi)
6. [.close(callback)](#closeApi)
7. [.closeSync()](#closeSyncApi)
8. [.prepare(sql, callback)](#prepareApi)
9. [.prepareSync(sql)](#prepareSyncApi)
10. [.execute([bindingParameters], callback)](#executeApi)
11. [.executeSync([bindingParameters])](#executeSyncApi)
12. [.executeNonQuery([bindingParameters], callback)](#executeNonQueryApi)
13. [.bind(bindingParameters, callback)](#bindApi)
14. [.bindSync(bindingParameters)](#bindSyncApi)
...columns = function (catalog, schema, table, column, callback)
{
var self = this;
if (!self.queue) self.queue = [];
callback = callback || arguments[arguments.length - 1];
self.queue.push(function (next)
{
self.conn.columns(catalog, schema, table, column, function (err, result)
{
if (err) return callback(err, [], false);
result.fetchAll(function (err, data)
{
result.closeSync();
callback(err, data);
return next();
});
});
});
}...
var self = this;
if (!self.queue) self.queue = [];
callback = callback || arguments[arguments.length - 1];
self.queue.push(function (next)
{
self.conn.columns(catalog, schema, table, column, function (err, result)
{
if (err) return callback(err, [], false);
result.fetchAll(function (err, data)
{
result.closeSync();
callback(err, data);
...commitTransaction = function (cb)
{
var self = this, deferred = null, onEndTransaction;
if(!cb)
{
deferred = Q.defer();
onEndTransaction = function(err)
{
if(err)
{
deferred.reject(err);
}
else
{
deferred.resolve(true);
}
};
}
//don't rollback
self.conn.endTransaction(false, deferred ? onEndTransaction : cb);
self.conn.inTransaction = false;
return deferred ? deferred.promise : self;
}...
10. [.execute([bindingParameters], callback)](#executeApi)
11. [.executeSync([bindingParameters])](#executeSyncApi)
12. [.executeNonQuery([bindingParameters], callback)](#executeNonQueryApi)
13. [.bind(bindingParameters, callback)](#bindApi)
14. [.bindSync(bindingParameters)](#bindSyncApi)
15. [.beginTransaction(callback)](#beginTransactionApi)
16. [.beginTransactionSync()](#beginTransactionSyncApi)
17. [.commitTransaction(callback)](#commitTransactionApi)
18. [.commitTransactionSync()](#commitTransactionSyncApi)
19. [.rollbackTransaction(callback)](#rollbackTransactionApi)
20. [.rollbackTransactionSync()](#rollbackTransactionSyncApi)
21. [.debug(value)](#enableDebugLogs)
* [**Connection Pooling APIs**](#PoolAPIs)
* [**bindingParameters**](#bindParameters)
...commitTransactionSync = function ()
{
var self = this;
self.conn.endTransactionSync(false); //don't rollback
self.conn.inTransaction = false;
return self;
}...
11. [.executeSync([bindingParameters])](#executeSyncApi)
12. [.executeNonQuery([bindingParameters], callback)](#executeNonQueryApi)
13. [.bind(bindingParameters, callback)](#bindApi)
14. [.bindSync(bindingParameters)](#bindSyncApi)
15. [.beginTransaction(callback)](#beginTransactionApi)
16. [.beginTransactionSync()](#beginTransactionSyncApi)
17. [.commitTransaction(callback)](#commitTransactionApi)
18. [.commitTransactionSync()](#commitTransactionSyncApi)
19. [.rollbackTransaction(callback)](#rollbackTransactionApi)
20. [.rollbackTransactionSync()](#rollbackTransactionSyncApi)
21. [.debug(value)](#enableDebugLogs)
* [**Connection Pooling APIs**](#PoolAPIs)
* [**bindingParameters**](#bindParameters)
* [**CALL Statement**](#callStmt)
...describe = function (obj, callback)
{
var self = this;
if (typeof(callback) !== "function")
{
throw({
error : "[node-odbc] Missing Arguments",
message : "You must specify a callback function in order " +
"for the describe method to work."
});
return false;
}
if (typeof(obj) !== "object")
{
callback({
error : "[node-odbc] Missing Arguments",
message : "You must pass an object as argument 0 if you want " +
"anything productive to happen in the describe method."
}, []);
return false;
}
if (!obj.database)
{
callback({
error : "[node-odbc] Missing Arguments",
message : "The object you passed did not contain a database " +
"property. This is required for the describe method to work."
}, []);
return false;
}
//set some defaults if they weren't passed
obj.schema = obj.schema || "%";
obj.type = obj.type || "table";
if (obj.table && obj.column)
{
//get the column details
self.columns(obj.database, obj.schema, obj.table, obj.column, callback);
}
else if (obj.table)
{
//get the columns in the table
self.columns(obj.database, obj.schema, obj.table, "%", callback);
}
else
{
//get the tables in the database
self.tables(obj.database, obj.schema, null, obj.type || "table", callback);
}
}...
/*
* In its most basic form you must call describe passing it an object which
* contains the database name and a callback function.
*
* This will return a list of tables in the database for all schemas.
*/
db.describe({
database : 'myAwesomeDatabase'
}, function (error, result) {
if (error) {
console.log(error);
return false;
}
...endTransaction = function (rollback, cb)
{
var self = this;
self.conn.endTransaction(rollback, cb);
self.conn.inTransaction = false;
return self;
}...
return deferred ? deferred.promise : self;
};
Database.prototype.endTransaction = function (rollback, cb)
{
var self = this;
self.conn.endTransaction(rollback, cb);
self.conn.inTransaction = false;
return self;
};
Database.prototype.commitTransaction = function (cb)
{
...endTransactionSync = function (rollback)
{
var self = this;
self.conn.endTransactionSync(rollback);
self.conn.inTransaction = false;
return self;
}...
return self;
};
Database.prototype.endTransactionSync = function (rollback)
{
var self = this;
self.conn.endTransactionSync(rollback);
self.conn.inTransaction = false;
return self;
};
Database.prototype.commitTransactionSync = function ()
{
...fetchStreamingResults = function (results, stream)
{
var self = this;
return results.fetch(function (err, data)
{
if (err)
{
return process.nextTick(function () { stream.emit('error', err); });
}
// when no more data returns, return push null to indicate the end of stream
if (!data)
{
return stream.push(null);
}
// if pushing the data returns 'true', that means we can query and push more
// immediately othewise the _read function will be called again (executing
// this function) once the reading party is ready to recieve more
if (stream.push(data))
{
return self.fetchStreamingResults(results, stream);
}
});
}...
var self = this;
var stream = new Readable({ objectMode: true });
var results;
stream._read = function()
{
// after the first internal call to _read, the 'results' should be set
// and the stream can continue fetching the results
if (results) return self.fetchStreamingResults(results, stream);
// in the first call to _read the stream starts to emit data once we've
// queried for results
return self.queryResult(sql, params, function (err, result)
{
if (err)
{
...open = function (connStr, cb) {
var self = this, deferred;
if (typeof(connStr) === "object")
{
var obj = connStr;
connStr = "";
Object.keys(obj).forEach(function (key) {
connStr += key + "=" + obj[key] + ";";
});
}
if (!cb)
{
deferred = Q.defer();
}
self.odbc.createConnection(function (err, conn) {
if(!cb)
{
if (err) deferred.reject(err);
} else
{
if (err) return cb(err);
}
self.conn = conn;
if (self.connectTimeout || self.connectTimeout === 0)
{
self.conn.connectTimeout = self.connectTimeout;
}
if (typeof(self.systemNaming) !== 'undefined')
{
self.conn.systemNaming = self.systemNaming;
}
self.conn.open(connStr, function (err, result)
{
if(cb)
{
if (err) return cb(err);
self.connected = true;
return cb(err, result);
}
else
{
if(err) deferred.reject(err);
self.connected = true;
deferred.resolve(result);
}
}); //conn.open
}); // odbc.createConnection
return deferred ? deferred.promise : null;
}...
## Quick Example
------------------
```javascript
var ibmdb = require('ibm_db');
ibmdb.open("DATABASE=<dbname>;HOSTNAME=<myhost>;UID=db2user;
PWD=password;PORT=<dbport>;PROTOCOL=TCPIP", function (err,conn) {
if (err) return console.log(err);
conn.query('select 1 from sysibm.sysdummy1', function (err, data) {
if (err) console.log(err);
else console.log(data);
conn.close(function () {
...openSync = function (connStr)
{
var self = this;
self.conn = self.odbc.createConnectionSync();
if (self.connectTimeout || self.connectTimeout === 0)
{
self.conn.connectTimeout = self.connectTimeout;
}
if (typeof(self.systemNaming) !== 'undefined')
{
self.conn.systemNaming = self.systemNaming;
}
if (typeof(connStr) === "object")
{
var obj = connStr;
connStr = "";
Object.keys(obj).forEach(function (key) {
connStr += key + "=" + obj[key] + ";";
});
}
var result = self.conn.openSync(connStr);
if (result)
{
self.connected = true;
}
return result;
}...
```javascript
var Database = require("ibm_db").Database
, ibmdb = new Database();
```
1. [.open(connectionString, [options,] callback)](#openApi)
2. [.openSync(connectionString)](#openSyncApi)
3. [.query(sqlQuery [, bindingParameters], callback)](#queryApi)
4. [.querySync(sqlQuery [, bindingParameters])](#querySyncApi)
5. [.queryStream(sqlQuery [, bindingParameters])](#queryStreamApi)
6. [.close(callback)](#closeApi)
7. [.closeSync()](#closeSyncApi)
8. [.prepare(sql, callback)](#prepareApi)
9. [.prepareSync(sql)](#prepareSyncApi)
...prepare = function (sql, cb)
{
var self = this, deferred;
if(!cb)
{
deferred = Q.defer();
}
self.conn.createStatement(function (err, stmt)
{
if(err)
{
if(cb)
{
return cb(err);
} else
{
deferred.reject(err);
}
}
stmt.queue = new SimpleQueue();
stmt.prepare(sql, function (err)
{
if (err)
{
if(cb)
{
return cb(err);
} else
{
deferred.reject(err)
}
}
deferred ? deferred.resolve(stmt) : cb(null, stmt);
});
});
return deferred ? deferred.promise : null;
}...
1. [.open(connectionString, [options,] callback)](#openApi)
2. [.openSync(connectionString)](#openSyncApi)
3. [.query(sqlQuery [, bindingParameters], callback)](#queryApi)
4. [.querySync(sqlQuery [, bindingParameters])](#querySyncApi)
5. [.queryStream(sqlQuery [, bindingParameters])](#queryStreamApi)
6. [.close(callback)](#closeApi)
7. [.closeSync()](#closeSyncApi)
8. [.prepare(sql, callback)](#prepareApi)
9. [.prepareSync(sql)](#prepareSyncApi)
10. [.execute([bindingParameters], callback)](#executeApi)
11. [.executeSync([bindingParameters])](#executeSyncApi)
12. [.executeNonQuery([bindingParameters], callback)](#executeNonQueryApi)
13. [.bind(bindingParameters, callback)](#bindApi)
14. [.bindSync(bindingParameters)](#bindSyncApi)
15. [.beginTransaction(callback)](#beginTransactionApi)
...prepareSync = function (sql)
{
var self = this;
var stmt = self.conn.createStatementSync();
stmt.queue = new SimpleQueue();
stmt.prepareSync(sql);
return stmt;
}...
2. [.openSync(connectionString)](#openSyncApi)
3. [.query(sqlQuery [, bindingParameters], callback)](#queryApi)
4. [.querySync(sqlQuery [, bindingParameters])](#querySyncApi)
5. [.queryStream(sqlQuery [, bindingParameters])](#queryStreamApi)
6. [.close(callback)](#closeApi)
7. [.closeSync()](#closeSyncApi)
8. [.prepare(sql, callback)](#prepareApi)
9. [.prepareSync(sql)](#prepareSyncApi)
10. [.execute([bindingParameters], callback)](#executeApi)
11. [.executeSync([bindingParameters])](#executeSyncApi)
12. [.executeNonQuery([bindingParameters], callback)](#executeNonQueryApi)
13. [.bind(bindingParameters, callback)](#bindApi)
14. [.bindSync(bindingParameters)](#bindSyncApi)
15. [.beginTransaction(callback)](#beginTransactionApi)
16. [.beginTransactionSync()](#beginTransactionSyncApi)
...query = function (query, params, cb)
{
var self = this, deferred, sql, resultset = [], multipleResultSet = false;
exports.debug && console.log(getElapsedTime(), "odbc.js:query() => Entry");
//support for promises
if (!cb && typeof params !== 'function')
{
deferred = Q.defer();
!params ? params = null : '';
}
if (typeof(params) === 'function')
{
cb = params;
params = null;
}
if (!self.connected)
{
deferred ? deferred.reject({ message : "Connection not open."}) :
cb({ message : "Connection not open."}, [], false);
return deferred ? deferred.promise : false;
}
self.queue.push(function (next) {
function cbQuery (initialErr, result, outparams)
{
if(outparams) {
resultset = outparams;
multipleResultSet = true;
}
if (result && typeof(result) === 'object') {
fetchMore();
} else {
cb(initialErr, resultset);
return next();
}
function fetchMore()
{
if (self.fetchMode)
{
result.fetchMode = self.fetchMode;
}
result.fetchAll(function (err, data, rowcount) {
var moreResults = false, moreResultsError = null;
// If there is any error, return it now only.
if( err || initialErr )
{
// For pooled connection, if we get SQL30081N, then close
// the connection now only and then proceed.
if(self.realClose){
if((err && err['message'] &&
err['message'].search("SQL30081N") != -1) ||
(initialErr && initialErr['message'] &&
initialErr['message'].search("SQL30081N") != -1))
{
self.closeSync();
}
}
if(multipleResultSet) resultset.push(data);
else resultset = data;
deferred ? deferred.reject(initialErr || err) : cb(initialErr || err, resultset);
result.closeSync();
initialErr = null;
err = null;
return next();
}
// Get the result data
try
{
if(rowcount) // Check for more result set.
moreResults = result.moreResultsSync();
}
catch (e)
{
moreResultsError = e;
moreResults = false;
}
//close the result before calling back
//if there are not more result sets
if (moreResults)
{
if( data.length ) resultset.push(data);
multipleResultSet = true;
fetchMore();
}
else
{
result.closeSync();
if( data.length ) {
if(multipleResultSet) resultset.push(data);
else resultset = data;
}
exports.debug && console.log(getElapsedTime(), "odbc.js:query() => Done.");
// send exception error and/or data to callback function.
// only once with all the results.
!cb ? deferred.resolve(resultset) : cb(moreResultsError, resultset);
}
moreResultsError = null;
return next();
});
}
} //function cbQuery
if(typeof query === "object")
{
sql = query.sql;
if(query.params) params = query.params;
}
else
{
sql = query;
}
exports.debug && console.log(getElapsedTime(), "odbc.js:query() => ", sql);
if (params)
{
if(Array.isArray(params))
{
var err = parseParams(params);
if(err) deferred ? deferred.reject(err) : cb(err);
}
if(typeof query === 'object')
{
query.params = params;
self.conn.query(query, cbQuery);
}
else
self.conn.query(query, params, cbQuery);
}
else
{
self.conn.query(query, cbQuery);
}
}); //self.queue.push
return deferred ? deferred.promise : false;
}...
```javascript
var ibmdb = require('ibm_db');
ibmdb.open("DATABASE=<dbname>;HOSTNAME=<myhost>;UID=db2user;PWD=password;PORT=<dbport>;PROTOCOL
=TCPIP", function (err,conn) {
if (err) return console.log(err);
conn.query('select 1 from sysibm.sysdummy1', function (err, data) {
if (err) console.log(err);
else console.log(data);
conn.close(function () {
console.log('done');
});
});
...queryResult = function (query, params, cb)
{
var self = this, sql;
if (typeof(params) === 'function')
{
cb = params;
params = null;
}
if (!self.connected)
{
return cb({ message : "Connection not open."}, null);
}
if(typeof query === "object")
{
sql = query.sql;
if(query.params) params = query.params;
}
else
{
sql = query;
}
exports.debug && console.log(getElapsedTime(), "odbc.js:queryResult() => ", sql);
self.queue.push(function (next) {
//ODBCConnection.query() is the fastest-path querying mechanism.
if (params)
{
if(Array.isArray(params))
{
var err = parseParams(params);
if(err) cb(err);
}
if(typeof query === 'object')
{
query.params = params;
self.conn.query(query, cbQuery);
}
else
self.conn.query(sql, params, cbQuery);
}
else
{
self.conn.query(sql, cbQuery);
}
function cbQuery (err, result)
{
if (err)
{
cb(err, null);
return next();
}
if (self.fetchMode)
{
result.fetchMode = self.fetchMode;
}
cb(err, result);
return next();
} // function cbQuery
}); //self.queue.push
}...
conn.openSync(cn);
// create table and insert some rows to it.
conn.querySync("create table mytab (c1 int, c2 varchar(20))");
conn.querySync("insert into mytab values (1, 'bimal'),(2, 'kamal'),(3,'mohan'),(4,'ram
x27;)");
// Select data from table
conn.queryResult("select * from mytab", function (err, result) {
if(err) {
console.log(err);
return;
}
// Fetch single row at once and process it.
// Note that queryResult will bring only 64k data from server and result.fetchSync
...queryResultSync = function (query, params)
{
var self = this, result, sql;
if (!self.connected)
{
throw ({ message : "Connection not open."});
}
if(typeof query === "object")
{
sql = query.sql;
if(query.params) params = query.params;
}
else
{
sql = query;
}
exports.debug && console.log(getElapsedTime(), "odbc.js:queryResultSync() => ", sql);
if (params)
{
if(Array.isArray(params))
{
var err = parseParams(params);
if(err) cb(err);
}
if(sql.search(/^call /i))
{
if(typeof query === 'object')
{
query.params = params;
self.conn.querySync(query);
}
else
result = self.conn.querySync(sql, params);
}
else // Its a CALL statement.
{
result = self.conn.querySync({"sql":sql, "params":params, "noResults":true});
return result;
}
}
else
{
result = self.conn.querySync(sql);
}
if (self.fetchMode)
{
result.fetchMode = self.fetchMode;
}
return result;
}n/a
function queryStream(sql, params)
{
var self = this;
var stream = new Readable({ objectMode: true });
var results;
stream._read = function()
{
// after the first internal call to _read, the 'results' should be set
// and the stream can continue fetching the results
if (results) return self.fetchStreamingResults(results, stream);
// in the first call to _read the stream starts to emit data once we've
// queried for results
return self.queryResult(sql, params, function (err, result)
{
if (err)
{
return process.nextTick(function () { stream.emit('error', err); });
}
results = result;
return self.fetchStreamingResults(results, stream);
});
};
return stream;
}...
, ibmdb = new Database();
```
1. [.open(connectionString, [options,] callback)](#openApi)
2. [.openSync(connectionString)](#openSyncApi)
3. [.query(sqlQuery [, bindingParameters], callback)](#queryApi)
4. [.querySync(sqlQuery [, bindingParameters])](#querySyncApi)
5. [.queryStream(sqlQuery [, bindingParameters])](#queryStreamApi)
6. [.close(callback)](#closeApi)
7. [.closeSync()](#closeSyncApi)
8. [.prepare(sql, callback)](#prepareApi)
9. [.prepareSync(sql)](#prepareSyncApi)
10. [.execute([bindingParameters], callback)](#executeApi)
11. [.executeSync([bindingParameters])](#executeSyncApi)
12. [.executeNonQuery([bindingParameters], callback)](#executeNonQueryApi)
...querySync = function (query, params)
{
var self = this, result, sql, outparams = null;
if (!self.connected)
{
throw ({ message : "Connection not open."});
}
if(typeof query === "object")
{
sql = query.sql;
if(query.params) params = query.params;
}
else
{
sql = query;
}
exports.debug && console.log(getElapsedTime(), "odbc.js:querySync() => ", sql);
if (params)
{
if(Array.isArray(params))
{
var err = parseParams(params);
if(err) return err;
}
if(typeof query === 'object')
{
query.params = params;
result = self.conn.querySync(query);
}
else
{
result = self.conn.querySync(sql, params);
}
}
else
{
result = self.conn.querySync(query);
}
if(Array.isArray(result))
{
if(result[1]) {
outparams = result[1]; // INOUT and OUT param values for SP.
}
result = result[0];
}
if(!result) return outparams; // For noResults.
// Processing for resultset.
var data, resultset = [], moreResults = true, moreResultsError = null;
var nullresult = true;
if(outparams) {
resultset = outparams;
nullresult = false;
}
if (self.fetchMode)
{
result.fetchMode = self.fetchMode;
}
while(moreResults)
{
data = result.fetchAllSync();
if(!data.length) {
moreResults = false;
break;
}
try
{
moreResults = result.moreResultsSync();
}
catch (e)
{
moreResultsError = e;
moreResults = false;
break;
}
if(data.length) {
if(nullresult && !moreResults) resultset = data;
else resultset.push(data);
nullresult = false;
}
}
result.closeSync();
if(moreResultsError) return moreResultsError;
if(nullresult) return [];
return resultset;
}...
var Database = require("ibm_db").Database
, ibmdb = new Database();
```
1. [.open(connectionString, [options,] callback)](#openApi)
2. [.openSync(connectionString)](#openSyncApi)
3. [.query(sqlQuery [, bindingParameters], callback)](#queryApi)
4. [.querySync(sqlQuery [, bindingParameters])](#querySyncApi)
5. [.queryStream(sqlQuery [, bindingParameters])](#queryStreamApi)
6. [.close(callback)](#closeApi)
7. [.closeSync()](#closeSyncApi)
8. [.prepare(sql, callback)](#prepareApi)
9. [.prepareSync(sql)](#prepareSyncApi)
10. [.execute([bindingParameters], callback)](#executeApi)
11. [.executeSync([bindingParameters])](#executeSyncApi)
...rollbackTransaction = function (cb)
{
var self = this, deferred = null, onEndTransaction;
if(!cb) {
deferred = Q.defer();
onEndTransaction = function(err) {
if(err) {
deferred.reject(err);
}
else {
deferred.resolve(true);
}
};
}
self.conn.endTransaction(true, deferred ? onEndTransaction : cb); //rollback
self.conn.inTransaction = false;
return deferred ? deferred.promise : self;
}...
12. [.executeNonQuery([bindingParameters], callback)](#executeNonQueryApi)
13. [.bind(bindingParameters, callback)](#bindApi)
14. [.bindSync(bindingParameters)](#bindSyncApi)
15. [.beginTransaction(callback)](#beginTransactionApi)
16. [.beginTransactionSync()](#beginTransactionSyncApi)
17. [.commitTransaction(callback)](#commitTransactionApi)
18. [.commitTransactionSync()](#commitTransactionSyncApi)
19. [.rollbackTransaction(callback)](#rollbackTransactionApi)
20. [.rollbackTransactionSync()](#rollbackTransactionSyncApi)
21. [.debug(value)](#enableDebugLogs)
* [**Connection Pooling APIs**](#PoolAPIs)
* [**bindingParameters**](#bindParameters)
* [**CALL Statement**](#callStmt)
* [**Build Options**](#buildOptions)
...rollbackTransactionSync = function ()
{
var self = this;
self.conn.endTransactionSync(true); //rollback
self.conn.inTransaction = false;
return self;
}...
13. [.bind(bindingParameters, callback)](#bindApi)
14. [.bindSync(bindingParameters)](#bindSyncApi)
15. [.beginTransaction(callback)](#beginTransactionApi)
16. [.beginTransactionSync()](#beginTransactionSyncApi)
17. [.commitTransaction(callback)](#commitTransactionApi)
18. [.commitTransactionSync()](#commitTransactionSyncApi)
19. [.rollbackTransaction(callback)](#rollbackTransactionApi)
20. [.rollbackTransactionSync()](#rollbackTransactionSyncApi)
21. [.debug(value)](#enableDebugLogs)
* [**Connection Pooling APIs**](#PoolAPIs)
* [**bindingParameters**](#bindParameters)
* [**CALL Statement**](#callStmt)
* [**Build Options**](#buildOptions)
...setIsolationLevel = function (isolationLevel)
{
var self = this;
return (self.conn.setIsolationLevel(isolationLevel));
}...
return stmt;
};
Database.prototype.setIsolationLevel = function(isolationLevel)
{
var self = this;
return (self.conn.setIsolationLevel(isolationLevel));
};
//Proxy all of the ODBCStatement functions so that they are queued
odbc.ODBCStatement.prototype._execute = odbc.ODBCStatement.prototype.execute;
odbc.ODBCStatement.prototype._executeSync = odbc.ODBCStatement.prototype.executeSync;
odbc.ODBCStatement.prototype._executeDirect = odbc.ODBCStatement.prototype.executeDirect;
odbc.ODBCStatement.prototype._executeDirectSync = odbc.ODBCStatement.prototype.executeDirectSync;
...tables = function (catalog, schema, table, type, callback)
{
var self = this;
if (!self.queue) self.queue = [];
callback = callback || arguments[arguments.length - 1];
self.queue.push(function (next)
{
self.conn.tables(catalog, schema, table, type, function (err, result)
{
if (err) return callback(err, [], false);
result.fetchAll(function (err, data)
{
result.closeSync();
callback(err, data);
return next();
});
});
});
}...
var self = this;
if (!self.queue) self.queue = [];
callback = callback || arguments[arguments.length - 1];
self.queue.push(function (next)
{
self.conn.tables(catalog, schema, table, type, function (err, result)
{
if (err) return callback(err, [], false);
result.fetchAll(function (err, data)
{
result.closeSync();
callback(err, data);
...function ODBC() { [native code] }...
var odbc = require("bindings")("odbc_bindings")
, SimpleQueue = require("./simple-queue")
, util = require("util")
, Readable = require('stream').Readable
, Q = require('q');
// Call of odbc.ODBC() loads odbc library and allocate environment handle.
// All calls of new Database() should use this same odbc unless passed as
// options.odbc. ENV will keep value of this odbc after first call of Database.
var ENV;
module.exports = function (options)
{
return new Database(options);
...function createConnection() { [native code] }...
}
if (!cb)
{
deferred = Q.defer();
}
self.odbc.createConnection(function (err, conn) {
if(!cb)
{
if (err) deferred.reject(err);
} else
{
if (err) return cb(err);
}
...function createConnectionSync() { [native code] }...
return deferred ? deferred.promise : null;
}; // Database.open function
Database.prototype.openSync = function (connStr)
{
var self = this;
self.conn = self.odbc.createConnectionSync();
if (self.connectTimeout || self.connectTimeout === 0)
{
self.conn.connectTimeout = self.connectTimeout;
}
if (typeof(self.systemNaming) !== 'undefined')
{
...function ODBCConnection() { [native code] }n/a
function beginTransaction() { [native code] }...
8. [.prepare(sql, callback)](#prepareApi)
9. [.prepareSync(sql)](#prepareSyncApi)
10. [.execute([bindingParameters], callback)](#executeApi)
11. [.executeSync([bindingParameters])](#executeSyncApi)
12. [.executeNonQuery([bindingParameters], callback)](#executeNonQueryApi)
13. [.bind(bindingParameters, callback)](#bindApi)
14. [.bindSync(bindingParameters)](#bindSyncApi)
15. [.beginTransaction(callback)](#beginTransactionApi)
16. [.beginTransactionSync()](#beginTransactionSyncApi)
17. [.commitTransaction(callback)](#commitTransactionApi)
18. [.commitTransactionSync()](#commitTransactionSyncApi)
19. [.rollbackTransaction(callback)](#rollbackTransactionApi)
20. [.rollbackTransactionSync()](#rollbackTransactionSyncApi)
21. [.debug(value)](#enableDebugLogs)
...function beginTransactionSync() { [native code] }...
9. [.prepareSync(sql)](#prepareSyncApi)
10. [.execute([bindingParameters], callback)](#executeApi)
11. [.executeSync([bindingParameters])](#executeSyncApi)
12. [.executeNonQuery([bindingParameters], callback)](#executeNonQueryApi)
13. [.bind(bindingParameters, callback)](#bindApi)
14. [.bindSync(bindingParameters)](#bindSyncApi)
15. [.beginTransaction(callback)](#beginTransactionApi)
16. [.beginTransactionSync()](#beginTransactionSyncApi)
17. [.commitTransaction(callback)](#commitTransactionApi)
18. [.commitTransactionSync()](#commitTransactionSyncApi)
19. [.rollbackTransaction(callback)](#rollbackTransactionApi)
20. [.rollbackTransactionSync()](#rollbackTransactionSyncApi)
21. [.debug(value)](#enableDebugLogs)
* [**Connection Pooling APIs**](#PoolAPIs)
...function close() { [native code] }...
* Update build.zip and defautl connection timeout. (Bimal Jha)
* Exit with error code on installation errors, to allow failure detection by automated build tools (Michael Szlapa)
* Add pool related test files. (Bimal Jha)
* Update conn.close() for Pool to avoid reconnection before moving to available pool.
Add pool related test files and update existing test files. (Bimal Jha)
* update examples (Bimal Jha)
* Updating the new build.zip for windows (Bimal Jha)
* delete build.zip file on ntx64 after unzip (bimaljha)
...function closeSync() { [native code] }...
1. [.open(connectionString, [options,] callback)](#openApi)
2. [.openSync(connectionString)](#openSyncApi)
3. [.query(sqlQuery [, bindingParameters], callback)](#queryApi)
4. [.querySync(sqlQuery [, bindingParameters])](#querySyncApi)
5. [.queryStream(sqlQuery [, bindingParameters])](#queryStreamApi)
6. [.close(callback)](#closeApi)
7. [.closeSync()](#closeSyncApi)
8. [.prepare(sql, callback)](#prepareApi)
9. [.prepareSync(sql)](#prepareSyncApi)
10. [.execute([bindingParameters], callback)](#executeApi)
11. [.executeSync([bindingParameters])](#executeSyncApi)
12. [.executeNonQuery([bindingParameters], callback)](#executeNonQueryApi)
13. [.bind(bindingParameters, callback)](#bindApi)
14. [.bindSync(bindingParameters)](#bindSyncApi)
...function columns() { [native code] }...
var self = this;
if (!self.queue) self.queue = [];
callback = callback || arguments[arguments.length - 1];
self.queue.push(function (next)
{
self.conn.columns(catalog, schema, table, column, function (err, result)
{
if (err) return callback(err, [], false);
result.fetchAll(function (err, data)
{
result.closeSync();
callback(err, data);
...function createStatement() { [native code] }...
var self = this, deferred;
if(!cb)
{
deferred = Q.defer();
}
self.conn.createStatement(function (err, stmt)
{
if(err)
{
if(cb)
{
return cb(err);
} else
...function createStatementSync() { [native code] }...
return deferred ? deferred.promise : null;
};
Database.prototype.prepareSync = function (sql)
{
var self = this;
var stmt = self.conn.createStatementSync();
stmt.queue = new SimpleQueue();
stmt.prepareSync(sql);
return stmt;
};
...function endTransaction() { [native code] }...
return deferred ? deferred.promise : self;
};
Database.prototype.endTransaction = function (rollback, cb)
{
var self = this;
self.conn.endTransaction(rollback, cb);
self.conn.inTransaction = false;
return self;
};
Database.prototype.commitTransaction = function (cb)
{
...function endTransactionSync() { [native code] }...
return self;
};
Database.prototype.endTransactionSync = function (rollback)
{
var self = this;
self.conn.endTransactionSync(rollback);
self.conn.inTransaction = false;
return self;
};
Database.prototype.commitTransactionSync = function ()
{
...function open() { [native code] }...
## Quick Example
------------------
```javascript
var ibmdb = require('ibm_db');
ibmdb.open("DATABASE=<dbname>;HOSTNAME=<myhost>;UID=db2user;
PWD=password;PORT=<dbport>;PROTOCOL=TCPIP", function (err,conn) {
if (err) return console.log(err);
conn.query('select 1 from sysibm.sysdummy1', function (err, data) {
if (err) console.log(err);
else console.log(data);
conn.close(function () {
...function openSync() { [native code] }...
```javascript
var Database = require("ibm_db").Database
, ibmdb = new Database();
```
1. [.open(connectionString, [options,] callback)](#openApi)
2. [.openSync(connectionString)](#openSyncApi)
3. [.query(sqlQuery [, bindingParameters], callback)](#queryApi)
4. [.querySync(sqlQuery [, bindingParameters])](#querySyncApi)
5. [.queryStream(sqlQuery [, bindingParameters])](#queryStreamApi)
6. [.close(callback)](#closeApi)
7. [.closeSync()](#closeSyncApi)
8. [.prepare(sql, callback)](#prepareApi)
9. [.prepareSync(sql)](#prepareSyncApi)
...function query() { [native code] }...
```javascript
var ibmdb = require('ibm_db');
ibmdb.open("DATABASE=<dbname>;HOSTNAME=<myhost>;UID=db2user;PWD=password;PORT=<dbport>;PROTOCOL
=TCPIP", function (err,conn) {
if (err) return console.log(err);
conn.query('select 1 from sysibm.sysdummy1', function (err, data) {
if (err) console.log(err);
else console.log(data);
conn.close(function () {
console.log('done');
});
});
...function querySync() { [native code] }...
var Database = require("ibm_db").Database
, ibmdb = new Database();
```
1. [.open(connectionString, [options,] callback)](#openApi)
2. [.openSync(connectionString)](#openSyncApi)
3. [.query(sqlQuery [, bindingParameters], callback)](#queryApi)
4. [.querySync(sqlQuery [, bindingParameters])](#querySyncApi)
5. [.queryStream(sqlQuery [, bindingParameters])](#queryStreamApi)
6. [.close(callback)](#closeApi)
7. [.closeSync()](#closeSyncApi)
8. [.prepare(sql, callback)](#prepareApi)
9. [.prepareSync(sql)](#prepareSyncApi)
10. [.execute([bindingParameters], callback)](#executeApi)
11. [.executeSync([bindingParameters])](#executeSyncApi)
...function setIsolationLevel() { [native code] }...
return stmt;
};
Database.prototype.setIsolationLevel = function(isolationLevel)
{
var self = this;
return (self.conn.setIsolationLevel(isolationLevel));
};
//Proxy all of the ODBCStatement functions so that they are queued
odbc.ODBCStatement.prototype._execute = odbc.ODBCStatement.prototype.execute;
odbc.ODBCStatement.prototype._executeSync = odbc.ODBCStatement.prototype.executeSync;
odbc.ODBCStatement.prototype._executeDirect = odbc.ODBCStatement.prototype.executeDirect;
odbc.ODBCStatement.prototype._executeDirectSync = odbc.ODBCStatement.prototype.executeDirectSync;
...function tables() { [native code] }...
var self = this;
if (!self.queue) self.queue = [];
callback = callback || arguments[arguments.length - 1];
self.queue.push(function (next)
{
self.conn.tables(catalog, schema, table, type, function (err, result)
{
if (err) return callback(err, [], false);
result.fetchAll(function (err, data)
{
result.closeSync();
callback(err, data);
...function ODBCResult() { [native code] }n/a
function closeSync() { [native code] }...
1. [.open(connectionString, [options,] callback)](#openApi)
2. [.openSync(connectionString)](#openSyncApi)
3. [.query(sqlQuery [, bindingParameters], callback)](#queryApi)
4. [.querySync(sqlQuery [, bindingParameters])](#querySyncApi)
5. [.queryStream(sqlQuery [, bindingParameters])](#queryStreamApi)
6. [.close(callback)](#closeApi)
7. [.closeSync()](#closeSyncApi)
8. [.prepare(sql, callback)](#prepareApi)
9. [.prepareSync(sql)](#prepareSyncApi)
10. [.execute([bindingParameters], callback)](#executeApi)
11. [.executeSync([bindingParameters])](#executeSyncApi)
12. [.executeNonQuery([bindingParameters], callback)](#executeNonQueryApi)
13. [.bind(bindingParameters, callback)](#bindApi)
14. [.bindSync(bindingParameters)](#bindSyncApi)
...function fetch() { [native code] }...
};
return stream;
};
Database.prototype.fetchStreamingResults = function(results, stream)
{
var self = this;
return results.fetch(function (err, data)
{
if (err)
{
return process.nextTick(function () { stream.emit('error', err); });
}
// when no more data returns, return push null to indicate the end of stream
if (!data)
...function fetchAll() { [native code] }...
function fetchMore()
{
if (self.fetchMode)
{
result.fetchMode = self.fetchMode;
}
result.fetchAll(function (err, data, rowcount) {
var moreResults = false, moreResultsError = null;
// If there is any error, return it now only.
if( err || initialErr )
{
// For pooled connection, if we get SQL30081N, then close
// the connection now only and then proceed.
...function fetchAllSync() { [native code] }...
, cn = "DATABASE=dbname;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=dbuser;PWD=xxx";
ibmdb.open(cn,function(err,conn){
var stmt = conn.prepareSync("select * from employee where empid = ?");
//Bind and Execute the statment asynchronously
stmt.execute([142], function (err, result) {
data = result.fetchAllSync();
console.log(data);
result.closeSync();
stmt.closeSync();
//Close the connection
conn.close(function(err){});
});
...function fetchSync() { [native code] }...
}
// Fetch single row at once and process it.
// Note that queryResult will bring only 64k data from server and result.fetchSync
// will return each row from this 64k client buffer. Once all data is read from
// buffer, ibm_db driver will bring another 64k chunk of data from server.
var data;
while( data = result.fetchSync() )
{
console.log(data);
}
// drop the table and close connection.
conn.querySync("drop table mytab");
conn.closeSync();
...function getColumnNamesSync() { [native code] }n/a
function moreResultsSync() { [native code] }...
return next();
}
// Get the result data
try
{
if(rowcount) // Check for more result set.
moreResults = result.moreResultsSync();
}
catch (e)
{
moreResultsError = e;
moreResults = false;
}
...function ODBCStatement() { [native code] }n/a
function bind() { [native code] }...
cb(err);
} else
{
deferred.reject(err);
}
}
}
self._bind(params, function (err) {
if (err) {
if(!deferred)
{
cb(err);
} else
{
deferred.reject(err);
...function bindSync() { [native code] }...
odbc.ODBCStatement.prototype.bindSync = function (ary) {
var self = this;
if(Array.isArray(ary))
{
var err = parseParams(ary);
if(err) return false;
}
return self._bindSync(ary);
};
module.exports.Pool = Pool;
Pool.count = 0;
...function execute() { [native code] }...
} else
{
deferred.reject(err);
}
return next();
}
self._execute(function (err, result, outparams) {
if(!deferred)
{
cb(err, result, outparams);
} else
{
if(err)
{
...function executeDirect() { [native code] }...
odbc.ODBCStatement.prototype.executeDirect = function (sql, cb)
{
var self = this;
self.queue = self.queue || new SimpleQueue();
self.queue.push(function (next) {
self._executeDirect(sql, function (err, result) {
cb(err, result);
return next();
});
});
};
...function executeDirectSync() { [native code] }n/a
function executeNonQuery() { [native code] }...
else
{
deferred.reject(err);
}
return next();
}
self._executeNonQuery(function (err, result) {
if(!deferred)
{
if(cb) cb(err, result);
}
else
{
if(err)
...function executeNonQuerySync() { [native code] }n/a
function executeSync() { [native code] }...
//If params are passed to this function, first bind them and
//then execute.
if (params)
{
err = self.bindSync(params);
if(err !== true) console.log(err);
}
return self._executeSync();
};
function parseParams(params)
{
var err, prm, paramtype, ctype, sqltype, datatype, data, len;
for (var i = 0; i < params.length; i++)
{
...function prepare() { [native code] }...
odbc.ODBCStatement.prototype.prepare = function (sql, cb) {
var self = this;
self.queue = self.queue || new SimpleQueue();
self.queue.push(function (next) {
self._prepare(sql, function (err) {
if(cb) cb(err);
return next();
});
});
};
...bind = function (ary, cb) {
var self = this;
self.bindQueue = self.bindQueue || new SimpleQueue();
self.bindQueue.push(function () {
if(Array.isArray(ary))
{
var err = parseParams(ary);
if(err && cb) cb(err);
}
self._bind(ary, function (err) {
if(cb) cb(err);
//NOTE: we do not call next() here because
//we want to pop the next bind call only
//after the next execute call
});
});
}...
6. [.close(callback)](#closeApi)
7. [.closeSync()](#closeSyncApi)
8. [.prepare(sql, callback)](#prepareApi)
9. [.prepareSync(sql)](#prepareSyncApi)
10. [.execute([bindingParameters], callback)](#executeApi)
11. [.executeSync([bindingParameters])](#executeSyncApi)
12. [.executeNonQuery([bindingParameters], callback)](#executeNonQueryApi)
13. [.bind(bindingParameters, callback)](#bindApi)
14. [.bindSync(bindingParameters)](#bindSyncApi)
15. [.beginTransaction(callback)](#beginTransactionApi)
16. [.beginTransactionSync()](#beginTransactionSyncApi)
17. [.commitTransaction(callback)](#commitTransactionApi)
18. [.commitTransactionSync()](#commitTransactionSyncApi)
19. [.rollbackTransaction(callback)](#rollbackTransactionApi)
20. [.rollbackTransactionSync()](#rollbackTransactionSyncApi)
...bindSync = function (ary) {
var self = this;
if(Array.isArray(ary))
{
var err = parseParams(ary);
if(err) return false;
}
return self._bindSync(ary);
}...
7. [.closeSync()](#closeSyncApi)
8. [.prepare(sql, callback)](#prepareApi)
9. [.prepareSync(sql)](#prepareSyncApi)
10. [.execute([bindingParameters], callback)](#executeApi)
11. [.executeSync([bindingParameters])](#executeSyncApi)
12. [.executeNonQuery([bindingParameters], callback)](#executeNonQueryApi)
13. [.bind(bindingParameters, callback)](#bindApi)
14. [.bindSync(bindingParameters)](#bindSyncApi)
15. [.beginTransaction(callback)](#beginTransactionApi)
16. [.beginTransactionSync()](#beginTransactionSyncApi)
17. [.commitTransaction(callback)](#commitTransactionApi)
18. [.commitTransactionSync()](#commitTransactionSyncApi)
19. [.rollbackTransaction(callback)](#rollbackTransactionApi)
20. [.rollbackTransactionSync()](#rollbackTransactionSyncApi)
21. [.debug(value)](#enableDebugLogs)
...function closeSync() { [native code] }...
1. [.open(connectionString, [options,] callback)](#openApi)
2. [.openSync(connectionString)](#openSyncApi)
3. [.query(sqlQuery [, bindingParameters], callback)](#queryApi)
4. [.querySync(sqlQuery [, bindingParameters])](#querySyncApi)
5. [.queryStream(sqlQuery [, bindingParameters])](#queryStreamApi)
6. [.close(callback)](#closeApi)
7. [.closeSync()](#closeSyncApi)
8. [.prepare(sql, callback)](#prepareApi)
9. [.prepareSync(sql)](#prepareSyncApi)
10. [.execute([bindingParameters], callback)](#executeApi)
11. [.executeSync([bindingParameters])](#executeSyncApi)
12. [.executeNonQuery([bindingParameters], callback)](#executeNonQueryApi)
13. [.bind(bindingParameters, callback)](#bindApi)
14. [.bindSync(bindingParameters)](#bindSyncApi)
...execute = function (params, cb)
{
var self = this, deferred;
// promises logic
if (!cb && typeof params !== 'function')
{
deferred = Q.defer();
// if(!params)
// {
// params = null;
// }
}
self.queue = self.queue || new SimpleQueue();
if (!cb)
{
cb = params;
params = null;
}
self.queue.push(function (next) {
//If params were passed to this function, then bind them and
//then execute.
if (params)
{
if(Array.isArray(params))
{
var err = parseParams(params);
if(err)
{
if(!deferred)
{
cb(err);
} else
{
deferred.reject(err);
}
}
}
self._bind(params, function (err) {
if (err) {
if(!deferred)
{
cb(err);
} else
{
deferred.reject(err);
}
return next();
}
self._execute(function (err, result, outparams) {
if(!deferred)
{
cb(err, result, outparams);
} else
{
if(err)
{
deferred.reject(err);
} else
{
deferred.resolve(result, outparams);
}
}
return next();
});
});
}
//Otherwise execute and pop the next bind call
else
{
self._execute(function (err, result, outparams) {
if(!deferred)
{
cb(err, result, outparams);
} else
{
if(err)
{
deferred.reject(err);
} else
{
deferred.resolve(result, outparams);
}
}
//NOTE: We only execute the next queued bind call after
// we have called execute() or executeNonQuery(). This ensures
// that we don't call a bind() a bunch of times without ever
// actually executing that bind. Not
self.bindQueue && self.bindQueue.next();
return next();
});
}
});
return deferred ? deferred.promise : null;
}...
3. [.query(sqlQuery [, bindingParameters], callback)](#queryApi)
4. [.querySync(sqlQuery [, bindingParameters])](#querySyncApi)
5. [.queryStream(sqlQuery [, bindingParameters])](#queryStreamApi)
6. [.close(callback)](#closeApi)
7. [.closeSync()](#closeSyncApi)
8. [.prepare(sql, callback)](#prepareApi)
9. [.prepareSync(sql)](#prepareSyncApi)
10. [.execute([bindingParameters], callback)](#executeApi)
11. [.executeSync([bindingParameters])](#executeSyncApi)
12. [.executeNonQuery([bindingParameters], callback)](#executeNonQueryApi)
13. [.bind(bindingParameters, callback)](#bindApi)
14. [.bindSync(bindingParameters)](#bindSyncApi)
15. [.beginTransaction(callback)](#beginTransactionApi)
16. [.beginTransactionSync()](#beginTransactionSyncApi)
17. [.commitTransaction(callback)](#commitTransactionApi)
...executeDirect = function (sql, cb)
{
var self = this;
self.queue = self.queue || new SimpleQueue();
self.queue.push(function (next) {
self._executeDirect(sql, function (err, result) {
cb(err, result);
return next();
});
});
}n/a
function executeDirectSync() { [native code] }n/a
executeNonQuery = function (params, cb)
{
var self = this, deferred;
if (!cb && typeof params !== 'function')
{
deferred = Q.defer();
}
self.queue = self.queue || new SimpleQueue();
if (!cb)
{
cb = params;
params = null;
}
self.queue.push(function (next) {
//If params were passed to this function, then bind them and
//then executeNonQuery.
if (params)
{
if(Array.isArray(params))
{
var err = parseParams(params);
if(err)
{
if(!deferred)
{
if(cb) cb(err);
}
else
{
deferred.reject(err);
}
}
}
self._bind(params, function (err) {
if (err) {
if(!deferred)
{
if(cb) cb(err)
}
else
{
deferred.reject(err);
}
return next();
}
self._executeNonQuery(function (err, result) {
if(!deferred)
{
if(cb) cb(err, result);
}
else
{
if(err)
{
deferred.reject(err);
}
else
{
deferred.resolve(result);
}
}
return next();
});
});
}
//Otherwise executeNonQuery and pop the next bind call
else {
self._executeNonQuery(function (err, result) {
if(!deferred)
{
if(cb) cb(err, result);
}
else
{
if(err)
{
deferred.reject(err);
}
else
{
deferred.resolve(result);
}
}
//NOTE: We only execute the next queued bind call after
// we have called execute() or executeNonQuery(). This ensures
// that we don't call a bind() a bunch of times without ever
// actually executing that bind. Not
self.bindQueue && self.bindQueue.next();
return next();
});
}
});
return deferred ? deferred.promise : null;
}...
5. [.queryStream(sqlQuery [, bindingParameters])](#queryStreamApi)
6. [.close(callback)](#closeApi)
7. [.closeSync()](#closeSyncApi)
8. [.prepare(sql, callback)](#prepareApi)
9. [.prepareSync(sql)](#prepareSyncApi)
10. [.execute([bindingParameters], callback)](#executeApi)
11. [.executeSync([bindingParameters])](#executeSyncApi)
12. [.executeNonQuery([bindingParameters], callback)](#executeNonQueryApi)
13. [.bind(bindingParameters, callback)](#bindApi)
14. [.bindSync(bindingParameters)](#bindSyncApi)
15. [.beginTransaction(callback)](#beginTransactionApi)
16. [.beginTransactionSync()](#beginTransactionSyncApi)
17. [.commitTransaction(callback)](#commitTransactionApi)
18. [.commitTransactionSync()](#commitTransactionSyncApi)
19. [.rollbackTransaction(callback)](#rollbackTransactionApi)
...function executeNonQuerySync() { [native code] }n/a
executeSync = function (params)
{
var self = this, err;
//If params are passed to this function, first bind them and
//then execute.
if (params)
{
err = self.bindSync(params);
if(err !== true) console.log(err);
}
return self._executeSync();
}...
4. [.querySync(sqlQuery [, bindingParameters])](#querySyncApi)
5. [.queryStream(sqlQuery [, bindingParameters])](#queryStreamApi)
6. [.close(callback)](#closeApi)
7. [.closeSync()](#closeSyncApi)
8. [.prepare(sql, callback)](#prepareApi)
9. [.prepareSync(sql)](#prepareSyncApi)
10. [.execute([bindingParameters], callback)](#executeApi)
11. [.executeSync([bindingParameters])](#executeSyncApi)
12. [.executeNonQuery([bindingParameters], callback)](#executeNonQueryApi)
13. [.bind(bindingParameters, callback)](#bindApi)
14. [.bindSync(bindingParameters)](#bindSyncApi)
15. [.beginTransaction(callback)](#beginTransactionApi)
16. [.beginTransactionSync()](#beginTransactionSyncApi)
17. [.commitTransaction(callback)](#commitTransactionApi)
18. [.commitTransactionSync()](#commitTransactionSyncApi)
...prepare = function (sql, cb) {
var self = this;
self.queue = self.queue || new SimpleQueue();
self.queue.push(function (next) {
self._prepare(sql, function (err) {
if(cb) cb(err);
return next();
});
});
}...
1. [.open(connectionString, [options,] callback)](#openApi)
2. [.openSync(connectionString)](#openSyncApi)
3. [.query(sqlQuery [, bindingParameters], callback)](#queryApi)
4. [.querySync(sqlQuery [, bindingParameters])](#querySyncApi)
5. [.queryStream(sqlQuery [, bindingParameters])](#queryStreamApi)
6. [.close(callback)](#closeApi)
7. [.closeSync()](#closeSyncApi)
8. [.prepare(sql, callback)](#prepareApi)
9. [.prepareSync(sql)](#prepareSyncApi)
10. [.execute([bindingParameters], callback)](#executeApi)
11. [.executeSync([bindingParameters])](#executeSyncApi)
12. [.executeNonQuery([bindingParameters], callback)](#executeNonQueryApi)
13. [.bind(bindingParameters, callback)](#bindApi)
14. [.bindSync(bindingParameters)](#bindSyncApi)
15. [.beginTransaction(callback)](#beginTransactionApi)
...function prepareSync() { [native code] }...
2. [.openSync(connectionString)](#openSyncApi)
3. [.query(sqlQuery [, bindingParameters], callback)](#queryApi)
4. [.querySync(sqlQuery [, bindingParameters])](#querySyncApi)
5. [.queryStream(sqlQuery [, bindingParameters])](#queryStreamApi)
6. [.close(callback)](#closeApi)
7. [.closeSync()](#closeSyncApi)
8. [.prepare(sql, callback)](#prepareApi)
9. [.prepareSync(sql)](#prepareSyncApi)
10. [.execute([bindingParameters], callback)](#executeApi)
11. [.executeSync([bindingParameters])](#executeSyncApi)
12. [.executeNonQuery([bindingParameters], callback)](#executeNonQueryApi)
13. [.bind(bindingParameters, callback)](#bindApi)
14. [.bindSync(bindingParameters)](#bindSyncApi)
15. [.beginTransaction(callback)](#beginTransactionApi)
16. [.beginTransactionSync()](#beginTransactionSyncApi)
...function Pool(_options) {
var self = this;
self.options = {};
self.maxPoolSize = 0;
if(_options)
{
if(_options.idleTimeout && !isNaN(_options.idleTimeout))
self.options.idleTimeout = _options.idleTimeout;
if(_options.autoCleanIdle)
self.options.autoCleanIdle = _options.autoCleanIdle;
if(_options.maxPoolSize)
self.maxPoolSize = _options.maxPoolSize;
if(_options.connectTimeout)
self.options.connectTimeout = _options.connectTimeout;
if(_options.systemNaming)
self.options.systemNaming=_options.systemNaming;
}
self.index = Pool.count++;
self.availablePool = {};
self.usedPool = {};
self.poolSize = 0;
if(!ENV) ENV = new odbc.ODBC();
self.odbc = ENV;
self.options.connectTimeout = self.options.connectTimeout || 60;
}...
### Using node < v0.10 on Linux
Be aware that through node v0.9 the uv_queue_work function, which is used to
execute the ODBC functions on a separate thread, uses libeio for its thread
pool. This thread pool by default is limited to 4 threads.
This means that if you have long running queries spread across multiple
instances of ibmdb.Database() or using odbc.Pool(), you will only be able to
have 4 concurrent queries.
You can increase the thread pool size by using @developmentseed's [node-eio]
(https://github.com/developmentseed/node-eio).
#### install:
```bash
...cleanUp = function (connStr, callback) {
var self = this;
if(self.availablePool[connStr].length < 2) return;
self.availablePool[connStr] = self.availablePool[connStr].filter(function(conn)
{
if(conn.lastUsed &&
(Date.now()-conn.lastUsed > (self.options.idleTimeout || 1800 * 1000)) &&
conn.realClose )
{
conn.realClose(function()
{
if(self.poolSize) self.poolSize--;
exports.debug && console.log("odbc.js : pool[%s] : Pool.cleanUp() : " +
"pool.realClose() : Connection duration : %s", self.index,
(Date.now() - conn.created)/1000);
});
return false;
}
else
{
return true;
}
});
}...
//move this connection back to the connection pool at the end.
if(db.conn)
{
self.availablePool[connStr] = self.availablePool[connStr] || [];
self.availablePool[connStr].push(db);
//start cleanUp if enabled
if(self.options.autoCleanIdle) self.cleanUp(connStr);
}
if(exports.debug) {
process.stdout.write(getElapsedTime());
console.dir(self);
}
}; // db.close function
...close = function (callback)
{
var self = this
, required = 0
, received = 0
, connections
, key
, x
;
exports.debug && console.log("%s odbc.js : pool[%s] : pool.close()", getElapsedTime(), self.index);
//we set a timeout because a previous db.close() may
//have caused the a behind the scenes db.open() to prepare
//a new connection
setTimeout(function () {
//merge the available pool and the usedPool
var pools = {};
for (key in self.availablePool)
{
pools[key] = (pools[key] || []).concat(self.availablePool[key]);
}
for (key in self.usedPool)
{
pools[key] = (pools[key] || []).concat(self.usedPool[key]);
}
exports.debug && console.log("%s odbc.js : pool[%s] : pool.close() - setTimeout() callback", getElapsedTime(), self.index);
//console.dir(pools);
if (Object.keys(pools).length === 0)
{
if (callback) return callback();
else return null;
}
for (key in pools)
{
connections = pools[key];
required += connections.length;
if(exports.debug) {
console.log("%s odbc.js : pool[%s] : pool.close() - processing pools %s - connections: %s",
getElapsedTime(), self.index, key, connections.length);
}
for (x = 0 ; x < connections.length; x ++)
{
(function (x) {
//call the realClose method to avoid
//automatically re-opening the connection
if(exports.debug) {
console.log("%s odbc.js : pool[%s] : pool.close() - calling realClose() for connection #%s",
getElapsedTime(), self.index, x);
}
if(connections[x].realClose) {
connections[x].realClose(function () {
if(exports.debug) {
console.log("%s odbc.js : pool[%s] : pool.close() - realClose() callback for connection #%s",
getElapsedTime(), self.index, x);
}
module.exports.close(connections[x]);
received += 1;
if(self.poolSize) self.poolSize--;
if (received === required)
{
if(callback) callback();
//prevent mem leaks
self = null;
connections = null;
required = null;
received = null;
key = null;
return;
}
}); // connections[x].realClose i.e. conn.close().
}
else {
exports.debug && console.log("%s realClose is not a member of connection %s", getElapsedTime(), x);
}
})(x);
} //for loop.
} //for (key in pools)
}, 2000); //setTimeout
}...
* Update build.zip and defautl connection timeout. (Bimal Jha)
* Exit with error code on installation errors, to allow failure detection by automated build tools (Michael Szlapa)
* Add pool related test files. (Bimal Jha)
* Update conn.close() for Pool to avoid reconnection before moving to available pool.
Add pool related test files and update existing test files. (Bimal Jha)
* update examples (Bimal Jha)
* Updating the new build.zip for windows (Bimal Jha)
* delete build.zip file on ntx64 after unzip (bimaljha)
...init = function (count, connStr)
{
var self = this;
var ret = false;
//check to see if we already have a connection for this connection string
if (self.availablePool[connStr] && self.availablePool[connStr].length)
{
console.log("Pool is already initialized and it has "+
self.availablePool[connStr].length + " available connections.\n");
return;
}
else
{
if((self.maxPoolSize > 0) && (count > self.maxPoolSize))
{
console.log(getElapsedTime(), " ** Can not open connection more than max pool size.\n");
count = self.maxPoolSize;
}
if(typeof(self.options.odbc) === undefined)
self.options.odbc = self.odbc;
for(var i = 0; i < count; i++)
{
var db = new Database(self.options);
self.poolSize++;
try{
ret = db.openSync(connStr);
} catch (ret) {
self.poolSize--;
exports.debug && console.log("%s odbc.js: %d connection(s) initialized.\n", getElapsedTime(), self.poolSize);
return ret;
}
if(ret !== true) break;
exports.debug && console.log("%s odbc.js : pool[%s] : pool.init %d", getElapsedTime(), self.index, i);
self.availablePool[connStr] = self.availablePool[connStr] || [];
db.created = Date.now();
db.realClose = db.close;
db.close = function (cb)
{
var db = this;
db.lastUsed = Date.now();
if(cb) cb(null);
if(db.conn && db.conn.inTransaction)
{
db.rollbackTransaction(function(err){});
}
self.usedPool[connStr].splice(self.usedPool[connStr].indexOf(db), 1);
if(db.conn)
{
self.availablePool[connStr] = self.availablePool[connStr] || [];
self.availablePool[connStr].push(db);
if(self.options.autoCleanIdle) self.cleanUp(connStr);
}
}; // db.close function
self.availablePool[connStr].push(db);
}
self.usedPool[connStr] = self.usedPool[connStr] || [];
exports.debug && console.log(getElapsedTime(), "Max pool size = " + self.maxPoolSize);
return ret;
}
}...
the next time you call `Pool.open()` for the same connection string.
For applications using multiple connections simultaneously, it is recommended to
use Pool.open instead of [ibmdb.open](#openApi).
1. [.open(connectionString, callback)](#openPoolApi)
2. [.close(callback)](#closePoolApi)
3. [.init(N, connStr)](#initPoolApi)
4. [.setMaxPoolSize(N)](#setMaxPoolSize)
5. [.setConnectTimeout(seconds)](#setConnectTimeout)
### <a name="openPoolApi"></a> 1) .open(connectionString, callback)
Get a `Database` instance which is already connected to `connectionString`
...open = function (connStr, callback)
{
var self = this
, db
;
//check to see if we already have a connection for this connection string
if (self.availablePool[connStr] && self.availablePool[connStr].length)
{
db = self.availablePool[connStr].shift();
db.lastUsed=null;
self.usedPool[connStr] = self.usedPool[connStr] || [];
self.usedPool[connStr].push(db);
callback(null, db);
}
else if((self.maxPoolSize > 0) && (self.poolSize >= self.maxPoolSize))
{
var timeout = self.options.connectTimeout;
var error = {"message":"Connection Timeout Occurred, Pool is full."};
var interval = setInterval(function () {
if (self.availablePool[connStr] && self.availablePool[connStr].length)
{
db = self.availablePool[connStr].shift();
db.lastUsed=null;
self.usedPool[connStr] = self.usedPool[connStr] || [];
self.usedPool[connStr].push(db);
clearInterval(interval);
callback(null, db);
}
if(timeout === 0)
{
clearInterval(interval);
callback(error, null);
}
else
{
timeout--;
}
}, 1000); //setInterval
}
else
{
if(typeof(self.options.odbc) === undefined)
self.options.odbc = self.odbc;
db = new Database(self.options);
self.poolSize++;
db.realClose = db.close;
db.close = function (cb)
{
var db = this;
db.lastUsed = Date.now();
//call back early, we can do the rest of this stuff after the client
//thinks that the connection is closed.
if(cb) cb(null);
// If this connection has some active transaction, rollback the
// transaction to free up the held resorces before moving back to
// the pool. So that, next request can get afresh connection from pool.
if(db.conn && db.conn.inTransaction)
{
db.rollbackTransaction(function(err){});
}
//remove this db from the usedPool
self.usedPool[connStr].splice(self.usedPool[connStr].indexOf(db), 1);
//move this connection back to the connection pool at the end.
if(db.conn)
{
self.availablePool[connStr] = self.availablePool[connStr] || [];
self.availablePool[connStr].push(db);
//start cleanUp if enabled
if(self.options.autoCleanIdle) self.cleanUp(connStr);
}
if(exports.debug) {
process.stdout.write(getElapsedTime());
console.dir(self);
}
}; // db.close function
db.open(connStr, function (error) {
exports.debug && console.log("%s odbc.js : pool[%s] : pool.db.open new connection.", getElapsedTime(), self.index);
if(error)
{
self.poolSize--;
}
else
{
self.usedPool[connStr] = self.usedPool[connStr] || [];
db.created = Date.now();
self.usedPool[connStr].push(db);
}
callback(error, db);
}); //db.open
}
}...
## Quick Example
------------------
```javascript
var ibmdb = require('ibm_db');
ibmdb.open("DATABASE=<dbname>;HOSTNAME=<myhost>;UID=db2user;
PWD=password;PORT=<dbport>;PROTOCOL=TCPIP", function (err,conn) {
if (err) return console.log(err);
conn.query('select 1 from sysibm.sysdummy1', function (err, data) {
if (err) console.log(err);
else console.log(data);
conn.close(function () {
...setConnectTimeout = function (timeout)
{
var self = this;
self.options.connectTimeout = timeout;
return true;
}...
For applications using multiple connections simultaneously, it is recommended to
use Pool.open instead of [ibmdb.open](#openApi).
1. [.open(connectionString, callback)](#openPoolApi)
2. [.close(callback)](#closePoolApi)
3. [.init(N, connStr)](#initPoolApi)
4. [.setMaxPoolSize(N)](#setMaxPoolSize)
5. [.setConnectTimeout(seconds)](#setConnectTimeout)
### <a name="openPoolApi"></a> 1) .open(connectionString, callback)
Get a `Database` instance which is already connected to `connectionString`
* **connectionString** - The connection string for your database
* **callback** - `callback (err, db)`
...setMaxPoolSize = function (size)
{
var self = this;
self.maxPoolSize = size;
return true;
}...
For applications using multiple connections simultaneously, it is recommended to
use Pool.open instead of [ibmdb.open](#openApi).
1. [.open(connectionString, callback)](#openPoolApi)
2. [.close(callback)](#closePoolApi)
3. [.init(N, connStr)](#initPoolApi)
4. [.setMaxPoolSize(N)](#setMaxPoolSize)
5. [.setConnectTimeout(seconds)](#setConnectTimeout)
### <a name="openPoolApi"></a> 1) .open(connectionString, callback)
Get a `Database` instance which is already connected to `connectionString`
* **connectionString** - The connection string for your database
...function SimpleQueue() {
var self = this;
self.fifo = [];
self.executing = false;
}n/a
maybeNext = function () {
var self = this;
if (!self.executing) {
self.next();
}
}...
}
SimpleQueue.prototype.push = function (fn) {
var self = this;
self.fifo.push(fn);
self.maybeNext();
};
SimpleQueue.prototype.maybeNext = function () {
var self = this;
if (!self.executing) {
self.next();
...next = function () {
var self = this;
if (self.fifo.length) {
var fn = self.fifo.shift();
self.executing = true;
fn(function () {
self.executing = false;
self.maybeNext();
});
}
}...
}
}
//NOTE: We only execute the next queued bind call after
// we have called execute() or executeNonQuery(). This ensures
// that we don't call a bind() a bunch of times without ever
// actually executing that bind. Not
self.bindQueue && self.bindQueue.next();
return next();
});
}
});
return deferred ? deferred.promise : null;
};
...push = function (fn) {
var self = this;
self.fifo.push(fn);
self.maybeNext();
}...
{
var self = this, deferred;
if(!cb)
{
deferred = Q.defer();
}
self.queue.push(function (next) {
if(self.conn)
{
self.conn.close(function (err) {
self.connected = false;
delete self.conn;
if (cb)
...