simple-oracledb
Advanced tools
Comparing version 0.0.33 to 0.0.34
@@ -92,2 +92,3 @@ ## Classes | ||
| [options] | <code>object</code> | Optional execute options | | ||
| [options.streamResults] | <code>object</code> | True to enable to stream the results in bulks, each bulk will invoke the provided callback (last callback invocation will have empty results) | | ||
| callback | <code>[AsyncCallback](#AsyncCallback)</code> | Invoked with an error or the query results object holding all data including LOBs | | ||
@@ -97,2 +98,3 @@ | ||
```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) { | ||
@@ -106,2 +108,15 @@ if (error) { | ||
}); | ||
//read all rows in bulks (streaming results) | ||
connection.query('SELECT * FROM departments', { | ||
streamResults: true | ||
}, function onResults(error, results) { | ||
if (error) { | ||
//handle error... | ||
} else if (results.length) { | ||
//handle next bulk of results | ||
} else { | ||
//all rows read | ||
} | ||
}); | ||
``` | ||
@@ -562,4 +577,5 @@ <a name="Connection+insert"></a> | ||
* [#readNextRows(columnNames, resultSet, callback)](#ResultSetReader+readNextRows) ℗ | ||
* [#readAllRows(columnNames, resultSet, callback, jsRowsBuffer)](#ResultSetReader+readAllRows) ℗ | ||
* [#readAllRows(columnNames, resultSet, callback, [jsRowsBuffer])](#ResultSetReader+readAllRows) ℗ | ||
* [#read(columnNames, resultSet, callback)](#ResultSetReader+read) | ||
* [#stream(columnNames, resultSet, callback)](#ResultSetReader+stream) | ||
@@ -583,3 +599,3 @@ <a name="new_ResultSetReader_new"></a> | ||
<a name="ResultSetReader+readAllRows"></a> | ||
### ResultSetReader#readAllRows(columnNames, resultSet, callback, jsRowsBuffer) ℗ | ||
### ResultSetReader#readAllRows(columnNames, resultSet, callback, [jsRowsBuffer]) ℗ | ||
Reads all data from the provided oracle ResultSet object into the provided buffer. | ||
@@ -594,3 +610,3 @@ | ||
| callback | <code>[AsyncCallback](#AsyncCallback)</code> | called when all rows are fully read or in case of an error | | ||
| jsRowsBuffer | <code>Array</code> | The result buffer | | ||
| [jsRowsBuffer] | <code>Array</code> | The result buffer, if not provided, the callback will be called for each bulk | | ||
@@ -609,2 +625,15 @@ <a name="ResultSetReader+read"></a> | ||
<a name="ResultSetReader+stream"></a> | ||
### ResultSetReader#stream(columnNames, resultSet, callback) | ||
Streams all data from the provided oracle ResultSet object to the callback in bulks.<br> | ||
The last callback call will have an empty result. | ||
**Access:** public | ||
| Param | Type | Description | | ||
| --- | --- | --- | | ||
| columnNames | <code>Array</code> | Array of strings holding the column names of the results | | ||
| resultSet | <code>Array</code> | The oracle ResultSet object | | ||
| callback | <code>[AsyncCallback](#AsyncCallback)</code> | called for each read bulk of rows or in case of an error | | ||
<a name="RowsReader"></a> | ||
@@ -611,0 +640,0 @@ ## RowsReader |
@@ -57,5 +57,7 @@ 'use strict'; | ||
* @param {object} [options] - Optional execute options | ||
* @param {object} [options.streamResults] - True to enable to stream the results in bulks, each bulk will invoke the provided callback (last callback invocation will have empty results) | ||
* @param {AsyncCallback} callback - Invoked with an error or the query results object holding all data including LOBs | ||
* @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) { | ||
@@ -69,2 +71,15 @@ * if (error) { | ||
* }); | ||
* | ||
* //read all rows in bulks (streaming results) | ||
* connection.query('SELECT * FROM departments', { | ||
* streamResults: true | ||
* }, function onResults(error, results) { | ||
* if (error) { | ||
* //handle error... | ||
* } else if (results.length) { | ||
* //handle next bulk of results | ||
* } else { | ||
* //all rows read | ||
* } | ||
* }); | ||
* ``` | ||
@@ -78,2 +93,13 @@ */ | ||
var callback = argumentsArray.pop(); | ||
var options = argumentsArray[argumentsArray.length - 1]; | ||
var streamResults = false; | ||
if (typeof options === 'object') { | ||
streamResults = options.streamResults; | ||
if (streamResults) { | ||
options.resultSet = true; | ||
} | ||
} | ||
argumentsArray.push(function onExecute(error, results) { | ||
@@ -83,3 +109,7 @@ if (error || (!results)) { | ||
} else if (results.resultSet) { | ||
resultSetReader.read(results.metaData, results.resultSet, callback); | ||
if (streamResults) { | ||
resultSetReader.stream(results.metaData, results.resultSet, callback); | ||
} else { | ||
resultSetReader.read(results.metaData, results.resultSet, callback); | ||
} | ||
} else { | ||
@@ -86,0 +116,0 @@ rowsReader.read(results.metaData, results.rows, callback); |
@@ -49,3 +49,3 @@ 'use strict'; | ||
* @param {AsyncCallback} callback - called when all rows are fully read or in case of an error | ||
* @param {Array} jsRowsBuffer - The result buffer | ||
* @param {Array} [jsRowsBuffer] - The result buffer, if not provided, the callback will be called for each bulk | ||
*/ | ||
@@ -59,3 +59,7 @@ ResultSetReader.prototype.readAllRows = function (columnNames, resultSet, callback, jsRowsBuffer) { | ||
} else if (jsRows && jsRows.length) { | ||
Array.prototype.push.apply(jsRowsBuffer, jsRows); | ||
if (jsRowsBuffer) { | ||
Array.prototype.push.apply(jsRowsBuffer, jsRows); | ||
} else { //stream results | ||
callback(null, jsRows); | ||
} | ||
@@ -66,3 +70,4 @@ process.nextTick(function fetchNextRows() { | ||
} else { | ||
callback(null, jsRowsBuffer); | ||
var lastResult = jsRowsBuffer || []; | ||
callback(null, lastResult); | ||
} | ||
@@ -86,2 +91,17 @@ }); | ||
/** | ||
* Streams all data from the provided oracle ResultSet object to the callback in bulks.<br> | ||
* The last callback call will have an empty result. | ||
* | ||
* @function | ||
* @memberof! ResultSetReader | ||
* @public | ||
* @param {Array} columnNames - Array of strings holding the column names of the results | ||
* @param {Array} resultSet - The oracle ResultSet object | ||
* @param {AsyncCallback} callback - called for each read bulk of rows or in case of an error | ||
*/ | ||
ResultSetReader.prototype.stream = function (columnNames, resultSet, callback) { | ||
this.readAllRows(columnNames, resultSet, callback); | ||
}; | ||
module.exports = new ResultSetReader(); |
{ | ||
"name": "simple-oracledb", | ||
"version": "0.0.33", | ||
"version": "0.0.34", | ||
"description": "Extend capabilities of oracledb with simplified API for quicker development.", | ||
@@ -5,0 +5,0 @@ "author": { |
@@ -183,2 +183,20 @@ # simple-oracledb | ||
In order to tream the results in bulks, you can provide the streamResults = true option.<br> | ||
The callback will be called for each bulk with array of objects.<br> | ||
Once all rows are read, the callback will be called with an empty array. | ||
```js | ||
connection.query('SELECT * FROM departments', { | ||
streamResults: true | ||
}, function onResults(error, results) { | ||
if (error) { | ||
//handle error... | ||
} else if (results.length) { | ||
//handle next bulk of results | ||
} else { | ||
//all rows read | ||
} | ||
}); | ||
``` | ||
<a name="usage-insert"></a> | ||
@@ -354,2 +372,3 @@ ## 'connection.insert(sql, bindVariables, options, callback)' | ||
| ----------- | ------- | ----------- | | ||
| 2015-12-21 | v0.0.34 | Added streaming of query results with new option streamResults=true | | ||
| 2015-12-17 | v0.0.33 | Maintenance | | ||
@@ -356,0 +375,0 @@ | 2015-12-08 | v0.0.24 | Added pool.getConnection connection validation via running SQL test command | |
@@ -258,2 +258,54 @@ 'use strict'; | ||
it('resultset - stream', function (done) { | ||
var table = 'TEST_ORA5'; | ||
initDB(table, [ | ||
{ | ||
COL1: 'PK1', | ||
COL2: 2, | ||
COL3: 30, | ||
COL4: '123' | ||
}, | ||
{ | ||
COL1: 'PK2', | ||
COL2: 200, | ||
COL3: 30, | ||
COL4: 'SOME TEST HERE' | ||
} | ||
], function (pool) { | ||
pool.getConnection(function (err, connection) { | ||
assert.isUndefined(err); | ||
connection.query('SELECT * FROM ' + table, [], { | ||
resultSet: true, | ||
streamResults: true | ||
}, function (error, jsRows) { | ||
assert.isNull(error); | ||
if (jsRows.length) { | ||
assert.deepEqual([ | ||
{ | ||
COL1: 'PK1', | ||
COL2: 2, | ||
COL3: 30, | ||
COL4: '123', | ||
LOB1: undefined, | ||
LOB2: undefined | ||
}, | ||
{ | ||
COL1: 'PK2', | ||
COL2: 200, | ||
COL3: 30, | ||
COL4: 'SOME TEST HERE', | ||
LOB1: undefined, | ||
LOB2: undefined | ||
} | ||
], jsRows); | ||
} else { //end of stream | ||
end(done, connection); | ||
} | ||
}); | ||
}); | ||
}); | ||
}); | ||
it('rows - lob data', function (done) { | ||
@@ -260,0 +312,0 @@ var table = 'TEST_ORA6'; |
@@ -81,3 +81,3 @@ 'use strict'; | ||
it('resultset - empty', function () { | ||
it('resultset - empty without stream', function () { | ||
var connection = {}; | ||
@@ -111,2 +111,35 @@ Connection.extend(connection); | ||
it('resultset - empty with stream', function () { | ||
var connection = {}; | ||
Connection.extend(connection); | ||
connection.execute = function () { | ||
var argumentsArray = Array.prototype.slice.call(arguments, 0); | ||
assert.equal(argumentsArray.length, 5); | ||
assert.equal(argumentsArray.shift(), 1); | ||
assert.equal(argumentsArray.shift(), 2); | ||
assert.equal(argumentsArray.shift(), 'a'); | ||
argumentsArray.shift(); | ||
argumentsArray.shift()(null, { | ||
metaData: columnNames, | ||
resultSet: { | ||
getRows: function (number, callback) { | ||
assert.equal(number, 100); | ||
callback(null, []); | ||
} | ||
} | ||
}); | ||
}; | ||
connection.query(1, 2, 'a', { | ||
streamResults: true | ||
}, function (error, jsRows) { | ||
assert.isNull(error); | ||
assert.deepEqual([], jsRows); | ||
}); | ||
}); | ||
it('rows - data', function () { | ||
@@ -177,3 +210,3 @@ var connection = {}; | ||
it('resultset - data', function () { | ||
it('resultset - data', function (done) { | ||
var connection = {}; | ||
@@ -287,4 +320,134 @@ Connection.extend(connection); | ||
], jsRows); | ||
done(); | ||
}); | ||
}); | ||
it('resultset - data stream', function (done) { | ||
var connection = {}; | ||
Connection.extend(connection); | ||
var date = new Date(); | ||
connection.execute = function () { | ||
var lob1 = helper.createCLOB(); | ||
var lob2 = helper.createCLOB(); | ||
var dbData = [ | ||
[ | ||
{ | ||
COL1: 'first row', | ||
COL2: 1, | ||
COL3: false, | ||
COL4: date, | ||
LOB1: undefined, | ||
LOB2: undefined | ||
} | ||
], | ||
[ | ||
{ | ||
COL1: 1, | ||
COL2: 'test', | ||
COL3: 50, | ||
COL4: lob1 | ||
}, | ||
{ | ||
COL1: 'a', | ||
COL2: date, | ||
COL3: undefined, | ||
COL4: undefined | ||
} | ||
], | ||
[ | ||
{ | ||
COL1: 10, | ||
COL2: true, | ||
COL3: lob2, | ||
COL4: 100, | ||
LOB1: undefined, | ||
LOB2: undefined | ||
} | ||
] | ||
]; | ||
var dbEvents = [null, function () { | ||
lob1.emit('data', 'test1'); | ||
lob1.emit('data', '\ntest2'); | ||
lob1.emit('end'); | ||
}, function () { | ||
lob2.emit('data', '123'); | ||
lob2.emit('data', '456'); | ||
lob2.emit('end'); | ||
}]; | ||
var argumentsArray = Array.prototype.slice.call(arguments, 0); | ||
argumentsArray.pop()(null, { | ||
metaData: columnNames, | ||
resultSet: { | ||
getRows: function (number, callback) { | ||
assert.equal(number, 100); | ||
var events = dbEvents.shift(); | ||
if (events) { | ||
setTimeout(events, 10); | ||
} | ||
callback(null, dbData.shift()); | ||
} | ||
} | ||
}); | ||
}; | ||
var outputData = [ | ||
[ | ||
{ | ||
COL1: 'first row', | ||
COL2: 1, | ||
COL3: false, | ||
COL4: date, | ||
LOB1: undefined, | ||
LOB2: undefined | ||
} | ||
], | ||
[ | ||
{ | ||
COL1: 1, | ||
COL2: 'test', | ||
COL3: 50, | ||
COL4: 'test1\ntest2', | ||
LOB1: undefined, | ||
LOB2: undefined | ||
}, | ||
{ | ||
COL1: 'a', | ||
COL2: date, | ||
COL3: undefined, | ||
COL4: undefined, | ||
LOB1: undefined, | ||
LOB2: undefined | ||
} | ||
], | ||
[ | ||
{ | ||
COL1: 10, | ||
COL2: true, | ||
COL3: '123456', | ||
COL4: 100, | ||
LOB1: undefined, | ||
LOB2: undefined | ||
} | ||
] | ||
]; | ||
connection.query(1, 2, 3, { | ||
streamResults: true, | ||
}, function (error, jsRows) { | ||
assert.isNull(error); | ||
assert.deepEqual(outputData.shift(), jsRows); | ||
if (outputData.length === 0) { | ||
done(); | ||
} else if (outputData.length < 0) { | ||
assert.fail(); | ||
} | ||
}); | ||
}); | ||
}); | ||
@@ -291,0 +454,0 @@ |
@@ -328,2 +328,346 @@ 'use strict'; | ||
}); | ||
describe('stream tests', function () { | ||
it('empty', function (done) { | ||
ResultSetReader.stream(columnNames, { | ||
getRows: function (number, callback) { | ||
assert.equal(number, 100); | ||
callback(null, []); | ||
} | ||
}, function (error, jsRows) { | ||
assert.isNull(error); | ||
assert.deepEqual([], jsRows); | ||
done(); | ||
}); | ||
}); | ||
it('array - all types', function (done) { | ||
var date = new Date(); | ||
var lob1 = helper.createCLOB(); | ||
var lob2 = helper.createCLOB(); | ||
var dbData = [ | ||
[ | ||
['first row', 1, false, date] | ||
], | ||
[ | ||
[1, 'test', 50, lob1], | ||
['a', date, undefined, null] | ||
], | ||
[ | ||
[10, true, lob2, 100] | ||
] | ||
]; | ||
var dbEvents = [null, function () { | ||
lob1.emit('data', 'test1'); | ||
lob1.emit('data', '\ntest2'); | ||
lob1.emit('end'); | ||
}, function () { | ||
lob2.emit('data', '123'); | ||
lob2.emit('data', '456'); | ||
lob2.emit('end'); | ||
}]; | ||
var outputData = [ | ||
[ | ||
{ | ||
COL1: 'first row', | ||
COL2: 1, | ||
COL3: false, | ||
COL4: date | ||
} | ||
], | ||
[ | ||
{ | ||
COL1: 1, | ||
COL2: 'test', | ||
COL3: 50, | ||
COL4: 'test1\ntest2' | ||
}, | ||
{ | ||
COL1: 'a', | ||
COL2: date, | ||
COL3: undefined, | ||
COL4: undefined | ||
} | ||
], | ||
[ | ||
{ | ||
COL1: 10, | ||
COL2: true, | ||
COL3: '123456', | ||
COL4: 100 | ||
} | ||
] | ||
]; | ||
ResultSetReader.stream(columnNames, { | ||
getRows: function (number, callback) { | ||
assert.equal(number, 100); | ||
var events = dbEvents.shift(); | ||
if (events) { | ||
setTimeout(events, 10); | ||
} | ||
callback(null, dbData.shift()); | ||
} | ||
}, function (error, jsRows) { | ||
assert.isNull(error); | ||
assert.deepEqual(outputData.shift(), jsRows); | ||
if (outputData.length === 0) { | ||
done(); | ||
} else if (outputData.length < 0) { | ||
assert.fail(); | ||
} | ||
}); | ||
}); | ||
it('object - all types', function (done) { | ||
var date = new Date(); | ||
var lob1 = helper.createCLOB(); | ||
var lob2 = helper.createCLOB(); | ||
var dbData = [ | ||
[ | ||
{ | ||
COL1: 'first row', | ||
COL2: 1, | ||
COL3: false, | ||
COL4: date | ||
} | ||
], | ||
[ | ||
{ | ||
COL1: 1, | ||
COL2: 'test', | ||
COL3: 50, | ||
COL4: lob1 | ||
}, | ||
{ | ||
COL1: 'a', | ||
COL2: date, | ||
COL3: undefined, | ||
COL4: undefined | ||
} | ||
], | ||
[ | ||
{ | ||
COL1: 10, | ||
COL2: true, | ||
COL3: lob2, | ||
COL4: 100 | ||
} | ||
] | ||
]; | ||
var dbEvents = [null, function () { | ||
lob1.emit('data', 'test1'); | ||
lob1.emit('data', '\ntest2'); | ||
lob1.emit('end'); | ||
}, function () { | ||
lob2.emit('data', '123'); | ||
lob2.emit('data', '456'); | ||
lob2.emit('end'); | ||
}]; | ||
var outputData = [ | ||
[ | ||
{ | ||
COL1: 'first row', | ||
COL2: 1, | ||
COL3: false, | ||
COL4: date | ||
} | ||
], | ||
[ | ||
{ | ||
COL1: 1, | ||
COL2: 'test', | ||
COL3: 50, | ||
COL4: 'test1\ntest2' | ||
}, | ||
{ | ||
COL1: 'a', | ||
COL2: date, | ||
COL3: undefined, | ||
COL4: undefined | ||
} | ||
], | ||
[ | ||
{ | ||
COL1: 10, | ||
COL2: true, | ||
COL3: '123456', | ||
COL4: 100 | ||
} | ||
] | ||
]; | ||
ResultSetReader.stream(columnNames, { | ||
getRows: function (number, callback) { | ||
assert.equal(number, 100); | ||
var events = dbEvents.shift(); | ||
if (events) { | ||
setTimeout(events, 10); | ||
} | ||
callback(null, dbData.shift()); | ||
} | ||
}, function (error, jsRows) { | ||
assert.isNull(error); | ||
assert.deepEqual(outputData.shift(), jsRows); | ||
if (outputData.length === 0) { | ||
done(); | ||
} else if (outputData.length < 0) { | ||
assert.fail(); | ||
} | ||
}); | ||
}); | ||
it('array - error', function (done) { | ||
var date = new Date(); | ||
var lob1 = helper.createCLOB(); | ||
var lob2 = helper.createCLOB(); | ||
var dbData = [ | ||
[ | ||
['first row', 1, false, date] | ||
], | ||
[ | ||
[1, 'test', 50, lob1], | ||
['a', date, undefined, null] | ||
], | ||
[ | ||
[10, true, lob2, 100] | ||
] | ||
]; | ||
var dbEvents = [null, function () { | ||
lob1.emit('data', 'test1'); | ||
lob1.emit('data', '\ntest2'); | ||
lob1.emit('end'); | ||
}, function () { | ||
lob2.emit('data', '123'); | ||
lob2.emit('data', '456'); | ||
lob2.emit('error', new Error('lob2 error')); | ||
}]; | ||
var counter = 0; | ||
ResultSetReader.stream(columnNames, { | ||
getRows: function (number, callback) { | ||
assert.equal(number, 100); | ||
var events = dbEvents.shift(); | ||
if (events) { | ||
setTimeout(events, 10); | ||
} | ||
callback(null, dbData.shift()); | ||
} | ||
}, function (error) { | ||
counter++; | ||
if (counter === 3) { | ||
assert.isDefined(error); | ||
assert.isNotNull(error); | ||
assert.equal(error.message, 'lob2 error'); | ||
done(); | ||
} else { | ||
assert.isNull(error); | ||
} | ||
}); | ||
}); | ||
it('object - error lob', function (done) { | ||
var date = new Date(); | ||
var lob1 = helper.createCLOB(); | ||
var lob2 = helper.createCLOB(); | ||
var dbData = [ | ||
[ | ||
{ | ||
COL1: 'first row', | ||
COL2: 1, | ||
COL3: false, | ||
COL4: date | ||
} | ||
], | ||
[ | ||
{ | ||
COL1: 1, | ||
COL2: 'test', | ||
COL3: 50, | ||
COL4: lob1 | ||
}, | ||
{ | ||
COL1: 'a', | ||
COL2: date, | ||
COL3: undefined, | ||
COL4: undefined | ||
} | ||
], | ||
[ | ||
{ | ||
COL1: 10, | ||
COL2: true, | ||
COL3: lob2, | ||
COL4: 100 | ||
} | ||
] | ||
]; | ||
var dbEvents = [null, function () { | ||
lob1.emit('data', 'test1'); | ||
lob1.emit('data', '\ntest2'); | ||
lob1.emit('end'); | ||
}, function () { | ||
lob2.emit('data', '123'); | ||
lob2.emit('data', '456'); | ||
lob2.emit('error', new Error('lob2 error')); | ||
}]; | ||
var counter = 0; | ||
ResultSetReader.stream(columnNames, { | ||
getRows: function (number, callback) { | ||
assert.equal(number, 100); | ||
var events = dbEvents.shift(); | ||
if (events) { | ||
setTimeout(events, 10); | ||
} | ||
callback(null, dbData.shift()); | ||
} | ||
}, function (error) { | ||
counter++; | ||
if (counter === 3) { | ||
assert.isDefined(error); | ||
assert.equal(error.message, 'lob2 error'); | ||
done(); | ||
} else { | ||
assert.isNull(error); | ||
} | ||
}); | ||
}); | ||
it('error getRows', function (done) { | ||
ResultSetReader.stream(columnNames, { | ||
getRows: function (number, callback) { | ||
assert.equal(number, 100); | ||
callback(new Error('getrows')); | ||
} | ||
}, function (error) { | ||
assert.isDefined(error); | ||
assert.equal(error.message, 'getrows'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
307971
6618
390