Introduce fetchArraySize to replace prefetchRows for query fetch tuning
This commit is contained in:
parent
1b717b80e4
commit
885de16a56
62
INSTALL.md
62
INSTALL.md
|
@ -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
|
||||
|
|
772
doc/api.md
772
doc/api.md
File diff suppressed because it is too large
Load Diff
|
@ -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()
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -43,8 +43,7 @@ oracledb.getConnection(
|
|||
sql,
|
||||
[],
|
||||
{
|
||||
resultSet: true,
|
||||
prefetchRows: 25
|
||||
resultSet: true
|
||||
},
|
||||
function(err, result)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
//
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -106,6 +106,7 @@ private:
|
|||
dpiStmt *dpiStmtHandle;
|
||||
dpiConn *dpiConnHandle;
|
||||
uint32_t numQueryVars;
|
||||
uint32_t fetchArraySize;
|
||||
njsVariable *queryVars;
|
||||
uint32_t outFormat;
|
||||
bool extendedMetaData;
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue