Extend capabilities of oracledb with simplified API for quicker development.
npm install simple-oracledb      
> Extend capabilities of oracledb with simplified API for quicker development.
* Overview
* Usage
* OracleDB
* Event: pool-created
* Event: pool-released
* Event: connection-created
* Event: connection-released
* createPool
* run
* Pool
* Event: connection-created
* Event: connection-released
* Event: release
* getConnection
* run
* parallelQuery
* terminate
* close
* Connection
* Event: release
* query
* insert
* update
* queryJSON
* batchInsert
* batchUpdate
* transaction
* run
* executeFile
* release
* close
* rollback
* SimpleOracleDB
* Event: pool-created
* Event: pool-released
* Event: connection-created
* Event: connection-released
* diagnosticInfo
* enableDiagnosticInfo
* Extensions
* connection.upsert
* Debug
* Installation
* Known Issues
* API Documentation
* Contributing
* Release History
* License
``js
//load the oracledb library
var oracledb = require('oracledb');
//load the simple oracledb
var SimpleOracleDB = require('simple-oracledb');
//modify the original oracledb library
SimpleOracleDB.extend(oracledb);
//from this point connections fetched via oracledb.getConnection(...) or pool.getConnection(...)
//have access to additional functionality.
oracledb.getConnection(function onConnection(error, connection) {
if (error) {
//handle error
} else {
//work with new capabilities or original oracledb capabilities
connection.query(...);
}
});
`
Another option is to modify your oracledb pool instance (in case the pool was created outside your code and
out of your control), as follows:
`js
//load the simple oracledb
var SimpleOracleDB = require('simple-oracledb');
function myFunction(pool) {
//modify the original oracledb pool instance
SimpleOracleDB.extend(pool);
//from this point connections fetched via pool.getConnection(...)
//have access to additional functionality.
pool.getConnection(function onConnection(error, connection) {
if (error) {
//handle error
} else {
//work with new capabilities or original oracledb capabilities
connection.query(...);
}
});
}
`
One last option is to modify your oracledb connection instance (in case the connection was created outside your code
and out of your control), as follows:
`js
//load the simple oracledb
var SimpleOracleDB = require('simple-oracledb');
function doSomething(connection, callback) {
//modify the original oracledb connection instance
SimpleOracleDB.extend(connection);
//from this point the connection has access to additional functionality as well as the original oracledb capabilities.
connection.query(...);
}
`
* pool - The pool instance
This events is triggered when a pool is created.
* pool - The pool instance
This events is triggered after a pool is released.
* connection - The connection instance
This events is triggered when a connection is created via oracledb.
* connection - The connection instance
This events is triggered when a connection is released successfully.
`js`
oracledb.createPool({
retryCount: 5, //The max amount of retries to get a connection from the pool in case of any error (default to 10 if not provided)
retryInterval: 500, //The interval in millies between get connection retry attempts (defaults to 250 millies if not provided)
runValidationSQL: true, //True to ensure the connection returned is valid by running a test validation SQL (defaults to true)
validationSQL: 'SELECT 1 FROM DUAL', //The test SQL to invoke before returning a connection to validate the connection is open (defaults to 'SELECT 1 FROM DUAL')
//any other oracledb pool attributes
}, function onPoolCreated(error, pool) {
//continue flow
});
Example
`js
oracledb.run({
user: process.env.ORACLE_USER,
password: process.env.ORACLE_PASSWORD,
connectString: process.env.ORACLE_CONNECTION_STRING
}, function onConnection(connection, callback) {
//run some query and the output will be available in the 'run' callback
connection.query('SELECT department_id, department_name FROM departments WHERE manager_id < :id', [110], callback);
}, function onActionDone(error, result) {
//do something with the result/error
});
oracledb.run({
user: process.env.ORACLE_USER,
password: process.env.ORACLE_PASSWORD,
connectString: process.env.ORACLE_CONNECTION_STRING
}, function (connection, callback) {
//run some database operations in a transaction
connection.transaction([
function firstAction(callback) {
connection.insert(...., callback);
},
function secondAction(callback) {
connection.update(...., callback);
}
], {
sequence: true
}, callback); //at end of transaction, call the oracledb provided callback
}, function onActionDone(error, result) {
//do something with the result/error
});
//full promise support for both oracledb.run and the action
oracledb.run({
user: process.env.ORACLE_USER,
password: process.env.ORACLE_PASSWORD,
connectString: process.env.ORACLE_CONNECTION_STRING
}, function (connection) {
//run some database operations in a transaction and return a promise
return connection.transaction([
function firstAction() {
return connection.insert(....); //returns a promise
},
function secondAction() {
return connection.update(....); //returns a promise
}
]);
}).then(function (result) {
//do something with the result
});
`
* connection - The connection instance
This events is triggered when a connection is created via pool.
* connection - The connection instance
This events is triggered when a connection is released successfully.
* pool - The pool instance
This events is triggered after the pool is released successfully.
Example
`js
oracledb.createPool({
retryCount: 5, //The max amount of retries to get a connection from the pool in case of any error (default to 10 if not provided)
retryInterval: 500, //The interval in millies between get connection retry attempts (defaults to 250 millies if not provided)
runValidationSQL: true, //True to ensure the connection returned is valid by running a test validation SQL (defaults to true)
usePingValidation: true, //If runValidationSQL, this flag will define if validation should first attempt to use connection.ping instead of running a SQL
validationSQL: 'SELECT 1 FROM DUAL', //The test SQL to invoke before returning a connection to validate the connection is open (defaults to 'SELECT 1 FROM DUAL')
//any other oracledb pool attributes
}, function onPoolCreated(error, pool) {
pool.getConnection(function onConnection(poolError, connection) {
//continue flow (connection, if provided, has been tested to ensure it is valid)
});
});
//another example but with promise support
oracledb.createPool({
retryCount: 5, //The max amount of retries to get a connection from the pool in case of any error (default to 10 if not provided)
retryInterval: 500, //The interval in millies between get connection retry attempts (defaults to 250 millies if not provided)
runValidationSQL: true, //True to ensure the connection returned is valid by running a test validation SQL (defaults to true)
usePingValidation: true, //If runValidationSQL, this flag will define if validation should first attempt to use connection.ping instead of running a SQL
validationSQL: 'SELECT 1 FROM DUAL', //The test SQL to invoke before returning a connection to validate the connection is open (defaults to 'SELECT 1 FROM DUAL')
//any other oracledb pool attributes
}).then(function onPoolCreated(pool) {
pool.getConnection(function onConnection(poolError, connection) {
//continue flow (connection, if provided, has been tested to ensure it is valid)
});
});
`
Example
`js
pool.run(function (connection, callback) {
//run some query and the output will be available in the 'run' callback
connection.query('SELECT department_id, department_name FROM departments WHERE manager_id < :id', [110], callback);
}, function onActionDone(error, result) {
//do something with the result/error
});
pool.run(function (connection, callback) {
//run some database operations in a transaction
connection.transaction([
function firstAction(callback) {
connection.insert(...., callback);
},
function secondAction(callback) {
connection.update(...., callback);
}
], {
sequence: true
}, callback); //at end of transaction, call the pool provided callback
}, {
ignoreReleaseErrors: false //enable/disable ignoring any release error (default not to ignore)
}, function onActionDone(error, result) {
//do something with the result/error
});
//another example but with promise support
pool.run(function (connection, callback) {
//run some query and the output will be available in the 'run' promise 'then'
connection.query('SELECT department_id, department_name FROM departments WHERE manager_id < :id', [110], callback);
}).then(function onActionDone(result) {
//do something with the result
});
//extended promise support (action is returning a promise instead of using the callback)
pool.run(function (connection) {
//run some query and the output will be available in the 'run' promise 'then'
return connection.query('SELECT department_id, department_name FROM departments WHERE manager_id < :id', [110]); //no need for a callback, instead return a promise
}).then(function onActionDone(result) {
//do something with the result
});
`
Example
`js
pool.parallelQuery([
{
sql: 'SELECT department_id, department_name FROM departments WHERE manager_id = :id',
bindParams: [100],
options: {
//any options here
}
},
{
sql: 'SELECT * FROM employees WHERE manager_id = :id',
bindParams: {
id: 100
}
}
], function onQueriesDone(error, results) {
//do something with the result/error
const query1Results = results[0];
const query2Results = results[1];
});
//another example but with promise support
pool.parallelQuery([
{
sql: 'SELECT department_id, department_name FROM departments WHERE manager_id = :id',
bindParams: [100],
options: {
//any options here
}
},
{
sql: 'SELECT * FROM employees WHERE manager_id = :id',
bindParams: {
id: 100
}
}
]).then(function onQueriesDone(results) {
//do something with the result
const query1Results = results[0];
const query2Results = results[1];
});
`
Example
`js
pool.terminate(); //no callback needed
//still possible to call with a terminate callback function
pool.terminate(function onTerminate(error) {
if (error) {
//now what?
}
});
//can also use close
pool.close();
`
Example
`js
//read all rows and get an array of objects with all data
connection.query('SELECT department_id, department_name FROM departments WHERE manager_id < :id', [110], function onResults(error, results) {
if (error) {
//handle error...
} else {
//print the 4th row DEPARTMENT_ID column value
console.log(results[3].DEPARTMENT_ID);
}
});
//same as previous example but with promise support
connection.query('SELECT department_id, department_name FROM departments WHERE manager_id < :id', [110]).then(function (results) {
//print the 4th row DEPARTMENT_ID column value
console.log(results[3].DEPARTMENT_ID);
});
//In order to split results into bulks, you can provide the splitResults = true option.
//The callback will be called for each bulk with array of objects.
//Once all rows are read, the callback will be called with an empty array.
//Promises are not supported with splitResults=true
connection.query('SELECT * FROM departments WHERE manager_id > :id', [110], {
splitResults: true,
bulkRowsAmount: 100 //The amount of rows to fetch (for splitting results, that is the max rows that the callback will get for each callback invocation)
}, function onResults(error, results) {
if (error) {
//handle error...
} else if (results.length) {
//handle next bulk of results
} else {
//all rows read
}
});
//In order to stream results into a read stream, you can provide the streamResults = true option.
//The optional callback will be called with a read stream instance which can be used to fetch/pipe the data.
//Once all rows are read, the proper stream events will be called.
const stream = connection.query('SELECT * FROM departments WHERE manager_id > :id', [110], {
streamResults: true
});
//listen to fetched rows via data event or just pipe to another handler
stream.on('data', function (row) {
//use row object
if (row.MY_ID === 800) {
stream.close(); //optionally call the close function to prevent any more 'data' events and free the connection to execute other operations
}
});
//optionally listen also to metadata of query
stream.on('metadata', function (metaData) {
console.log(metaData);
});
//listen to other events such as end/close/error....
`
Example
`js
connection.insert('INSERT INTO mylobs (id, clob_column1, blob_column2) VALUES (:id, EMPTY_CLOB(), EMPTY_BLOB())', { //no need to specify the RETURNING clause in the SQL
id: 110,
clobText1: 'some long clob string', //add bind constiable with LOB column name and text content (need to map that name in the options)
blobBuffer2: new Buffer('some blob content, can be binary...') //add bind constiable with LOB column name and text content (need to map that name in the options)
}, {
autoCommit: true, //must be set to true in options to support auto commit after update is done, otherwise the auto commit will be false (oracledb.autoCommit is not checked)
lobMetaInfo: { //if LOBs are provided, this data structure must be provided in the options object and the bind constiables parameter must be an object (not array)
clob_column1: 'clobText1', //map oracle column name to bind constiable name
blob_column2: 'blobBuffer2'
}
}, function onResults(error, output) {
//continue flow...
});
//add few more items to the RETURNING clause (only used if lobMetaInfo is provided)
connection.insert('INSERT INTO mylobs (id, clob_column1, blob_column2) VALUES (:myid, EMPTY_CLOB(), EMPTY_BLOB())', { //no need to specify the RETURNING clause in the SQL
myid: {
type: oracledb.NUMBER,
dir: oracledb.BIND_INOUT,
val: 1234
},
clobText1: 'some long clob string', //add bind constiable with LOB column name and text content (need to map that name in the options)
blobBuffer2: new Buffer('some blob content, can be binary...') //add bind constiable with LOB column name and text content (need to map that name in the options)
}, {
autoCommit: true, //must be set to true in options to support auto commit after update is done, otherwise the auto commit will be false (oracledb.autoCommit is not checked)
lobMetaInfo: { //if LOBs are provided, this data structure must be provided in the options object and the bind constiables parameter must be an object (not array)
clob_column1: 'clobText1', //map oracle column name to bind constiable name
blob_column2: 'blobBuffer2'
},
returningInfo: { //all items in this column/bind constiable object will be added to the generated RETURNING clause
id: 'myid'
}
}, function onResults(error, output) {
//continue flow...
});
//another example but with promise support
connection.insert('INSERT INTO mylobs (id, clob_column1, blob_column2) VALUES (:id, EMPTY_CLOB(), EMPTY_BLOB())', { //no need to specify the RETURNING clause in the SQL
id: 110,
clobText1: 'some long clob string', //add bind constiable with LOB column name and text content (need to map that name in the options)
blobBuffer2: new Buffer('some blob content, can be binary...') //add bind constiable with LOB column name and text content (need to map that name in the options)
}, {
autoCommit: true, //must be set to true in options to support auto commit after update is done, otherwise the auto commit will be false (oracledb.autoCommit is not checked)
lobMetaInfo: { //if LOBs are provided, this data structure must be provided in the options object and the bind constiables parameter must be an object (not array)
clob_column1: 'clobText1', //map oracle column name to bind constiable name
blob_column2: 'blobBuffer2'
}
}).then(function (results) {
console.log(results.rowsAffected);
});
`
Example
`js
connection.update('UPDATE mylobs SET name = :name, clob_column1 = EMPTY_CLOB(), blob_column2 = EMPTY_BLOB() WHERE id = :id', { //no need to specify the RETURNING clause in the SQL
id: 110,
name: 'My Name',
clobText1: 'some long clob string', //add bind constiable with LOB column name and text content (need to map that name in the options)
blobBuffer2: new Buffer('some blob content, can be binary...') //add bind constiable with LOB column name and text content (need to map that name in the options)
}, {
autoCommit: true, //must be set to true in options to support auto commit after update is done, otherwise the auto commit will be false (oracledb.autoCommit is not checked)
lobMetaInfo: { //if LOBs are provided, this data structure must be provided in the options object and the bind constiables parameter must be an object (not array)
clob_column1: 'clobText1', //map oracle column name to bind constiable name
blob_column2: 'blobBuffer2'
}
}, function onResults(error, output) {
//continue flow...
});
//another example but with promise support
connection.update('UPDATE mylobs SET name = :name, clob_column1 = EMPTY_CLOB(), blob_column2 = EMPTY_BLOB() WHERE id = :id', { //no need to specify the RETURNING clause in the SQL
id: 110,
name: 'My Name',
clobText1: 'some long clob string', //add bind constiable with LOB column name and text content (need to map that name in the options)
blobBuffer2: new Buffer('some blob content, can be binary...') //add bind constiable with LOB column name and text content (need to map that name in the options)
}, {
autoCommit: true, //must be set to true in options to support auto commit after update is done, otherwise the auto commit will be false (oracledb.autoCommit is not checked)
lobMetaInfo: { //if LOBs are provided, this data structure must be provided in the options object and the bind constiables parameter must be an object (not array)
clob_column1: 'clobText1', //map oracle column name to bind constiable name
blob_column2: 'blobBuffer2'
}
}).then(function (results) {
console.log(results.rowsAffected);
});
`
Example
`js
connection.queryJSON('SELECT JSON_DATA FROM APP_CONFIG WHERE ID > :id', [110], function onResults(error, results) {
if (error) {
//handle error...
} else if (results.rowCount === 1) { //single JSON is returned
//print the JSON
console.log(results.json);
} else if (results.rowCount > 1) { //multiple JSONs are returned
//print the JSON
results.json.forEach(function printJSON(json) {
console.log(json);
});
} else {
console.log('Did not find any results');
}
});
//another example but with promise support
connection.queryJSON('SELECT JSON_DATA FROM APP_CONFIG WHERE ID > :id', [110]).then(function (results) {
if (results.rowCount === 1) { //single JSON is returned
//print the JSON
console.log(results.json);
} else if (results.rowCount > 1) { //multiple JSONs are returned
//print the JSON
results.json.forEach(function printJSON(json) {
console.log(json);
});
}
});
`
Example
`js`
connection.batchInsert('INSERT INTO mylobs (id, clob_column1, blob_column2) VALUES (:id, EMPTY_CLOB(), EMPTY_BLOB())', [ //no need to specify the RETURNING clause in the SQL
{ //first row values
id: 110,
clobText1: 'some long clob string', //add bind constiable with LOB column name and text content (need to map that name in the options)
blobBuffer2: new Buffer('some blob content, can be binary...') //add bind constiable with LOB column name and text content (need to map that name in the options)
},
{ //second row values
id: 111,
clobText1: 'second row',
blobBuffer2: new Buffer('second rows')
}
], {
autoCommit: true, //must be set to true in options to support auto commit after insert is done, otherwise the auto commit will be false (oracledb.autoCommit is not checked)
lobMetaInfo: { //if LOBs are provided, this data structure must be provided in the options object and the bind constiables parameter must be an object (not array)
clob_column1: 'clobText1', //map oracle column name to bind constiable name
blob_column2: 'blobBuffer2'
}
}, function onResults(error, output) {
//continue flow...
});
Example
`js`
connection.batchUpdate('UPDATE mylobs SET name = :name, clob_column1 = EMPTY_CLOB(), blob_column2 = EMPTY_BLOB() WHERE id = :id', [ //no need to specify the RETURNING clause in the SQL
{ //first row values
id: 110,
clobText1: 'some long clob string', //add bind constiable with LOB column name and text content (need to map that name in the options)
blobBuffer2: new Buffer('some blob content, can be binary...') //add bind constiable with LOB column name and text content (need to map that name in the options)
},
{ //second row values
id: 111,
clobText1: 'second row',
blobBuffer2: new Buffer('second rows')
}
], {
autoCommit: true, //must be set to true in options to support auto commit after update is done, otherwise the auto commit will be false (oracledb.autoCommit is not checked)
lobMetaInfo: { //if LOBs are provided, this data structure must be provided in the options object and the bind constiables parameter must be an object (not array)
clob_column1: 'clobText1', //map oracle column name to bind constiable name
blob_column2: 'blobBuffer2'
}
}, function onResults(error, output) {
//continue flow...
});
Example
`js
//run all actions in parallel
connection.transaction([
function insertSomeRows(callback) {
connection.insert(...., function (error, results) {
//some more inserts....
connection.insert(...., callback);
});
},
function insertSomeMoreRows(callback) {
connection.insert(...., callback);
},
function doSomeUpdates(callback) {
connection.update(...., callback);
},
function runBatchUpdates(callback) {
connection.batchUpdate(...., callback);
}
], {
sequence: false
}, function onTransactionResults(error, output) {
//continue flow...
});
//run all actions in sequence
connection.transaction([
function firstAction(callback) {
connection.insert(...., callback);
},
function secondAction(callback) {
connection.update(...., callback);
}
], {
sequence: true
}, function onTransactionResults(error, output) {
//continue flow...
});
//another example but with promise support
connection.transaction([
function firstAction(callback) {
connection.insert(...., callback);
},
function secondAction(callback) {
connection.update(...., callback);
}
], {
sequence: true
}).then(function onTransactionResults(output) {
//continue flow...
});
//actions can return a promise instead of using callback (you can mix actions to either use callback or return a promise)
connection.transaction([
function firstAction() {
return connection.insert(....); //return a promise
},
function secondAction() {
return connection.update(....); //return a promise
}
], {
sequence: true
}).then(function onTransactionResults(output) {
//continue flow...
});
`
Example
`js
//run all actions in parallel
connection.run([
function insertSomeRows(callback) {
connection.insert(...., function (error, results) {
//some more inserts....
connection.insert(...., callback);
});
},
function insertSomeMoreRows(callback) {
connection.insert(...., callback);
},
function doSomeUpdates(callback) {
connection.update(...., callback);
},
function runBatchUpdates(callback) {
connection.batchUpdate(...., callback);
}
], {
sequence: false
}, function onActionsResults(error, output) {
//continue flow...
});
//run all actions in sequence
connection.run([
function firstAction(callback) {
connection.insert(...., callback);
},
function secondAction(callback) {
connection.update(...., callback);
}
], {
sequence: true
}, function onActionsResults(error, output) {
//continue flow...
});
//run some actions in sequence and a subset in parallel
connection.run([
function firstAction(callback) {
connection.insert(...., callback);
},
function secondAction(callback) {
connection.update(...., callback);
},
function subsetInParallel(callback) {
//run all actions in parallel
connection.run([
function insertSomeRows(subsetCallback) {
connection.insert(...., function (error, results) {
//some more inserts....
connection.insert(...., subsetCallback);
});
},
function insertSomeMoreRows(subsetCallback) {
connection.insert(...., subsetCallback);
},
function doSomeUpdates(subsetCallback) {
connection.update(...., subsetCallback);
},
function runBatchUpdates(subsetCallback) {
connection.batchUpdate(...., subsetCallback);
}
], {
sequence: false
}, callback); //all parallel actions done, call main callback
}
], {
sequence: true
}, function onActionsResults(error, output) {
//continue flow...
});
//another example but with promise support
connection.run([
function firstAction(callback) {
connection.insert(...., callback);
},
function secondAction(callback) {
connection.update(...., callback);
}
], {
sequence: true
}).then(function onActionsResults(output) {
//continue flow...
});
//actions can return a promise instead of using callback (you can mix actions to either use callback or return a promise)
connection.run([
function firstAction() {
return connection.insert(....); //return a promise
},
function secondAction() {
return connection.update(....); //return a promise
}
], {
sequence: true
}).then(function onActionsResults(output) {
//continue flow...
});
`
Example
`js`
connection.executeFile('./populate_table.sql', function onResults(error, results) {
if (error) {
//handle error...
} else {
//continue
}
});
Example
`js
connection.release(); //no callback needed
//still possible to call with a release callback function
connection.release(function onRelease(error) {
if (error) {
//now what?
}
});
//retry release in case of errors is enabled if options are provided
connection.release({
retryCount: 20, //retry max 20 times in case of errors (default is 10 if not provided)
retryInterval: 1000 //retry every 1 second (default is 250 millies if not provided)
});
//you can provide both retry options and callback (callback will be called only after all retries are done or in case connection was released)
connection.release({
retryCount: 10,
retryInterval: 250,
force: true //break any running operation before running release
}, function onRelease(error) {
if (error) {
//now what?
}
});
//can also use close instead of release
connection.close({
retryCount: 10,
retryInterval: 250
}, function onRelease(error) {
if (error) {
//now what?
}
});
`
Example
`js
connection.rollback(); //no callback needed
//still possible to call with a rollback callback function
connection.rollback(function onRollback(error) {
if (error) {
//now what?
}
});
`
* pool - The pool instance
This events is triggered when a pool is created.
* pool - The pool instance
This events is triggered after a pool is released.
* connection - The connection instance
This events is triggered when a connection is created via oracledb.
* connection - The connection instance
This events is triggered when a connection is released successfully.
Example
`js
//define a new function for all new connection objects called 'myConnFunc' which accepts 2 arguments
SimpleOracleDB.addExtension('connection', 'myConnFunc', function (myParam1, myParam2, callback) {
//implement some custom functionality...
callback();
});
//get connection (via oracledb directly or via pool) and start using the new function
connection.myConnFunc('test', 123, function () {
//continue flow...
});
//extensions are automatically promisified (can be disabled) so you can also run extension functions without callback
const promise = connection.myConnFunc('test', 123);
promise.then(function () {
//continue flow...
}).catch(function (error) {
//got some error...
});
//define a new function for all new pool objects called 'myPoolFunc'
SimpleOracleDB.addExtension('pool', 'myPoolFunc', function () {
//implement some custom functionality
});
//get pool and start using the new function
pool.myPoolFunc();
`
An example of an existing extension can be found at: oracledb-upsert which adds the connection.upsert (insert/update) functionality.
The rest of the API is the same as defined in the oracledb library: https://github.com/oracle/node-oracledb/blob/master/doc/api.md
``ini``
NODE_DEBUG=simple-oracledb
`sh``
npm install --save simple-oracledb
This library doesn't define oracledb as a dependency and therefore it is not installed when installing simple-oracledb.
You should define oracledb in your package.json and install it based on the oracledb installation instructions found at: installation guide
* oracledb version 1.7.0 breaks the API and prevents the library from being extended. This was fixed in oracledb 1.7.1 (oracledb case)
| Date | Version | Description |
| ----------- | ------- | ----------- |
| 2021-10-22 | v3.0.0 | Add null binding support, update constants with latest changes and do not break by default after run is done |
| 2020-05-13 | v2.0.0 | Migrate to github actions and upgrade minimal node version |
| 2019-05-25 | v1.4.2 | Maintenance |
| 2019-01-25 | v1.4.0 | useExecuteMany=true by default |
| 2018-09-23 | v1.3.0 | Added executeMany support for the batch APIs |
| 2018-04-14 | v1.2.2 | Performance improvement for pooled connection fetching (#23) |
| 2017-01-20 | v1.1.57 | connection.run, connection.transaction and oracledb.run actions can now return a promise instead of using a callback |
| 2017-01-14 | v1.1.56 | pool.run actions now can return a promise instead of using a callback |
| 2016-12-28 | v1.1.50 | Added pool.parallelQuery which enables parallel queries using multiple connections |
| 2016-11-15 | v1.1.41 | Added connection.executeFile to read SQL statement from file and execute it |
| 2016-10-07 | v1.1.26 | Added oracledb.run |
| 2016-08-15 | v1.1.2 | Added 'metadata' event for connection.query with streaming |
| 2016-08-10 | v1.1.0 | Breaking change connection.run and connection.transaction default is now sequence instead of parallel |
| 2016-08-09 | v1.0.2 | Added connection.run |
| 2016-08-07 | v0.1.98 | NODE_DEBUG=simple-oracledb will now also log all SQL statements and bind params for the connection.execute function |
| 2016-08-05 | v0.1.96 | Extensions are now automatically promisified |
| 2016-08-05 | v0.1.95 | Added promise support for all library APIs |
| 2016-07-26 | v0.1.84 | Add integration test via docker |
| 2016-07-24 | v0.1.83 | Add support for node-oracledb promise |
| 2016-07-17 | v0.1.80 | Add support for node-oracledb promise |
| 2016-07-14 | v0.1.79 | Fixed possible max stack size error |
| 2016-05-01 | v0.1.57 | Added the new monitor (SimpleOracleDB.diagnosticInfo and SimpleOracleDB.enableDiagnosticInfo) and SimpleOracleDB is now an event emitter |
| 2016-03-31 | v0.1.51 | Added new stream.close function to stop streaming data and free the connection for more operations |
| 2016-03-03 | v0.1.40 | Connection and Pool are now event emitters |
| 2016-03-02 | v0.1.38 | Added new force option for connection.release/close |
| 2016-02-28 | v0.1.37 | Added SimpleOracleDB.addExtension which allows to further extend oracledb |
| 2016-02-22 | v0.1.32 | Added new pool.run operation |
| 2016-02-16 | v0.1.29 | new optional options.returningInfo to insert/update/batch to enable to modify the returning/into clause when using LOBs |
| 2016-02-12 | v0.1.26 | Added sequence option for connection.transaction and added pool.close=pool.terminate, connection.close=connection.release aliases |
| 2016-02-10 | v0.1.23 | Adding debug logs via NODE_DEBUG=simple-oracledb |
| 2016-02-09 | v0.1.20 | connection.release now supports retry options |
| 2016-01-22 | v0.1.18 | Fixed missing call to resultset.close after done reading |
| 2016-01-12 | v0.1.8 | Avoid issues with oracledb stream option which is based on this library |
| 2016-01-07 | v0.1.7 | connection.query with streamResults=true returns a readable stream |
| 2015-12-30 | v0.1.6 | connection.transaction disables commit/rollback while running |
| 2015-12-29 | v0.1.4 | Added connection.transaction |
| 2015-12-29 | v0.1.3 | Added connection.batchUpdate |
| 2015-12-22 | v0.1.2 | Added streaming of query results with new option streamResults=true |
| 2015-12-21 | v0.1.1 | Rename streamResults to splitResults |
| 2015-12-21 | v0.0.35 | New bulkRowsAmount option to manage query resultset behaviour |
| 2015-12-21 | v0.0.34 | Added splitting of query results into bulks with new option splitResults=true |
| 2015-12-08 | v0.0.24 | Added pool.getConnection connection validation via running SQL test command |
| 2015-11-17 | v0.0.17 | Added pool.getConnection automatic retry |
| 2015-11-15 | v0.0.16 | Added connection.batchInsert and connection.rollback |
| 2015-10-20 | v0.0.10 | Added connection.queryJSON |
| 2015-10-19 | v0.0.9 | autoCommit support when doing INSERT/UPDATE with LOBs |
| 2015-10-19 | v0.0.7 | Added pool.terminate |
| 2015-10-18 | v0.0.5 | Added connection.update |
| 2015-10-18 | v0.0.4 | Added connection.insert |
| 2015-10-15 | v0.0.1 | Initial release. |