Introduce fetchArraySize to replace prefetchRows for query fetch tuning

This commit is contained in:
Christopher Jones 2017-12-12 09:56:12 +11:00
parent 1b717b80e4
commit 885de16a56
24 changed files with 839 additions and 437 deletions

View File

@ -49,16 +49,27 @@ This node-oracledb release has been tested with Node 4, 6 and 8 on
some 32-bit Linux, 32-bit Windows, Solaris and AIX environments, but
these architectures have not been fully tested.
*Note*: Installation has improved significantly in node-oracledb 2.x.
Pre-built binaries are now available for some combinations of
platforms and Node.js versions. And if you need to build your own
binary, the Oracle header files and node-oracledb environment variables
`OCI_INC_DIR` and `OCI_LIB_DIR` are no longer required. At run time,
Oracle client libraries must now always be in the default library
#### Changes in node-oracledb 2.x
In node-oracledb 2.x, pre-built binaries are available as a
convenience for common architectures. Note the operating systems and
versions of Node.js that the binaries are compatibile with will change
as the Node.js project evolves, and are not guaranteed.
Building from source code has improved significantly in 2.x The Oracle
header files and node-oracledb environment variables `OCI_INC_DIR` and
`OCI_LIB_DIR` are no longer required.
The Oracle client libraries must now always be in the default library
search path, such as `PATH` (on Windows) or `LD_LIBRARY_PATH` (on
Linux) or in `~/lib` (on macOS) because they are dynamically loaded at
run time. 'Rpath' linking is no longer performed on Linux or macOS.
Node-oracledb 2.x binaries will run with any of the Oracle client
11.2, 12.1 or 12.2 libraries without needing recompilation. Note the
available Oracle functionality will vary with different Oracle Client
versions.
## <a name="quickstart"></a> 2. Quick Start Node-oracledb Installation
Many users will be able to use pre-built node-oracledb binaries:
@ -92,7 +103,7 @@ from source code:
See [Troubleshooting Node-oracledb Installation Problems](#troubleshooting) if you have issues.
## 3. <a name="instructions"></a> Node-oracledb Installation Instructions
## <a name="instructions"></a> 3. Node-oracledb Installation Instructions
#### Which Instructions to Follow
@ -112,7 +123,7 @@ Another OS with Oracle Database 11.2 or 12c, or client libraries available | Upd
Source code from GitHub | Start with [Node-oracledb Installation from GitHub](#github) and then follow relevant platform instructions.
I don't have internet access | [Node-oracledb Installation Without Internet Access](#offline)
### 3.1 <a name="prerequisites"></a> Prerequisites
### <a name="prerequisites"></a> 3.1 Prerequisites
All installations need:
@ -172,6 +183,9 @@ Questions and issues can be posted as [GitHub Issues][10].
Review the generic [prerequisites](#prerequisites).
Pre-built binaries were built on Oracle Linux 6 and will require a
compatible glibc.
If source code is being compiled you need:
- GCC 4.7 (or later) because compiling for Node 4 (or later) requires
@ -221,7 +235,7 @@ npm install oracledb
```
Available pre-built node-oracledb binaries can been seen on the
[releases][41] page.
[releases][41] page. They were built on Oracle Linux 6.
If a pre-built binary is successfully installed but isn't usable
because it depends on a different glibc version, uninstall
@ -328,6 +342,9 @@ Questions and issues can be posted as [GitHub Issues][10].
Review the generic [prerequisites](#prerequisites).
Pre-built binaries were built on Oracle Linux 6 and will require a
compatible glibc.
If source code is being compiled you need:
- GCC 4.7 (or later) because compiling for Node 4 (or later) requires
@ -377,7 +394,7 @@ npm install oracledb
```
Available pre-built node-oracledb binaries can been seen on the
[releases][41] page.
[releases][41] page. They were built on Oracle Linux 6.
If a pre-built binary is successfully installed but isn't usable
because it depends on a different glibc version, uninstall
@ -612,6 +629,8 @@ Questions and issues can be posted as [GitHub Issues][10].
Review the generic [prerequisites](#prerequisites).
The pre-built binaries were built on macOS Sierra, 10.12.6.
Oracle Instant Client libraries are required on macOS. There is no
native Oracle Database for macOS but one can easily be run in a Linux
virtual machine, see [The Easiest Way to Install Oracle Database on
@ -738,6 +757,9 @@ Questions and issues can be posted as [GitHub Issues][10].
Review the generic [prerequisites](#prerequisites).
The pre-built binaries were built with Visual Studio 2015 and require
the matching [redistributable][27].
You may need Administrator privileges to set environment variables or
install software.
@ -845,7 +867,7 @@ variable `TNS_ADMIN` to that directory name.
The `PATH` variable needs to include the appropriate VS Redistributable:
- Oracle client 12.2 requires the [Visual Studio 2013 Redistributable][27].
- Oracle client 12.1 requires the [Visual Studio 2010 Redistributable][28].
- Oracle client 12.1 requires the [Visual Studio 2010 Redistributable][27].
- Oracle client 11.2 requires the [Visual Studio 2005 Redistributable][29].
You can also find out the version required by locating the library
@ -888,6 +910,9 @@ Questions and issues can be posted as [GitHub Issues][10].
Review the generic [prerequisites](#prerequisites).
The pre-built binaries were built with Visual Studio 2015 and require
the matching [redistributable][27].
The Oracle software can be either a database home or a full Oracle
client installation. Make sure that `PATH` contains the correct
binary directory, for example `C:\oracle\product\12.2.0\dbhome_1\bin`.
@ -1265,10 +1290,10 @@ Build node-oracledb from source code using the [Node-oracledb
Installation Instructions](#instructions) for your operating system
but change the install command to download from [GitHub][1] instead of
from [npmjs.com][4]. For example, to install the code corresponding
to the tag 'v1.13.1', use the command:
to the GitHub tag 'v2.0.15', use the command:
```
npm install oracle/node-oracledb#v1.13.1
npm install oracle/node-oracledb#v2.0.15
```
#### 3.11.2 Installing GitHub clones and zip files
@ -1400,16 +1425,12 @@ Some companies block access to github.com so `npm install oracledb`
will fail to download binaries, as will installing source code from
GitHub with `npm install oracle/node-oracledb.git#v2.0.15`.
To install node-oracledb in this case, compile the source code
included in the npm package:
- Use `npm install -verbose oracledb` and locate the URL it uses to
download the node-oracledb package, for example
- Download the node-oracledb package from npm, for example
`https://registry.npmjs.org/oracledb/-/oracledb-2.0.15.tgz`
Download and save the package.
- Create a directory such as `oracledb_build` and extract the package
inside it:
@ -1569,9 +1590,8 @@ If `require('oracledb')` fails:
[24]: https://docs.oracle.com/database/122/NTCLI/toc.htm
[25]: http://www.oracle.com/technetwork/topics/winx64soft-089540.html
[26]: http://www.oracle.com/technetwork/topics/winsoft-085727.html
[27]: https://support.microsoft.com/en-us/kb/2977003#bookmark-vs2013
[28]: https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads#bookmark-vs2010
[29]: https://www.microsoft.com/en-us/download/details.aspx?id=18471
[27]: https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads
[29]: https://www.microsoft.com/en-us/download/details.aspx?id=3387
[30]: http://www.oracle.com/technetwork/topics/aix5lsoft-098883.html
[31]: http://www.oracle.com/technetwork/topics/solx8664soft-097204.html
[32]: https://github.com/oracle/node-oracledb/blob/node-oracledb-v1/INSTALL.md

File diff suppressed because it is too large Load Diff

View File

@ -40,14 +40,13 @@
var oracledb = require('oracledb');
var dbConfig = require('./dbconfig.js');
// Prefetching is a tuning feature for optimizing row transfer from
// the Oracle Database to node-oracledb with ResultSets. The default
// prefetch size is 100. The prefetch size does not affect how, or
// when, rows are returned by node-oracledb to the application.
// Buffering is handled by the underlying Oracle client libraries.
// Benchmark to choose the optimal size for each application or query.
// fetchArraySize can be adjusted to tune data transfer from the
// Oracle Database to node-oracledb. The value of fetchArraySize does
// not affect how, or when, rows are returned by node-oracledb to the
// application. Buffering is handled by node-oracledb. Benchmark to
// choose the optimal size for each application or query.
//
//oracledb.prefetchRows = 100;
//oracledb.fetchArraySize = 100; // default value is 100
var numRows = 10; // number of rows to return from each call to getRows()

View File

@ -22,11 +22,22 @@
* Executes a query and uses a ResultSet to fetch rows with getRow().
* Uses Oracle's sample HR schema.
*
* Note using queryStream() or getRows() is recommended instead of
* getRow().
*
*****************************************************************************/
var oracledb = require('oracledb');
var dbConfig = require('./dbconfig.js');
// fetchArraySize can be adjusted to tune data transfer from the
// Oracle Database to node-oracledb. The value of fetchArraySize does
// not affect how, or when, rows are returned by node-oracledb to the
// application. Buffering is handled by node-oracledb. Benchmark to
// choose the optimal size for each application or query.
//
//oracledb.fetchArraySize = 100; // default value is 100
var rowCount = 0;
oracledb.getConnection(

View File

@ -20,7 +20,7 @@
*
* DESCRIPTION
* Executes a query and uses a ResultSet to fetch batches of rows
* with getRows(). Also shows setting the prefetch size.
* with getRows(). Also shows setting the fetch array size.
* Uses Oracle's sample HR schema.
*
*****************************************************************************/
@ -28,16 +28,21 @@
var oracledb = require('oracledb');
var dbConfig = require('./dbconfig.js');
// Prefetching is a tuning feature for optimizing row transfer from
// the Oracle Database to node-oracledb with ResultSets. The default
// prefetch size is 100. The prefetch size does not affect how, or
// when, rows are returned by node-oracledb to the application.
// Buffering is handled by the underlying Oracle client libraries.
// Benchmark to choose the optimal size for each application or query.
//
//oracledb.prefetchRows = 100;
var numRows = 10; // number of rows to return from each call to getRows()
// Number of rows to return from each call to getRows()
var numRows = 10;
// fetchArraySize can be adjusted to tune data transfer from the
// Oracle Database to node-oracledb. The value of fetchArraySize does
// not affect how, or when, rows are returned by node-oracledb to the
// application. Buffering is handled by node-oracledb. Benchmark to
// choose the optimal size for each application or query.
//
// For small values of numRows, use the same value for fetchArraySize.
// For large values of numRows use a factor of that value for
// fetchArraySize.
oracledb.fetchArraySize = 10;
oracledb.getConnection(
{
@ -55,8 +60,8 @@ oracledb.getConnection(
ORDER BY employee_id`,
[], // no bind variables
{
resultSet: true, // return a ResultSet. Default is false
prefetchRows: 25 // the prefetch size can be set for each query
resultSet: true // return a ResultSet. Default is false
//, fetchArraySize: 10 // this can also be set per statement
},
function(err, result)
{

View File

@ -43,8 +43,7 @@ oracledb.getConnection(
sql,
[],
{
resultSet: true,
prefetchRows: 25
resultSet: true
},
function(err, result)
{

View File

@ -59,10 +59,13 @@ oracledb.getConnection(
// execute() options argument. Since the query only returns one
// row, we can optimize memory usage by reducing the default
// maxRows value. Other options such as the query result format
// or whether to get extra metadata could be used:
// { maxRows: 1, outFormat: oracledb.OBJECT, extendedMetaData: true },
{ maxRows: 1 },
// maxRows value. For the complete list of other options see
// the documentation.
{ maxRows: 1
//, outFormat: oracledb.OBJECT // query result format
//, extendedMetaData: true // get extra metadata
//, fetchArraySize: 100 // internal buffer allocation size for tuning
},
// The callback function handles the SQL execution results
function(err, result)

View File

@ -36,13 +36,20 @@ var dbConfig = require('./dbconfig.js');
// executions. They can also be set or overridden at the individual
// execute() call level
// The default value for maxRows is 100 meaning only 100 rows will be
// fetched. Rows after this will not be fetched. No error will
// occur. Increasing maxRows will increase memory usage so when the
// number of query rows is large, or not known, it is recommended to
// use a ResultSet (see resultset1.js) or Stream (see selectstream.js).
// Use maxRows to limit the number of rows returned. Rows after this
// will not be fetched. No error will occur. It is prefereable to
// use a row limiting SQL clause such as OFFSET / FETCH so the
// database does not process extra rows unnecessarily.
//
// oracledb.maxRows = 100;
// oracledb.maxRows = 100; // default value is 100
// fetchArraySize can be adjusted to tune data transfer from the
// Oracle Database to node-oracledb. The value of fetchArraySize does
// not affect how, or when, rows are returned by node-oracledb to the
// application. Buffering is handled by node-oracledb. Benchmark to
// choose the optimal size for each application or query.
//
//oracledb.fetchArraySize = 100; // default value is 100
// This script sets outFormat in the execute() call but it could be set here instead:
//

View File

@ -30,6 +30,8 @@
var oracledb = require('oracledb');
var dbConfig = require('./dbconfig.js');
var rowcount = 0;
oracledb.getConnection(
{
user : dbConfig.user,
@ -44,7 +46,9 @@ oracledb.getConnection(
}
var stream = connection.queryStream(
'SELECT first_name, last_name FROM employees ORDER BY employee_id'
'SELECT first_name, last_name FROM employees ORDER BY employee_id',
[], // no binds
{ fetchArraySize: 100 } // internal buffer size for performance tuning
);
stream.on('error', function (error) {
@ -61,10 +65,12 @@ oracledb.getConnection(
stream.on('data', function (data) {
// console.log("stream 'data' event");
console.log(data);
rowcount++;
});
stream.on('end', function () {
// console.log("stream 'end' event");
console.log('Rows selected: ' + rowcount);
connection.close(
function(err) {
if (err) {

View File

@ -52,6 +52,8 @@ function queryStream(sql, binding, options) {
options.resultSet = true;
stream = new QueryStream(null, self._oracledb);
if (options.fetchArraySize)
stream._fetchArraySize = options.fetchArraySize;
self._execute(sql, binding, options, function(err, result) {
if (err) {

View File

@ -51,6 +51,10 @@ function QueryStream(resultSet, oracledb) {
_closed: { // used to track that the stream is closed
value: false,
writable: true
},
_fetchArraySize: { // used to identify the fetch array size
value: oracledb.fetchArraySize,
writable: true
}
}
);
@ -125,7 +129,7 @@ QueryStream.prototype._read = function () {
// errors related to close w/conncurrent operations on resultsets
self._fetching = true;
fetchCount = self._oracledb.maxRows || 100;
fetchCount = self._fetchArraySize;
// Calling the C layer getRows directly to avoid assertions on the public method
self._resultSet._getRows(fetchCount, function(err, rows) {

View File

@ -485,6 +485,29 @@ bool njsBaton::GetIntFromJSON(Local<Object> obj, const char *key,
}
//-----------------------------------------------------------------------------
// njsBaton::GetPositiveIntFromJSON()
// Gets a positive integer value from the JSON object for the given key, if
// possible. If undefined, leave value alone and do not set error; otherwise,
// set error. Index is the argument index in the caller.
//-----------------------------------------------------------------------------
bool njsBaton::GetPositiveIntFromJSON(Local<Object> obj, const char *key,
int index, uint32_t *value)
{
uint32_t tempValue = *value;
if (!GetUnsignedIntFromJSON(obj, key, index, &tempValue))
return false;
if (tempValue == 0) {
error = njsMessages::Get(errInvalidPropertyValueInParam, key,
index + 1);
return false;
}
*value = tempValue;
return true;
}
//-----------------------------------------------------------------------------
// njsBaton::GetStringFromJSON()
// Gets a string value from the JSON object for the given key, if possible.
@ -698,6 +721,28 @@ bool njsCommon::SetPropInt(Local<Value> value, int32_t *valuePtr,
}
//-----------------------------------------------------------------------------
// njsCommon::SetPropPositiveInt()
// Sets a property to a positive integer value. If the value is not a
// positive integer, an error is raised and false is returned.
//-----------------------------------------------------------------------------
bool njsCommon::SetPropPositiveInt(Local<Value> value, uint32_t *valuePtr,
const char *name)
{
uint32_t tempValue = *valuePtr;
if (!SetPropUnsignedInt(value, &tempValue, name))
return false;
if (tempValue == 0) {
string errMsg = njsMessages::Get(errInvalidPropertyValue, name);
Nan::ThrowError(errMsg.c_str());
return false;
}
*valuePtr = tempValue;
return true;
}
//-----------------------------------------------------------------------------
// njsCommon::SetPropString()
// Sets a property to a string value. If the value is not a string, an error

View File

@ -218,6 +218,8 @@ protected:
uint32_t *value);
bool SetPropBool(Local<Value> value, bool *valuePtr, const char *name);
bool SetPropInt(Local<Value> value, int32_t *valuePtr, const char *name);
bool SetPropPositiveInt(Local<Value> value, uint32_t *valuePtr,
const char *name);
bool SetPropString(Local<Value> value, std::string *valuePtr,
const char *name);
bool SetPropUnsignedInt(Local<Value> value, uint32_t *valuePtr,
@ -256,7 +258,7 @@ public:
uint32_t stmtCacheSize;
uint32_t lobPrefetchSize;
uint32_t maxRows;
uint32_t prefetchRows;
uint32_t fetchArraySize;
uint32_t rowsFetched;
uint32_t bufferRowIndex;
uint64_t rowsAffected;
@ -330,6 +332,8 @@ public:
bool *value);
bool GetStringFromJSON(Local<Object> obj, const char *key, int index,
string &value);
bool GetPositiveIntFromJSON(Local<Object> obj, const char *key, int index,
uint32_t *value);
bool GetIntFromJSON(Local<Object> obj, const char *key, int index,
int32_t *value);
bool GetUnsignedIntFromJSON(Local<Object> obj, const char *key, int index,

View File

@ -66,9 +66,6 @@ Nan::Persistent<FunctionTemplate> njsConnection::connectionTemplate_s;
// max number of bytes for data converted to string with fetchAsString or fetchInfo
#define NJS_MAX_FETCH_AS_STRING_SIZE 200
// number of rows prefetched by non-ResultSet queries
#define NJS_PREFETCH_NON_RESULTSET 2
//-----------------------------------------------------------------------------
// njsConnection::Init()
// Initialization function of Connection class. Maps functions and properties
@ -158,14 +155,13 @@ bool njsConnection::ProcessQueryVars(njsBaton *baton, dpiStmt *dpiStmtHandle,
// get query information for the specified column
vars[i].pos = i + 1;
vars[i].isArray = false;
vars[i].maxArraySize = 0;
vars[i].bindDir = NJS_BIND_OUT;
if (dpiStmt_getQueryInfo(dpiStmtHandle, vars[i].pos, &queryInfo) < 0) {
baton->GetDPIError();
return false;
}
vars[i].name = std::string(queryInfo.name, queryInfo.nameLength);
vars[i].maxArraySize = baton->maxRows;
vars[i].maxArraySize = baton->fetchArraySize;
vars[i].dbSizeInBytes = queryInfo.typeInfo.dbSizeInBytes;
vars[i].precision = queryInfo.typeInfo.precision +
queryInfo.typeInfo.fsPrecision;
@ -247,30 +243,22 @@ bool njsConnection::ProcessQueryVars(njsBaton *baton, dpiStmt *dpiStmtHandle,
//-----------------------------------------------------------------------------
bool njsConnection::ProcessFetch(njsBaton *baton)
{
int moreRows, setFetchArraySize = 0;
uint32_t i, numRowsToFetch;
njsVariable *var;
uint32_t i;
int moreRows;
// create ODPI-C variables and define them, if necessary
for (i = 0; i < baton->numQueryVars; i++) {
var = &baton->queryVars[i];
if (var->dpiVarHandle)
continue;
if (!setFetchArraySize) {
setFetchArraySize = 1;
if (dpiStmt_setFetchArraySize(baton->dpiStmtHandle,
baton->maxRows) < 0) {
baton->GetDPIError();
return false;
}
}
if (dpiConn_newVar(baton->dpiConnHandle, var->varTypeNum,
var->nativeTypeNum, baton->maxRows, var->maxSize, 1, 0, NULL,
&var->dpiVarHandle, &var->dpiVarData) < 0) {
var->nativeTypeNum, baton->fetchArraySize, var->maxSize, 1, 0,
NULL, &var->dpiVarHandle, &var->dpiVarData) < 0) {
baton->GetDPIError();
return false;
}
var->maxArraySize = baton->maxRows;
var->maxArraySize = baton->fetchArraySize;
if (dpiStmt_define(baton->dpiStmtHandle, i + 1,
var->dpiVarHandle) < 0) {
baton->GetDPIError();
@ -278,8 +266,10 @@ bool njsConnection::ProcessFetch(njsBaton *baton)
}
}
// perform fetch
if (dpiStmt_fetchRows(baton->dpiStmtHandle, baton->maxRows,
// perform fetch, but do not fetch more rows than requested at this time
numRowsToFetch = (baton->fetchArraySize < baton->maxRows) ?
baton->fetchArraySize : baton->maxRows;
if (dpiStmt_fetchRows(baton->dpiStmtHandle, numRowsToFetch,
&baton->bufferRowIndex, &baton->rowsFetched, &moreRows) < 0) {
baton->GetDPIError();
return false;
@ -323,6 +313,11 @@ bool njsConnection::ProcessVars(njsBaton *baton, njsVariable *vars,
baton->GetDPIError();
return false;
}
if (dpiStmt_setFetchArraySize(stmt,
baton->fetchArraySize) < 0) {
baton->GetDPIError();
return false;
}
var->queryVars = new njsVariable[var->numQueryVars];
if (!ProcessQueryVars(baton, stmt, var->queryVars,
var->numQueryVars))
@ -1145,8 +1140,8 @@ bool njsConnection::ProcessOptions(Nan::NAN_METHOD_ARGS_TYPE args,
Local<Object> options = args[index]->ToObject();
if (!baton->GetUnsignedIntFromJSON(options, "maxRows", 2, &baton->maxRows))
return false;
if (!baton->GetUnsignedIntFromJSON(options, "prefetchRows", 2,
&baton->prefetchRows))
if (!baton->GetPositiveIntFromJSON(options, "fetchArraySize", 2,
&baton->fetchArraySize))
return false;
if (!baton->GetUnsignedIntFromJSON(options, "outFormat", 2,
&baton->outFormat))
@ -1459,7 +1454,7 @@ NAN_METHOD(njsConnection::Execute)
baton->jsOracledb.Reset(connection->jsOracledb);
oracledb = baton->GetOracledb();
baton->maxRows = oracledb->getMaxRows();
baton->prefetchRows = oracledb->getPrefetchRows();
baton->fetchArraySize = oracledb->getFetchArraySize();
oracledb->SetFetchAsStringTypesOnBaton(baton);
oracledb->SetFetchAsBufferTypesOnBaton(baton);
baton->outFormat = oracledb->getOutFormat();
@ -1500,9 +1495,15 @@ void njsConnection::Async_Execute(njsBaton *baton)
// for queries, perform defines and ensure that rows have been fetched
if (baton->numQueryVars > 0) {
// for result sets, use the default array size, if value is zero
if (baton->getRS && baton->maxRows == 0)
baton->maxRows = NJS_MAX_ROWS;
// adjust fetch array size downward if it exceeds maxRows for basic
// fetches (no need to waste memory!)
if (!baton->getRS && baton->maxRows < baton->fetchArraySize)
baton->fetchArraySize = baton->maxRows;
if (dpiStmt_setFetchArraySize(baton->dpiStmtHandle,
baton->fetchArraySize) < 0) {
baton->GetDPIError();
return;
}
// perform defines
baton->queryVars = new njsVariable[baton->numQueryVars];
@ -1529,9 +1530,9 @@ void njsConnection::Async_Execute(njsBaton *baton)
return;
}
// if not getting a result set, we no longer require the statement so
// release it now
if (!baton->getRS) {
// if not getting a result set and there are no more rows to fetch, we no
// longer require the statement so release it now
if (!baton->getRS && baton->rowsFetched == baton->maxRows) {
if (dpiStmt_release(baton->dpiStmtHandle) < 0)
baton->GetDPIError();
baton->dpiStmtHandle = NULL;
@ -1547,6 +1548,38 @@ void njsConnection::Async_AfterExecute(njsBaton *baton, Local<Value> argv[])
{
Nan::EscapableHandleScope scope;
Local<Object> result = Nan::New<v8::Object>();
Local<Object> callingObj, rows;
Local<Function> callback;
njsBaton *newBaton;
// for direct fetch, first check to see if more round trips are required
if (baton->queryVars && !baton->getRS) {
if (!njsConnection::GetRows(baton, rows))
return;
if (baton->rowsFetched < baton->maxRows) {
callback = Nan::New<Function>(baton->jsCallback);
callingObj = Nan::New(baton->jsCallingObj);
newBaton = new njsBaton(callback, callingObj);
baton->jsCallback.Reset();
newBaton->fetchArraySize = baton->fetchArraySize;
newBaton->maxRows = baton->maxRows - baton->rowsFetched;
newBaton->fetchMultipleRows = true;
newBaton->jsRows.Reset(rows);
newBaton->dpiStmtHandle = baton->dpiStmtHandle;
baton->dpiStmtHandle = NULL;
newBaton->dpiConnHandle = baton->dpiConnHandle;
baton->dpiConnHandle = NULL;
newBaton->jsOracledb.Reset(baton->jsOracledb);
newBaton->queryVars = baton->queryVars;
newBaton->numQueryVars = baton->numQueryVars;
newBaton->outFormat = baton->outFormat;
newBaton->getRS = false;
baton->keepQueryInfo = true;
newBaton->QueueWork("Execute", Async_ExecuteGetMoreRows,
Async_AfterExecute, 2);
return;
}
}
// handle queries
if (baton->queryVars) {
@ -1572,9 +1605,6 @@ void njsConnection::Async_AfterExecute(njsBaton *baton, Local<Value> argv[])
// otherwise, return rows
} else {
Local<Object> rows;
if (!GetRows(baton, rows))
return;
Nan::Set(result, Nan::New<v8::String>("rows").ToLocalChecked(),
rows);
Nan::Set(result,
@ -1604,6 +1634,17 @@ void njsConnection::Async_AfterExecute(njsBaton *baton, Local<Value> argv[])
}
//-----------------------------------------------------------------------------
// njsConnection::Async_ExecuteGetMoreRows()
// Worker function for njsConnection::Execute() method called when additional
// round trips to the database are required.
//-----------------------------------------------------------------------------
void njsConnection::Async_ExecuteGetMoreRows(njsBaton *baton)
{
ProcessFetch(baton);
}
//-----------------------------------------------------------------------------
// njsConnection::Release()
// Releases the connection from use by JS. This releases the connection back

View File

@ -95,6 +95,7 @@ private:
static NAN_METHOD(Execute);
static void Async_Execute(njsBaton *baton);
static void Async_AfterExecute(njsBaton *baton, Local<Value> argv[]);
static void Async_ExecuteGetMoreRows(njsBaton *baton);
// Release Method on Connection class
static NAN_METHOD(Release);

View File

@ -83,7 +83,7 @@ njsOracledb::njsOracledb()
poolMin = NJS_POOL_MIN;
poolIncrement = NJS_POOL_INCR;
poolTimeout = NJS_POOL_TIMEOUT;
prefetchRows = NJS_PREFETCH_ROWS;
fetchArraySize = DPI_DEFAULT_FETCH_ARRAY_SIZE;
connClass = "";
externalAuth = false;
lobPrefetchSize = NJS_LOB_PREFETCH_SIZE;
@ -144,8 +144,8 @@ void njsOracledb::Init(Handle<Object> target)
Nan::New<v8::String>("stmtCacheSize").ToLocalChecked(),
njsOracledb::GetStmtCacheSize, njsOracledb::SetStmtCacheSize);
Nan::SetAccessor(temp->InstanceTemplate(),
Nan::New<v8::String>("prefetchRows").ToLocalChecked(),
njsOracledb::GetPrefetchRows, njsOracledb::SetPrefetchRows);
Nan::New<v8::String>("fetchArraySize").ToLocalChecked(),
njsOracledb::GetFetchArraySize, njsOracledb::SetFetchArraySize);
Nan::SetAccessor(temp->InstanceTemplate(),
Nan::New<v8::String>("autoCommit").ToLocalChecked(),
njsOracledb::GetAutoCommit, njsOracledb::SetAutoCommit);
@ -423,27 +423,27 @@ NAN_SETTER(njsOracledb::SetStmtCacheSize)
//-----------------------------------------------------------------------------
// njsOracledb::GetPrefetchRows()
// Get accessor of "prefetchRows" property.
// njsOracledb::GetFetchArraySize()
// Get accessor of "fetchArraySize" property.
//-----------------------------------------------------------------------------
NAN_GETTER(njsOracledb::GetPrefetchRows)
NAN_GETTER(njsOracledb::GetFetchArraySize)
{
njsOracledb *oracledb = (njsOracledb*) ValidateGetter(info);
if (oracledb)
info.GetReturnValue().Set(oracledb->prefetchRows);
info.GetReturnValue().Set(oracledb->fetchArraySize);
}
//-----------------------------------------------------------------------------
// njsOracledb::SetPrefetchRows()
// Set accessor of "prefetchRows" property.
// njsOracledb::SetFetchArraySize()
// Set accessor of "fetchArraySize" property.
//-----------------------------------------------------------------------------
NAN_SETTER(njsOracledb::SetPrefetchRows)
NAN_SETTER(njsOracledb::SetFetchArraySize)
{
njsOracledb *oracledb = (njsOracledb*) ValidateSetter(info);
if (oracledb)
oracledb->SetPropUnsignedInt(value, &oracledb->prefetchRows,
"prefetchRows");
oracledb->SetPropPositiveInt(value, &oracledb->fetchArraySize,
"fetchArraySize");
}

View File

@ -92,7 +92,6 @@ using namespace v8;
#define NJS_POOL_MAX 4
#define NJS_POOL_INCR 1
#define NJS_POOL_TIMEOUT 60
#define NJS_PREFETCH_ROWS 100
#define NJS_LOB_PREFETCH_SIZE 16384
#define NJS_POOL_DEFAULT_PING_INTERVAL 60
@ -115,7 +114,7 @@ public:
unsigned int getPoolMax() const { return poolMax; }
unsigned int getPoolIncrement() const { return poolIncrement; }
unsigned int getPoolTimeout() const { return poolTimeout; }
unsigned int getPrefetchRows() const { return prefetchRows; }
unsigned int getFetchArraySize() const { return fetchArraySize; }
const std::string& getConnectionClass() const { return connClass; }
bool getExtendedMetaData() const { return extendedMetaData; }
bool IsValid() const { return true; }
@ -152,7 +151,7 @@ private:
static NAN_GETTER(GetVersion);
static NAN_GETTER(GetConnectionClass);
static NAN_GETTER(GetExternalAuth);
static NAN_GETTER(GetPrefetchRows);
static NAN_GETTER(GetFetchArraySize);
static NAN_GETTER(GetFetchAsString);
static NAN_GETTER(GetFetchAsBuffer);
static NAN_GETTER(GetLobPrefetchSize);
@ -172,7 +171,7 @@ private:
static NAN_SETTER(SetVersion);
static NAN_SETTER(SetConnectionClass);
static NAN_SETTER(SetExternalAuth);
static NAN_SETTER(SetPrefetchRows);
static NAN_SETTER(SetFetchArraySize);
static NAN_SETTER(SetFetchAsString);
static NAN_SETTER(SetFetchAsBuffer);
static NAN_SETTER(SetLobPrefetchSize);
@ -190,7 +189,7 @@ private:
uint32_t maxRows;
uint32_t stmtCacheSize;
uint32_t prefetchRows;
uint32_t fetchArraySize;
uint32_t poolMin;
uint32_t poolMax;

View File

@ -129,6 +129,7 @@ Local<Object> njsResultSet::CreateFromBaton(njsBaton *baton)
resultSet->outFormat = baton->outFormat;
resultSet->numQueryVars = baton->numQueryVars;
resultSet->queryVars = baton->queryVars;
resultSet->fetchArraySize = baton->fetchArraySize;
baton->queryVars = NULL;
resultSet->activeBaton = NULL;
resultSet->jsConnection.Reset(baton->jsCallingObj);
@ -164,6 +165,7 @@ bool njsResultSet::CreateFromRefCursor(njsBaton *baton, dpiStmt *dpiStmtHandle,
resultSet->activeBaton = NULL;
resultSet->queryVars = queryVars;
resultSet->numQueryVars = numQueryVars;
resultSet->fetchArraySize = baton->fetchArraySize;
value = scope.Escape(obj);
return true;
}
@ -301,6 +303,7 @@ void njsResultSet::GetRowsCommon(njsBaton *baton)
baton->numQueryVars = numQueryVars;
baton->keepQueryInfo = true;
baton->jsOracledb.Reset(jsOracledb);
baton->fetchArraySize = fetchArraySize;
}
baton->QueueWork("GetRowsCommon", Async_GetRows, Async_AfterGetRows, 2);
}

View File

@ -106,6 +106,7 @@ private:
dpiStmt *dpiStmtHandle;
dpiConn *dpiConnHandle;
uint32_t numQueryVars;
uint32_t fetchArraySize;
njsVariable *queryVars;
uint32_t outFormat;
bool extendedMetaData;

View File

@ -904,7 +904,7 @@ describe('3. examples.js', function(){
connection.execute(
"SELECT employees_name FROM nodb_eg_emp10",
[],
{ resultSet: true, prefetchRows: 50 },
{ resultSet: true, fetchArraySize: 50 },
function(err, result) {
should.not.exist(err);
(result.resultSet.metaData[0]).name.should.eql('EMPLOYEES_NAME');
@ -938,7 +938,7 @@ describe('3. examples.js', function(){
connection.execute(
"SELECT * FROM nodb_eg_emp10 ORDER BY employees_id",
[],
{ resultSet: true, prefetchRows: 110 },
{ resultSet: true, fetchArraySize: 110 },
function(err, result) {
should.not.exist(err);
(result.resultSet.metaData[0]).name.should.eql('EMPLOYEES_ID');

View File

@ -243,12 +243,12 @@ Overview of node-oracledb functional tests
12.1.7 negative - 1
12.1.8 negative - (-1)
12.1.9 negative - random string
12.2 Testing prefetchRows option
12.2 Testing fetchArraySize option
12.2.1 negative - negative value
12.2.2 negative - random string
12.2.3 negative - NaN
12.2.4 negative - null
12.2.5 prefetchRows can be set to 0
12.2.5 negative - zero value
12.3 Testing function getRows()
12.3.1 retrieved set is exactly the size of result
12.3.2 retrieved set is greater than the size of result
@ -304,9 +304,8 @@ Overview of node-oracledb functional tests
13.2.1 should be able to stop the stream early with _close
13.2.2 should be able to stop the stream before any data
13.2.3 should invoke an optional callback passed to _close
13.3 Testing QueryStream\'s maxRows control
13.3.1 should use oracledb.maxRows for fetching
13.3.2 should default to 100 if oracledb.maxRows is false
13.3 Testing QueryStream's fetchArraySize option
13.3.1 should use oracledb.fetchArraySize for fetching
14. stream2.js
14.1 Bind by position and return an array
@ -874,7 +873,7 @@ Overview of node-oracledb functional tests
58.1.3 poolIncrement
58.1.4 poolTimeout
58.1.5 maxRows
58.1.6 prefetchRows
58.1.6 fetchArraySize
58.1.7 autoCommit
58.1.8 version (read-only)
58.1.9 connectionClass

View File

@ -52,7 +52,7 @@ describe('58. properties.js', function() {
defaultValues.poolIncrement = oracledb.poolIncrement;
defaultValues.poolTimeout = oracledb.poolTimeout;
defaultValues.maxRows = oracledb.maxRows;
defaultValues.prefetchRows = oracledb.prefetchRows;
defaultValues.fetchArraySize = oracledb.fetchArraySize;
defaultValues.autoCommit = oracledb.autoCommit;
defaultValues.version = oracledb.version;
defaultValues.connectionClass = oracledb.connectionClass;
@ -73,7 +73,7 @@ describe('58. properties.js', function() {
oracledb.poolIncrement = defaultValues.poolIncrement;
oracledb.poolTimeout = defaultValues.poolTimeout;
oracledb.maxRows = defaultValues.maxRows;
oracledb.prefetchRows = defaultValues.prefetchRows;
oracledb.fetchArraySize = defaultValues.fetchArraySize;
oracledb.autoCommit = defaultValues.autoCommit;
// oracledb.version = defaultValues.version; // version is a read-only property. it needn't to restore.
oracledb.connectionClass = defaultValues.connectionClass;
@ -128,12 +128,12 @@ describe('58. properties.js', function() {
(oracledb.maxRows).should.eql(defaultValues.maxRows + 1);
});
it('58.1.6 prefetchRows', function() {
var t = oracledb.prefetchRows;
oracledb.prefetchRows = t + 1;
it('58.1.6 fetchArraySize', function() {
var t = oracledb.fetchArraySize;
oracledb.fetchArraySize = t + 1;
t.should.eql(defaultValues.prefetchRows);
(oracledb.prefetchRows).should.eql(defaultValues.prefetchRows + 1);
t.should.eql(defaultValues.fetchArraySize);
(oracledb.fetchArraySize).should.eql(defaultValues.fetchArraySize + 1);
});
it('58.1.7 autoCommit', function() {

View File

@ -116,7 +116,7 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: false, prefetchRows: 100, maxRows: 1000 },
{ resultSet: false, fetchArraySize: 100, maxRows: 1000 },
function(err, result) {
should.not.exist(err);
@ -135,7 +135,7 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: true, prefetchRows: 100, maxRows: 1000 },
{ resultSet: true, fetchArraySize: 100, maxRows: 1000 },
function(err, result) {
should.not.exist(err);
@ -152,7 +152,7 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: 0, prefetchRows: 100, maxRows: 1000 },
{ resultSet: 0, fetchArraySize: 100, maxRows: 1000 },
function(err, result) {
should.not.exist(result);
should.exist(err);
@ -168,7 +168,7 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: null, prefetchRows: 100, maxRows: 1000 },
{ resultSet: null, fetchArraySize: 100, maxRows: 1000 },
function(err, result) {
should.not.exist(result);
should.exist(err);
@ -184,7 +184,7 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: undefined, prefetchRows: 100, maxRows: 1000 },
{ resultSet: undefined, fetchArraySize: 100, maxRows: 1000 },
function(err, result) {
should.not.exist(err);
@ -202,7 +202,7 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: NaN, prefetchRows: 100, maxRows: 1000 },
{ resultSet: NaN, fetchArraySize: 100, maxRows: 1000 },
function(err, result) {
should.not.exist(result);
should.exist(err);
@ -218,7 +218,7 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: 1, prefetchRows: 100, maxRows: 1000 },
{ resultSet: 1, fetchArraySize: 100, maxRows: 1000 },
function(err, result) {
should.not.exist(result);
should.exist(err);
@ -234,7 +234,7 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: -1, prefetchRows: 100, maxRows: 1000 },
{ resultSet: -1, fetchArraySize: 100, maxRows: 1000 },
function(err, result) {
should.not.exist(result);
should.exist(err);
@ -250,7 +250,7 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: 'foo', prefetchRows: 100, maxRows: 1000 },
{ resultSet: 'foo', fetchArraySize: 100, maxRows: 1000 },
function(err, result) {
should.not.exist(result);
should.exist(err);
@ -262,18 +262,18 @@ describe('12. resultSet1.js', function() {
});
describe('12.2 Testing prefetchRows option', function() {
describe('12.2 Testing fetchArraySize option', function() {
it('12.2.1 negative - negative value', function(done) {
connection.should.be.ok();
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: true, prefetchRows: -10, maxRows: 1000 },
{ resultSet: true, fetchArraySize: -10, maxRows: 1000 },
function(err) {
should.exist(err);
(err.message).should.startWith('NJS-007:');
// NJS-007: invalid value for "prefetchRows"
// NJS-007: invalid value for "fetchArraySize"
done();
}
);
@ -285,11 +285,11 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: true, prefetchRows: 'bar', maxRows: 1000 },
{ resultSet: true, fetchArraySize: 'bar', maxRows: 1000 },
function(err) {
should.exist(err);
(err.message).should.startWith('NJS-008:');
// NJS-008: invalid type for "prefetchRows"
// NJS-008: invalid type for "fetchArraySize"
done();
}
);
@ -301,11 +301,11 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: true, prefetchRows: NaN, maxRows: 1000 },
{ resultSet: true, fetchArraySize: NaN, maxRows: 1000 },
function(err) {
should.exist(err);
(err.message).should.startWith('NJS-007:');
// NJS-007: invalid value for "prefetchRows"
// NJS-007: invalid value for "fetchArraySize"
done();
}
);
@ -317,26 +317,28 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: true, prefetchRows: null, maxRows: 1000 },
{ resultSet: true, fetchArraySize: null, maxRows: 1000 },
function(err, result) {
should.not.exist(result);
should.exist(err);
should.strictEqual(err.message, "NJS-007: invalid value for \"prefetchRows\" in parameter 3");
should.strictEqual(err.message, "NJS-007: invalid value for \"fetchArraySize\" in parameter 3");
done();
}
);
});
it('12.2.5 prefetchRows can be set to 0', function(done) {
it('12.2.5 negative - zero value', function(done) {
connection.should.be.ok();
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: true, prefetchRows: 0, maxRows: 1000 },
{ resultSet: true, fetchArraySize: 0, maxRows: 1000 },
function(err, result) {
should.not.exist(err);
result.resultSet.close(done);
should.not.exist(result);
should.exist(err);
should.strictEqual(err.message, "NJS-007: invalid value for \"fetchArraySize\" in parameter 3");
done();
}
);
});
@ -352,7 +354,7 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: true, prefetchRows: 100 },
{ resultSet: true, fetchArraySize: 100 },
function(err, result) {
should.not.exist(err);
fetchRowFromRS(result.resultSet, nRows);
@ -385,7 +387,7 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: true, prefetchRows: 100 },
{ resultSet: true, fetchArraySize: 100 },
function(err, result) {
should.not.exist(err);
fetchRowFromRS(result.resultSet, nRows);
@ -418,7 +420,7 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: true, prefetchRows: 100 },
{ resultSet: true, fetchArraySize: 100 },
function(err, result) {
should.not.exist(err);
fetchRowFromRS(result.resultSet, nRows);
@ -451,7 +453,7 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: true, prefetchRows: 100 },
{ resultSet: true, fetchArraySize: 100 },
function(err, result) {
should.not.exist(err);
fetchRowFromRS(result.resultSet, nRows);
@ -484,7 +486,7 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: true, prefetchRows: 100, outFormat: oracledb.ARRAY },
{ resultSet: true, fetchArraySize: 100, outFormat: oracledb.ARRAY },
function(err, result) {
should.not.exist(err);
fetchRowFromRS(result.resultSet, nRows);
@ -520,7 +522,7 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: true, prefetchRows: 100, outFormat: oracledb.OBJECT },
{ resultSet: true, fetchArraySize: 100, outFormat: oracledb.OBJECT },
function(err, result) {
should.not.exist(err);
fetchRowFromRS(result.resultSet, nRows);
@ -556,7 +558,7 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: true, prefetchRows: 100 },
{ resultSet: true, fetchArraySize: 100 },
function(err, result) {
should.not.exist(err);
fetchRowFromRS(result.resultSet, nRows);
@ -620,7 +622,7 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: true, prefetchRows: 100 },
{ resultSet: true, fetchArraySize: 100 },
function(err, result) {
should.not.exist(err);
fetchRowFromRS(result.resultSet);
@ -649,7 +651,7 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: true, prefetchRows: 100 },
{ resultSet: true, fetchArraySize: 100 },
function(err, result) {
should.not.exist(err);
fetchRowFromRS(result.resultSet, nRows);
@ -678,7 +680,7 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: true, prefetchRows: 100 },
{ resultSet: true, fetchArraySize: 100 },
function(err, result) {
should.not.exist(err);
fetchRowFromRS(result.resultSet, nRows);
@ -707,7 +709,7 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: true, prefetchRows: 100 },
{ resultSet: true, fetchArraySize: 100 },
function(err, result) {
should.not.exist(err);
fetchRowFromRS(result.resultSet, nRows);
@ -738,7 +740,7 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: true, prefetchRows: 100 },
{ resultSet: true, fetchArraySize: 100 },
function(err, result) {
should.not.exist(err);
fetchRowFromRS(result.resultSet);
@ -771,7 +773,7 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: true, prefetchRows: 100, outFormat: oracledb.ARRAY },
{ resultSet: true, fetchArraySize: 100, outFormat: oracledb.ARRAY },
function(err, result) {
should.not.exist(err);
fetchRowFromRS(result.resultSet);
@ -805,7 +807,7 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: true, prefetchRows: 100, outFormat: oracledb.OBJECT },
{ resultSet: true, fetchArraySize: 100, outFormat: oracledb.OBJECT },
function(err, result) {
should.not.exist(err);
fetchRowFromRS(result.resultSet);
@ -871,7 +873,7 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: true, prefetchRows: 100 },
{ resultSet: true, fetchArraySize: 100 },
function(err, result) {
should.not.exist(err);
fetchRowFromRS(result.resultSet, nRows);
@ -904,7 +906,7 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: true, prefetchRows: 100 },
{ resultSet: true, fetchArraySize: 100 },
function(err, result) {
should.not.exist(err);
fetchRowFromRS(result.resultSet, nRows);
@ -934,7 +936,7 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: true, prefetchRows: 100 },
{ resultSet: true, fetchArraySize: 100 },
function(err, result) {
should.not.exist(err);
fetchRowFromRS(result.resultSet, nRows);
@ -970,7 +972,7 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: true, prefetchRows: 100 },
{ resultSet: true, fetchArraySize: 100 },
function(err, result) {
should.not.exist(err);
fetchRowFromRS(result.resultSet, nRows);
@ -1007,7 +1009,7 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT employees_name FROM nodb_rs1_emp",
[],
{ resultSet: true, prefetchRows: 100 },
{ resultSet: true, fetchArraySize: 100 },
function(err, result) {
should.not.exist(err);
fetchRowFromRS(result.resultSet, nRows, callback);
@ -1019,7 +1021,7 @@ describe('12. resultSet1.js', function() {
connection.execute(
"SELECT * FROM nodb_rs1_emp",
[],
{ resultSet: true, prefetchRows: 100 },
{ resultSet: true, fetchArraySize: 100 },
function(err, result) {
should.not.exist(err);
fetchRowFromRS(result.resultSet, nRows, callback);

View File

@ -546,25 +546,25 @@ describe('13. stream1.js', function () {
});
});
describe('13.3 Testing QueryStream\'s maxRows control', function () {
it('13.3.1 should use oracledb.maxRows for fetching', function (done) {
var defaultMaxRows;
var testMaxRows = 9;
describe('13.3 Testing QueryStream\'s fetchArraySize option', function () {
it('13.3.1 should use oracledb.fetchArraySize for fetching', function (done) {
var defaultFetchArraySize;
var testFetchArraySize = 9;
defaultMaxRows = oracledb.maxRows;
oracledb.maxRows = testMaxRows;
defaultFetchArraySize = oracledb.fetchArraySize;
oracledb.fetchArraySize = testFetchArraySize;
var stream = connection.queryStream('SELECT employee_name FROM nodb_stream1 ORDER BY employee_name');
stream.on('data', function () {
stream.pause();
// Using the internal/private caches to validate
should.equal(stream._fetchedRows.length, testMaxRows - (1 + stream._readableState.buffer.length));
should.equal(stream._fetchedRows.length, testFetchArraySize - (1 + stream._readableState.buffer.length));
stream._close();
});
stream.on('close', function() {
oracledb.maxRows = defaultMaxRows;
oracledb.fetchArraySize = defaultFetchArraySize;
done();
});
@ -576,20 +576,5 @@ describe('13. stream1.js', function () {
done(err);
});
});
it('13.3.2 Negative - should fail with NJS-026 if oracledb.maxRows is zero', function (done) {
var defaultMaxRows;
var testMaxRows = 0;
defaultMaxRows = oracledb.maxRows;
should.throws(
function() {
oracledb.maxRows = testMaxRows;
},
/NJS-026: maxRows must be greater than zero/
);
oracledb.maxRows = defaultMaxRows;
done();
}); // 13.3.2
});
});