Rework how errors are thrown

This commit is contained in:
Christopher Jones 2023-02-21 12:13:36 +11:00
parent 7126ff0c9a
commit 7665061280
16 changed files with 672 additions and 373 deletions

View File

@ -19,6 +19,7 @@
'use strict';
const errors = require('./errors.js');
const nodbUtil = require('./util.js');
class AqQueue {
@ -33,7 +34,7 @@ class AqQueue {
// Returns a single message from the queue, if one is available.
//---------------------------------------------------------------------------
async deqOne() {
nodbUtil.checkArgCount(arguments, 0, 0);
errors.assertArgCount(arguments, 0, 0);
return await this._deqOne();
}
@ -44,8 +45,8 @@ class AqQueue {
// if any are available.
//----------------------------------------------------------------------------
async deqMany(maxMessages) {
nodbUtil.checkArgCount(arguments, 1, 1);
nodbUtil.assert(typeof maxMessages === 'number', 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 1);
errors.assertParamValue(typeof maxMessages === 'number', 1);
return await this._deqMany(maxMessages);
}
@ -55,9 +56,9 @@ class AqQueue {
// Enqueues a single message into the queue.
//---------------------------------------------------------------------------
async enqOne(message) {
nodbUtil.checkArgCount(arguments, 1, 1);
nodbUtil.assert(typeof message === 'object' || typeof message === 'string',
'NJS-005', 1);
errors.assertArgCount(arguments, 1, 1);
errors.assertParamValue(typeof message === 'object' ||
typeof message === 'string', 1);
return await this._enqOne(message);
}
@ -68,8 +69,8 @@ class AqQueue {
// multiple round-trips.
//----------------------------------------------------------------------------
async enqMany(messages) {
nodbUtil.checkArgCount(arguments, 1, 1);
nodbUtil.assert(Array.isArray(messages), 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 1);
errors.assertParamValue(Array.isArray(messages), 1);
return await this._enqMany(messages);
}

View File

@ -22,6 +22,7 @@
const BaseDbObject = require('./dbObject.js');
const EventEmitter = require('events');
const QueryStream = require('./queryStream.js');
const errors = require('./errors.js');
const nodbUtil = require('./util.js');
const constants = require('./constants.js');
const settings = require('./settings.js');
@ -40,7 +41,7 @@ class Connection extends EventEmitter {
async _acquireLock() {
if (this._inProgress) {
if (settings.errorOnConcurrentExecute) {
throw new Error(nodbUtil.getErrorMessage('NJS-081'));
errors.throwErr(errors.ERR_CONCURRENT_OPS);
}
await new Promise((resolve, reject) => {
const payload = {resolve: resolve, reject: reject};
@ -105,7 +106,7 @@ class Connection extends EventEmitter {
// Breaks the execution of the statement.
//---------------------------------------------------------------------------
async breakExecution() {
nodbUtil.checkArgCount(arguments, 0, 0);
errors.assertArgCount(arguments, 0, 0);
await this._break();
}
@ -115,10 +116,10 @@ class Connection extends EventEmitter {
// Changes the password of the specified user.
//---------------------------------------------------------------------------
async changePassword(user, password, newPassword) {
nodbUtil.checkArgCount(arguments, 3, 3);
nodbUtil.assert(typeof user === 'string', 'NJS-005', 1);
nodbUtil.assert(typeof password === 'string', 'NJS-005', 2);
nodbUtil.assert(typeof newPassword === 'string', 'NJS-005', 3);
errors.assertArgCount(arguments, 3, 3);
errors.assertParamValue(typeof user === 'string', 1);
errors.assertParamValue(typeof password === 'string', 2);
errors.assertParamValue(typeof newPassword === 'string', 3);
await this._changePassword(user, password, newPassword);
}
@ -130,16 +131,16 @@ class Connection extends EventEmitter {
async close(a1) {
let options = {};
nodbUtil.checkArgCount(arguments, 0, 1);
errors.assertArgCount(arguments, 0, 1);
if (arguments.length == 1) {
nodbUtil.assert(nodbUtil.isObject(a1), 'NJS-005', 1);
errors.assertParamValue(nodbUtil.isObject(a1), 1);
options = a1;
}
// If already in the process of closing, throw an error instead of doing
// a roundtrip
if (this._closing) {
throw new Error (nodbUtil.getErrorMessage('NJS-003'));
errors.throwErr(errors.ERR_INVALID_CONNECTION);
}
this._closing = true;
@ -162,7 +163,7 @@ class Connection extends EventEmitter {
// Commits the current transaction.
//---------------------------------------------------------------------------
async commit() {
nodbUtil.checkArgCount(arguments, 0, 0);
errors.assertArgCount(arguments, 0, 0);
await this._commit();
}
@ -172,8 +173,8 @@ class Connection extends EventEmitter {
// Creates a temporary LOB and returns it to the caller.
//---------------------------------------------------------------------------
async createLob(type) {
nodbUtil.checkArgCount(arguments, 1, 1);
nodbUtil.assert(typeof type === 'number', 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 1);
errors.assertParamValue(typeof type === 'number', 1);
return (await this._createLob(type));
}
@ -186,17 +187,17 @@ class Connection extends EventEmitter {
let binds = [];
let executeOpts = {};
nodbUtil.checkArgCount(arguments, 1, 3);
nodbUtil.assert(typeof sql === 'string', 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 3);
errors.assertParamValue(typeof sql === 'string', 1);
switch (arguments.length) {
case 2:
nodbUtil.assert(nodbUtil.isObjectOrArray(a2), 'NJS-005', 2);
errors.assertParamValue(nodbUtil.isObjectOrArray(a2), 2);
binds = a2;
break;
case 3:
nodbUtil.assert(nodbUtil.isObjectOrArray(a2), 'NJS-005', 2);
nodbUtil.assert(nodbUtil.isObject(a3), 'NJS-005', 3);
errors.assertParamValue(nodbUtil.isObjectOrArray(a2), 2);
errors.assertParamValue(nodbUtil.isObject(a3), 3);
binds = a2;
executeOpts = a3;
break;
@ -235,18 +236,18 @@ class Connection extends EventEmitter {
async executeMany(sql, bindsOrNumIters, a3) {
let options = {};
nodbUtil.checkArgCount(arguments, 2, 3);
nodbUtil.assert(typeof sql === 'string', 'NJS-005', 1);
errors.assertArgCount(arguments, 2, 3);
errors.assertParamValue(typeof sql === 'string', 1);
if (typeof bindsOrNumIters === 'number') {
nodbUtil.assert(Number.isInteger(bindsOrNumIters), 'NJS-005', 2);
nodbUtil.assert(bindsOrNumIters > 0, 'NJS-005', 2);
errors.assertParamValue(Number.isInteger(bindsOrNumIters), 2);
errors.assertParamValue(bindsOrNumIters > 0, 2);
} else {
nodbUtil.assert(Array.isArray(bindsOrNumIters), 'NJS-005', 2);
nodbUtil.assert(bindsOrNumIters.length > 0, 'NJS-005', 2);
errors.assertParamValue(Array.isArray(bindsOrNumIters), 2);
errors.assertParamValue(bindsOrNumIters.length > 0, 2);
}
if (arguments.length == 3) {
nodbUtil.assert(nodbUtil.isObject(a3), 'NJS-005', 3);
errors.assertParamValue(nodbUtil.isObject(a3), 3);
options = a3;
}
@ -262,8 +263,8 @@ class Connection extends EventEmitter {
// using the fully qualified name.
//---------------------------------------------------------------------------
async getDbObjectClass(name) {
nodbUtil.checkArgCount(arguments, 1, 1);
nodbUtil.assert(typeof name === 'string', 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 1);
errors.assertParamValue(typeof name === 'string', 1);
let cls = this._dbObjectClasses[name];
if (cls) {
@ -280,10 +281,10 @@ class Connection extends EventEmitter {
async getQueue(name, a2) {
let options = {};
nodbUtil.checkArgCount(arguments, 1, 2);
nodbUtil.assert(typeof name === 'string', 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 2);
errors.assertParamValue(typeof name === 'string', 1);
if (arguments.length == 2) {
nodbUtil.assert(nodbUtil.isObject(a2), 'NJS-005', 2);
errors.assertParamValue(nodbUtil.isObject(a2), 2);
options = a2;
}
return (await this._getQueue(name, options));
@ -296,7 +297,7 @@ class Connection extends EventEmitter {
// the current connection).
//---------------------------------------------------------------------------
getSodaDatabase() {
nodbUtil.checkArgCount(arguments, 0, 0);
errors.assertArgCount(arguments, 0, 0);
return (this._getSodaDatabase());
}
@ -306,7 +307,7 @@ class Connection extends EventEmitter {
// Returns information about the statement.
//---------------------------------------------------------------------------
async getStatementInfo(sql) {
nodbUtil.checkArgCount(arguments, 1, 1);
errors.assertArgCount(arguments, 1, 1);
return (await this._getStatementInfo(sql));
}
@ -326,7 +327,7 @@ class Connection extends EventEmitter {
// Sends a "ping" to the database to see if it is "alive".
//---------------------------------------------------------------------------
async ping() {
nodbUtil.checkArgCount(arguments, 0, 0);
errors.assertArgCount(arguments, 0, 0);
await this._ping();
}
@ -338,15 +339,15 @@ class Connection extends EventEmitter {
// ---------------------------------------------------------------------------
queryStream(sql, binding, options) {
nodbUtil.checkArgCount(arguments, 1, 3);
nodbUtil.assert(typeof sql === 'string', 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 3);
errors.assertParamValue(typeof sql === 'string', 1);
if (binding) {
nodbUtil.assert(nodbUtil.isObjectOrArray(binding), 'NJS-005', 2);
errors.assertParamValue(nodbUtil.isObjectOrArray(binding), 2);
}
if (options) {
nodbUtil.assert(nodbUtil.isObject(options), 'NJS-005', 3);
errors.assertParamValue(nodbUtil.isObject(options), 3);
}
binding = binding || [];
@ -358,18 +359,13 @@ class Connection extends EventEmitter {
// calling execute() via nextTick to ensure that handlers are registered
// prior to the events being emitted
process.nextTick(() => {
process.nextTick(async () => {
try {
const p = this._execute(sql, binding, options);
p.then(function(result) {
if (!result.resultSet) {
stream.destroy(new Error(nodbUtil.getErrorMessage('NJS-019')));
} else {
stream._open(result.resultSet);
}
}, function(err) {
stream.destroy(err);
});
const result = await this._execute(sql, binding, options);
if (!result.resultSet) {
errors.throwErr(errors.ERR_NOT_A_QUERY);
}
stream._open(result.resultSet);
} catch (err) {
stream.destroy(err);
return;
@ -385,7 +381,7 @@ class Connection extends EventEmitter {
// Rolls back the current transaction.
//---------------------------------------------------------------------------
async rollback() {
nodbUtil.checkArgCount(arguments, 0, 0);
errors.assertArgCount(arguments, 0, 0);
await this._rollback();
}
@ -396,9 +392,9 @@ class Connection extends EventEmitter {
async shutdown(a1) {
let mode = constants.SHUTDOWN_MODE_DEFAULT;
nodbUtil.checkArgCount(arguments, 0, 1);
errors.assertArgCount(arguments, 0, 1);
if (a1 !== undefined) {
nodbUtil.assert(typeof mode === 'number', 'NJS-005', 1);
errors.assertParamValue(typeof mode === 'number', 1);
mode = a1;
}
@ -412,9 +408,9 @@ class Connection extends EventEmitter {
async startup(a1) {
let opts = {};
nodbUtil.checkArgCount(arguments, 0, 1);
errors.assertArgCount(arguments, 0, 1);
if (arguments.length == 1) {
nodbUtil.assert(typeof opts === 'object', 'NJS-005', 1);
errors.assertParamValue(typeof opts === 'object', 1);
opts = a1;
}
@ -428,9 +424,9 @@ class Connection extends EventEmitter {
// changes or of AQ messages available to dequeue.
//---------------------------------------------------------------------------
async subscribe(name, options) {
nodbUtil.checkArgCount(arguments, 2, 2);
nodbUtil.assert(typeof name === 'string', 'NJS-005', 1);
nodbUtil.assert(nodbUtil.isObject(options), 'NJS-005', 2);
errors.assertArgCount(arguments, 2, 2);
errors.assertParamValue(typeof name === 'string', 1);
errors.assertParamValue(nodbUtil.isObject(options), 2);
await this._subscribe(name, options);
}
@ -440,19 +436,19 @@ class Connection extends EventEmitter {
// Starts a two-phase-commit transaction.
//--------------------------------------------------------------------------
async tpcBegin(xid, flag, timeout) {
nodbUtil.checkArgCount(arguments, 1, 3);
nodbUtil.assert(nodbUtil.isXid(xid), 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 3);
errors.assertParamValue(nodbUtil.isXid(xid), 1);
if (arguments.length < 3) {
timeout = 60; // seconds
} else {
nodbUtil.assert(typeof timeout === 'number', 'NJS-005', 3);
errors.assertParamValue(typeof timeout === 'number', 3);
}
if (arguments.length < 2) {
flag = constants.TPC_BEGIN_NEW;
} else {
nodbUtil.assert(typeof flag === 'number', 'NJS-005', 2);
errors.assertParamValue(typeof flag === 'number', 2);
}
await this._tpcBegin(xid, flag, timeout);
}
@ -463,15 +459,15 @@ class Connection extends EventEmitter {
// Commits a two-phase-commit transaction.
//---------------------------------------------------------------------------
async tpcCommit(xid, onePhase) {
nodbUtil.checkArgCount(arguments, 0, 2);
errors.assertArgCount(arguments, 0, 2);
if (arguments.length < 2) {
onePhase = false;
} else {
nodbUtil.assert(typeof onePhase === 'boolean', 'NJS-005', 2);
errors.assertParamValue(typeof onePhase === 'boolean', 2);
}
if (arguments.length >= 1) {
nodbUtil.assert(nodbUtil.isXid(xid), 'NJS-005', 1);
errors.assertParamValue(nodbUtil.isXid(xid), 1);
}
await this._tpcCommit(xid, onePhase);
}
@ -482,16 +478,16 @@ class Connection extends EventEmitter {
// Ends a two-phase-commit transaction.
//---------------------------------------------------------------------------
async tpcEnd(xid, flag) {
nodbUtil.checkArgCount(arguments, 0, 2);
errors.assertArgCount(arguments, 0, 2);
if (arguments.length < 2) {
flag = constants.TPC_END_NORMAL;
} else {
nodbUtil.assert(typeof flag === 'number', 'NJS-005', 2);
errors.assertParamValue(typeof flag === 'number', 2);
}
if (arguments.length >= 1) {
nodbUtil.assert(nodbUtil.isXid(xid), 'NJS-005', 1);
errors.assertParamValue(nodbUtil.isXid(xid), 1);
}
await this._tpcEnd(xid, flag);
@ -504,8 +500,8 @@ class Connection extends EventEmitter {
// transaction.
// ---------------------------------------------------------------------------
async tpcForget(xid) {
nodbUtil.checkArgCount(arguments, 1, 1);
nodbUtil.assert(nodbUtil.isXid(xid), 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 1);
errors.assertParamValue(nodbUtil.isXid(xid), 1);
await this._tpcForget(xid);
}
@ -516,9 +512,9 @@ class Connection extends EventEmitter {
// Prepares a two-phase-commit transaction for commit.
//---------------------------------------------------------------------------
async tpcPrepare(xid) {
nodbUtil.checkArgCount(arguments, 0, 1);
errors.assertArgCount(arguments, 0, 1);
if (arguments.length >= 1) {
nodbUtil.assert(nodbUtil.isXid(xid), 'NJS-005', 1);
errors.assertParamValue(nodbUtil.isXid(xid), 1);
}
return await this._tpcPrepare(xid);
@ -530,10 +526,10 @@ class Connection extends EventEmitter {
// Returns a list of pending two-phase-commit transactions.
//---------------------------------------------------------------------------
async tpcRecover(asString) {
nodbUtil.checkArgCount(arguments, 0, 1);
errors.assertArgCount(arguments, 0, 1);
if (arguments.length == 1) {
nodbUtil.assert(typeof asString === 'boolean', 'NJS-005', 1);
errors.assertParamValue(typeof asString === 'boolean', 1);
} else {
asString = true;
}
@ -564,9 +560,9 @@ class Connection extends EventEmitter {
// Rolls back the current changes in a two-phase-commit transaction.
//---------------------------------------------------------------------------
async tpcRollback(xid) {
nodbUtil.checkArgCount(arguments, 0, 1);
errors.assertArgCount(arguments, 0, 1);
if (arguments.length == 1) {
nodbUtil.assert(nodbUtil.isXid(xid), 'NJS-005', 1);
errors.assertParamValue(nodbUtil.isXid(xid), 1);
}
await this._tpcRollback(xid);
@ -578,8 +574,8 @@ class Connection extends EventEmitter {
// Destroy a subscription which was earlier created using subscribe().
//---------------------------------------------------------------------------
async unsubscribe(name) {
nodbUtil.checkArgCount(arguments, 1, 1);
nodbUtil.assert(typeof name === 'string', 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 1);
errors.assertParamValue(typeof name === 'string', 1);
await this._unsubscribe(name);
}

385
lib/errors.js Normal file
View File

@ -0,0 +1,385 @@
// Copyright (c) 2022, Oracle and/or its affiliates.
//-----------------------------------------------------------------------------
//
// You may not use the identified files except in compliance with the Apache
// License, Version 2.0 (the "License.")
//
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0.
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
//-----------------------------------------------------------------------------
'use strict';
const util = require('util');
// define error prefix for all messages
const ERR_PREFIX = "NJS";
// define error number constants (used in JavaScript library)
const ERR_MISSING_CALLBACK = 1;
const ERR_INVALID_POOL = 2;
const ERR_INVALID_CONNECTION = 3;
const ERR_INVALID_PROPERTY_VALUE = 4;
const ERR_INVALID_PARAMETER_VALUE = 5;
const ERR_INVALID_PROPERTY_VALUE_IN_PARAM = 7;
const ERR_INVALID_NUMBER_OF_PARAMETERS = 9;
const ERR_UNSUPPORTED_DATA_TYPE = 10;
const ERR_BIND_VALUE_AND_TYPE_MISMATCH = 11;
const ERR_INVALID_BIND_DATA_TYPE = 12;
const ERR_INVALID_BIND_DIRECTION = 13;
const ERR_NO_TYPE_FOR_CONVERSION = 15;
const ERR_INSUFFICENT_BUFFER_FOR_BINDS = 16;
const ERR_BUSY_RS = 17;
const ERR_INVALID_RS = 18;
const ERR_NOT_A_QUERY = 19;
const ERR_INVALID_TYPE_FOR_CONVERSION = 21;
const ERR_INVALID_LOB = 22;
const ERR_BUSY_LOB = 23;
const ERR_INSUFFICIENT_MEMORY = 24;
const ERR_INVALID_TYPE_FOR_ARRAY_BIND = 34;
const ERR_REQUIRED_MAX_ARRAY_SIZE = 35;
const ERR_INVALID_ARRAY_SIZE = 36;
const ERR_INCOMPATIBLE_TYPE_ARRAY_BIND = 37;
const ERR_CONN_REQUEST_TIMEOUT = 40;
const ERR_CANNOT_CONVERT_RS_TO_STREAM = 41;
const ERR_CANNOT_INVOKE_RS_METHODS = 42;
const ERR_RS_ALREADY_CONVERTED = 43;
const ERR_INVALID_BIND_UNIT = 44;
const ERR_CANNOT_LOAD_BINARY = 45;
const ERR_POOL_WITH_ALIAS_ALREADY_EXISTS = 46;
const ERR_POOL_WITH_ALIAS_NOT_FOUND = 47;
const ERR_INCOMPATIBLE_TYPE_ARRAY_INDEX_BIND = 52;
const ERR_NON_ARRAY_PROVIDED = 53;
const ERR_MIXED_BIND = 55;
const ERR_MISSING_MAX_SIZE_BY_POS = 56;
const ERR_MISSING_MAX_SIZE_BY_NAME = 57;
const ERR_MAX_SIZE_TOO_SMALL = 58;
const ERR_MISSING_TYPE_BY_POS = 59;
const ERR_MISSING_TYPE_BY_NAME = 60;
const ERR_INVALID_SUBSCR = 61;
const ERR_MISSING_SUBSCR_CALLBACK = 62;
const ERR_MISSING_SUBSCR_SQL = 63;
const ERR_POOL_CLOSING = 64;
const ERR_POOL_CLOSED = 65;
const ERR_INVALID_SODA_DOC_CURSOR = 66;
const ERR_NO_BINARY_AVAILABLE = 67;
const ERR_INVALID_ERR_NUM = 68;
const ERR_NODE_TOO_OLD = 69;
const ERR_INVALID_AQ_MESSAGE = 70;
const ERR_CONVERT_FROM_OBJ_ELEMENT = 71;
const ERR_CONVERT_FROM_OBJ_ATTR = 72;
const ERR_CONVERT_TO_OBJ_ELEMENT = 73;
const ERR_CONVERT_TO_OBJ_ATTR = 74;
const ERR_DBL_CONNECT_STRING = 75;
const ERR_QUEUE_MAX_EXCEEDED = 76;
const ERR_CLIENT_LIB_ALREADY_INITIALIZED = 77;
const ERR_UNSUPPORTED_DATA_TYPE_IN_JSON = 78;
const ERR_CONVERT_TO_JSON_VALUE = 79;
const ERR_DBL_USER = 80;
const ERR_CONCURRENT_OPS = 81;
const ERR_POOL_RECONFIGURING = 82;
const ERR_POOL_STATISTICS_DISABLED = 83;
const ERR_TOKEN_BASED_AUTH = 84;
const ERR_POOL_TOKEN_BASED_AUTH = 85;
const ERR_CONN_TOKEN_BASED_AUTH = 86;
const ERR_TOKEN_HAS_EXPIRED = 87;
const ERR_TOKEN_CALLBACK_DUP = 88;
const messages = new Map();
messages.set(ERR_INVALID_CONNECTION,
'invalid connection');
messages.set(ERR_INVALID_POOL,
'invalid pool');
messages.set(ERR_INVALID_PROPERTY_VALUE,
'invalid value for property %s');
messages.set(ERR_MISSING_CALLBACK,
'expected callback as last parameter');
messages.set(ERR_INVALID_PARAMETER_VALUE,
'invalid value for parameter %d');
messages.set(ERR_INVALID_PROPERTY_VALUE_IN_PARAM,
'invalid value for "%s" in parameter %d');
messages.set(ERR_INVALID_NUMBER_OF_PARAMETERS,
'invalid number of parameters');
messages.set(ERR_UNSUPPORTED_DATA_TYPE,
'unsupported data type %d in column %d');
messages.set(ERR_BIND_VALUE_AND_TYPE_MISMATCH,
'encountered bind value and type mismatch');
messages.set(ERR_INVALID_BIND_DATA_TYPE,
'encountered invalid bind data type in parameter %d');
messages.set(ERR_INVALID_BIND_DIRECTION,
'invalid bind direction');
messages.set(ERR_NO_TYPE_FOR_CONVERSION,
'type was not specified for conversion');
messages.set(ERR_INSUFFICENT_BUFFER_FOR_BINDS,
'buffer is too small for OUT binds');
messages.set(ERR_BUSY_RS,
'concurrent operations on ResultSet are not allowed');
messages.set(ERR_INVALID_RS,
'invalid ResultSet');
messages.set(ERR_NOT_A_QUERY,
'ResultSet cannot be returned for non-query statements');
messages.set(ERR_INVALID_TYPE_FOR_CONVERSION,
'invalid type for conversion specified');
messages.set(ERR_INVALID_LOB,
'invalid Lob');
messages.set(ERR_BUSY_LOB,
'concurrent operations on LOB are not allowed');
messages.set(ERR_INSUFFICIENT_MEMORY,
'memory allocation failed');
messages.set(ERR_INVALID_TYPE_FOR_ARRAY_BIND,
'data type is unsupported for array bind');
messages.set(ERR_REQUIRED_MAX_ARRAY_SIZE,
'maxArraySize is required for IN OUT array bind');
messages.set(ERR_INVALID_ARRAY_SIZE,
'given array is of size greater than maxArraySize');
messages.set(ERR_INCOMPATIBLE_TYPE_ARRAY_BIND,
'invalid data type at array index %d for bind ":%"');
messages.set(ERR_CONN_REQUEST_TIMEOUT,
'connection request timeout. Request exceeded queueTimeout of %d');
messages.set(ERR_CANNOT_CONVERT_RS_TO_STREAM,
'cannot convert ResultSet to QueryStream after invoking methods');
messages.set(ERR_CANNOT_INVOKE_RS_METHODS,
'cannot invoke ResultSet methods after converting to QueryStream');
messages.set(ERR_RS_ALREADY_CONVERTED,
'ResultSet already converted to QueryStream');
messages.set(ERR_INVALID_BIND_UNIT,
'bind object must contain one of the following keys: ' +
'"dir", "type", "maxSize", or "val"');
messages.set(ERR_CANNOT_LOAD_BINARY,
'cannot load a node-oracledb binary for Node.js %s');
messages.set(ERR_POOL_WITH_ALIAS_ALREADY_EXISTS,
'pool alias "%s" already exists in the connection pool cache');
messages.set(ERR_POOL_WITH_ALIAS_NOT_FOUND,
'pool alias "%s" not found in connection pool cache');
messages.set(ERR_INCOMPATIBLE_TYPE_ARRAY_INDEX_BIND,
'invalid data type at array index %d for bind position %d');
messages.set(ERR_NON_ARRAY_PROVIDED,
'an array value was expected');
messages.set(ERR_MIXED_BIND,
'binding by position and name cannot be mixed');
messages.set(ERR_MISSING_MAX_SIZE_BY_POS,
'maxSize must be specified and not zero for bind position %d');
messages.set(ERR_MISSING_MAX_SIZE_BY_NAME,
'maxSize must be specified and not zero for bind "%s"');
messages.set(ERR_MAX_SIZE_TOO_SMALL,
'maxSize of %d is too small for value of length %d in row %d');
messages.set(ERR_MISSING_TYPE_BY_POS,
'type must be specified for bind position %d');
messages.set(ERR_MISSING_TYPE_BY_NAME,
'type must be specified for bind "%s"');
messages.set(ERR_INVALID_SUBSCR,
'invalid subscription');
messages.set(ERR_MISSING_SUBSCR_CALLBACK,
'subscription notification callback missing');
messages.set(ERR_MISSING_SUBSCR_SQL,
'subscription notification SQL missing');
messages.set(ERR_POOL_CLOSING,
'connection pool is closing');
messages.set(ERR_POOL_CLOSED,
'connection pool was closed');
messages.set(ERR_INVALID_SODA_DOC_CURSOR,
'invalid SODA document cursor');
messages.set(ERR_NO_BINARY_AVAILABLE,
'a pre-built node-oracledb binary was not found for %s');
messages.set(ERR_INVALID_ERR_NUM,
'invalid error number %d supplied');
messages.set(ERR_NODE_TOO_OLD,
'node-oracledb %s requires Node.js %s or later');
messages.set(ERR_INVALID_AQ_MESSAGE,
'message must be a string, buffer, database object or an object ' +
'containing a payload property which itself is a string, buffer or ' +
'database object');
messages.set(ERR_CONVERT_FROM_OBJ_ELEMENT,
'cannot convert from element of type "%s" to JavaScript value');
messages.set(ERR_CONVERT_FROM_OBJ_ATTR,
'cannot convert from attribute "%s" of type "%s" to JavaScript value');
messages.set(ERR_CONVERT_TO_OBJ_ELEMENT,
'cannot convert from JavaScript value to element of type %s');
messages.set(ERR_CONVERT_TO_OBJ_ATTR,
'cannot convert from JavaScript value to attribute "%s" of type "%s"');
messages.set(ERR_DBL_CONNECT_STRING,
'only one of connectString and connectionString can be used');
messages.set(ERR_QUEUE_MAX_EXCEEDED,
'connection request rejected. Pool queue length queueMax %d reached');
messages.set(ERR_CLIENT_LIB_ALREADY_INITIALIZED,
'Oracle Client library has already been initialized');
messages.set(ERR_UNSUPPORTED_DATA_TYPE_IN_JSON,
'unsupported data type %d in JSON value');
messages.set(ERR_CONVERT_TO_JSON_VALUE,
'cannot convert from JavaScript value to JSON value');
messages.set(ERR_DBL_USER,
'only one of user and username can be used');
messages.set(ERR_CONCURRENT_OPS,
'concurrent operations on a connection are disabled');
messages.set(ERR_POOL_RECONFIGURING,
'connection pool is being reconfigured');
messages.set(ERR_POOL_STATISTICS_DISABLED,
'pool statistics not enabled');
messages.set(ERR_TOKEN_BASED_AUTH,
'invalid or missing parameter with token based authentication. ' +
'The token and privateKey attributes must contain values. ' +
'Other credentials cannot be specified');
messages.set(ERR_POOL_TOKEN_BASED_AUTH,
'invalid connection pool configuration with token based authentication. ' +
'The homogeneous and externalAuth attributes must be set to true');
messages.set(ERR_CONN_TOKEN_BASED_AUTH,
'invalid standalone configuration with token based authentication. ' +
'The externalAuth attribute must be set to true');
messages.set(ERR_TOKEN_HAS_EXPIRED,
'access token has expired');
messages.set(ERR_TOKEN_CALLBACK_DUP,
'accessTokenCallback cannot be specified when accessToken is a function');
//-----------------------------------------------------------------------------
// assert()
//
// Checks the condition, and if the condition is not true, throws an exception
// using the specified error number and arguments.
//-----------------------------------------------------------------------------
function assert(condition) {
if (!condition) {
const args = Array.prototype.slice.call(arguments, 1);
throwErr(...args);
}
}
//-----------------------------------------------------------------------------
// assertArgCount()
//
// Asserts that the argument count falls between the minimum and maximum number
// of arguments.
//-----------------------------------------------------------------------------
function assertArgCount(args, minArgCount, maxArgCount) {
assert(args.length >= minArgCount && args.length <= maxArgCount,
ERR_INVALID_NUMBER_OF_PARAMETERS);
}
//-----------------------------------------------------------------------------
// assertParamPropValue()
//
// Asserts that the property value of a parmeter passes the specified
// condition.
//-----------------------------------------------------------------------------
function assertParamPropValue(condition, parameterNum, propName) {
assert(condition, ERR_INVALID_PROPERTY_VALUE_IN_PARAM, propName,
parameterNum);
}
//-----------------------------------------------------------------------------
// assertParamValue()
//
// Asserts that the parmeter value passes the specified condition.
//-----------------------------------------------------------------------------
function assertParamValue(condition, parameterNum) {
assert(condition, ERR_INVALID_PARAMETER_VALUE, parameterNum);
}
//-----------------------------------------------------------------------------
// assertPropValue()
//
// Asserts that the property value passes the specified condition.
//-----------------------------------------------------------------------------
function assertPropValue(condition, propName) {
assert(condition, ERR_INVALID_PROPERTY_VALUE, propName);
}
//-----------------------------------------------------------------------------
// throwErr()
//
// Throws an error with the given error number after formatting it with the
// given arguments.
//-----------------------------------------------------------------------------
function throwErr(errorNum) {
let baseText = messages.get(errorNum);
if (!baseText)
baseText = messages.get(ERR_INVALID_ERR_NUM);
const errorNumStr = errorNum.toString().padStart(3, '0');
const args = [...arguments];
args[0] = `${ERR_PREFIX}-${errorNumStr}: ${baseText}`;
throw new Error(util.format(...args));
}
// define exports
module.exports = {
ERR_MISSING_CALLBACK,
ERR_INVALID_POOL,
ERR_INVALID_CONNECTION,
ERR_INVALID_PROPERTY_VALUE,
ERR_INVALID_PARAMETER_VALUE,
ERR_INVALID_PROPERTY_VALUE_IN_PARAM,
ERR_INVALID_NUMBER_OF_PARAMETERS,
ERR_UNSUPPORTED_DATA_TYPE,
ERR_BIND_VALUE_AND_TYPE_MISMATCH,
ERR_INVALID_BIND_DATA_TYPE,
ERR_INVALID_BIND_DIRECTION,
ERR_NO_TYPE_FOR_CONVERSION,
ERR_INSUFFICENT_BUFFER_FOR_BINDS,
ERR_BUSY_RS,
ERR_INVALID_RS,
ERR_NOT_A_QUERY,
ERR_INVALID_TYPE_FOR_CONVERSION,
ERR_INVALID_LOB,
ERR_BUSY_LOB,
ERR_INSUFFICIENT_MEMORY,
ERR_INVALID_TYPE_FOR_ARRAY_BIND,
ERR_REQUIRED_MAX_ARRAY_SIZE,
ERR_INVALID_ARRAY_SIZE,
ERR_INCOMPATIBLE_TYPE_ARRAY_BIND,
ERR_CONN_REQUEST_TIMEOUT,
ERR_CANNOT_CONVERT_RS_TO_STREAM,
ERR_CANNOT_INVOKE_RS_METHODS,
ERR_RS_ALREADY_CONVERTED,
ERR_INVALID_BIND_UNIT,
ERR_CANNOT_LOAD_BINARY,
ERR_POOL_WITH_ALIAS_ALREADY_EXISTS,
ERR_POOL_WITH_ALIAS_NOT_FOUND,
ERR_INCOMPATIBLE_TYPE_ARRAY_INDEX_BIND,
ERR_NON_ARRAY_PROVIDED,
ERR_MIXED_BIND,
ERR_MISSING_MAX_SIZE_BY_POS,
ERR_MISSING_MAX_SIZE_BY_NAME,
ERR_MAX_SIZE_TOO_SMALL,
ERR_MISSING_TYPE_BY_POS,
ERR_MISSING_TYPE_BY_NAME,
ERR_INVALID_SUBSCR,
ERR_MISSING_SUBSCR_CALLBACK,
ERR_MISSING_SUBSCR_SQL,
ERR_POOL_CLOSING,
ERR_POOL_CLOSED,
ERR_INVALID_SODA_DOC_CURSOR,
ERR_NO_BINARY_AVAILABLE,
ERR_INVALID_ERR_NUM,
ERR_NODE_TOO_OLD,
ERR_INVALID_AQ_MESSAGE,
ERR_CONVERT_FROM_OBJ_ELEMENT,
ERR_CONVERT_FROM_OBJ_ATTR,
ERR_CONVERT_TO_OBJ_ELEMENT,
ERR_CONVERT_TO_OBJ_ATTR,
ERR_DBL_CONNECT_STRING,
ERR_QUEUE_MAX_EXCEEDED,
ERR_CLIENT_LIB_ALREADY_INITIALIZED,
ERR_UNSUPPORTED_DATA_TYPE_IN_JSON,
ERR_CONVERT_TO_JSON_VALUE,
ERR_DBL_USER,
ERR_CONCURRENT_OPS,
ERR_POOL_RECONFIGURING,
ERR_POOL_STATISTICS_DISABLED,
ERR_TOKEN_BASED_AUTH,
ERR_POOL_TOKEN_BASED_AUTH,
ERR_CONN_TOKEN_BASED_AUTH,
assert,
assertArgCount,
assertParamPropValue,
assertParamValue,
assertPropValue,
throwErr
};

View File

@ -22,6 +22,7 @@
const { Duplex } = require('stream');
const Connection = require('./connection.js');
const constants = require('./constants.js');
const errors = require('./errors.js');
const nodbUtil = require('./util.js');
class Lob extends Duplex {
@ -119,7 +120,7 @@ class Lob extends Duplex {
// versions of node-oracledb.
//---------------------------------------------------------------------------
async close() {
nodbUtil.checkArgCount(arguments, 0, 0);
errors.assertArgCount(arguments, 0, 0);
if (this.valid) {
try {
await this._close();
@ -135,7 +136,7 @@ class Lob extends Duplex {
// Returns all of the data in the LOB as a single string or buffer.
//---------------------------------------------------------------------------
async getData() {
nodbUtil.checkArgCount(arguments, 0, 0);
errors.assertArgCount(arguments, 0, 0);
return await this._getData();
}
@ -151,7 +152,7 @@ class Lob extends Duplex {
}
nodbUtil.wrap_fns(Lob.prototype, "NJS-023",
nodbUtil.wrap_fns(Lob.prototype, errors.ERR_BUSY_LOB,
"close",
"getData");
Lob.prototype._serializedRead = nodbUtil.serialize(Lob.prototype.readData);

View File

@ -21,15 +21,15 @@
const constants = require('./constants.js');
const nodbUtil = require('./util.js');
const errors = require('./errors.js');
const util = require('util');
// This version of node-oracledb works with Node.js 14 or later. The test
// stops hard-to-interpret runtime errors and crashes with older Node.js
// versions.
let vs = process.version.substring(1).split(".").map(Number);
if (vs[0] < 14) {
throw new Error(nodbUtil.getErrorMessage('NJS-069', nodbUtil.PACKAGE_JSON_VERSION, "14.0"));
}
errors.assert(vs[0] >= 14, errors.ERR_NODE_TOO_OLD,
nodbUtil.PACKAGE_JSON_VERSION, "14.0");
const AqDeqOptions = require('./aqDeqOptions.js');
const AqEnqOptions = require('./aqEnqOptions.js');
@ -86,7 +86,7 @@ for (let i = 0; i < binaryLocations.length; i++) {
} else {
nodeInfo = `\n Node.js require('oracledb') error was:\n ${err.message}\n ${nodbUtil.getInstallHelp()}\n`;
}
throw new Error(nodbUtil.getErrorMessage('NJS-045', nodeInfo));
errors.throwErr(errors.ERR_CANNOT_LOAD_BINARY, nodeInfo);
}
}
}
@ -101,14 +101,11 @@ async function createPool(poolAttrs) {
let poolAlias;
// check arguments
nodbUtil.checkArgCount(arguments, 1, 1);
nodbUtil.assert(nodbUtil.isObject(poolAttrs), 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 1);
errors.assertParamValue(nodbUtil.isObject(poolAttrs), 1);
if (poolAttrs.poolAlias !== undefined) {
if (typeof poolAttrs.poolAlias !== 'string' ||
poolAttrs.poolAlias.length === 0) {
throw new Error(nodbUtil.getErrorMessage('NJS-004',
'poolAttrs.poolAlias'));
}
errors.assertParamPropValue(typeof poolAttrs.poolAlias === 'string' &&
poolAttrs.poolAlias.length !== 0, 1, "poolAlias");
poolAlias = poolAttrs.poolAlias;
} else if (poolAttrs.poolAlias === undefined
&& !poolCache[defaultPoolAlias]
@ -116,20 +113,20 @@ async function createPool(poolAttrs) {
poolAlias = defaultPoolAlias;
}
if (poolCache[poolAlias] || tempUsedPoolAliases[poolAlias]) {
throw new Error(nodbUtil.getErrorMessage('NJS-046', poolAlias));
errors.throwErr(errors.ERR_POOL_WITH_ALIAS_ALREADY_EXISTS, poolAlias);
}
if (poolAttrs.accessToken !== undefined) {
// cannot set username or password for token based authentication
if (poolAttrs.user !== undefined ||
poolAttrs.password !== undefined) {
throw new Error(nodbUtil.getErrorMessage('NJS-084'));
errors.throwErr(errors.ERR_TOKEN_BASED_AUTH);
}
// homogeneous and externalAuth must be set to true for token based
// authentication
if (poolAttrs.homogeneous === false ||
poolAttrs.externalAuth === false) {
throw new Error(nodbUtil.getErrorMessage('NJS-085'));
errors.throwErr(errors.ERR_POOL_TOKEN_BASED_AUTH);
}
}
@ -152,12 +149,10 @@ async function createPool(poolAttrs) {
// token based authentication
if (poolAttrs.accessToken !== undefined) {
// accessTokenCallback is depricated from node-oracledb 5.5
if (poolAttrs.accessTokenCallback !== undefined &&
typeof poolAttrs.accessToken === 'function') {
throw new Error(nodbUtil.getErrorMessage('NJS-088'));
errors.throwErr(errors.ERR_TOKEN_CALLBACK_DUP);
}
await nodbUtil.checkToken(adjustedPoolAttrs);
if (typeof poolAttrs.accessToken === 'function') {
adjustedPoolAttrs.accessTokenCallback = poolAttrs.accessToken;
@ -212,12 +207,11 @@ async function getConnection(a1) {
let connAttrs = {};
// verify the number and types of arguments
nodbUtil.checkArgCount(arguments, 0, 1);
errors.assertArgCount(arguments, 0, 1);
if (arguments.length == 0) {
poolAlias = defaultPoolAlias;
} else {
nodbUtil.assert(typeof a1 === 'string' || nodbUtil.isObject(a1),
'NJS-005', 1);
errors.assertParamValue(typeof a1 === 'string' || nodbUtil.isObject(a1), 1);
if (typeof a1 === 'string') {
poolAlias = a1;
} else {
@ -232,7 +226,7 @@ async function getConnection(a1) {
if (poolAlias) {
pool = poolCache[poolAlias];
if (!pool) {
throw new Error(nodbUtil.getErrorMessage('NJS-047', poolAlias));
errors.throwErr(errors.ERR_POOL_WITH_ALIAS_NOT_FOUND, poolAlias);
}
return await pool.getConnection(connAttrs);
@ -242,12 +236,12 @@ async function getConnection(a1) {
// cannot set username or password for token based authentication
if (connAttrs.user !== undefined ||
connAttrs.password !== undefined) {
throw new Error(nodbUtil.getErrorMessage('NJS-084'));
errors.throwErr(errors.ERR_TOKEN_BASED_AUTH);
}
// externalAuth must be set to true for token based authentication
if (connAttrs.externalAuth === false) {
throw new Error(nodbUtil.getErrorMessage('NJS-086'));
errors.throwErr(errors.ERR_CONN_TOKEN_BASED_AUTH);
}
await nodbUtil.checkToken(connAttrs);
@ -271,10 +265,11 @@ async function getConnection(a1) {
function getPool(poolAlias) {
let pool;
nodbUtil.checkArgCount(arguments, 0, 1);
errors.assertArgCount(arguments, 0, 1);
if (poolAlias) {
nodbUtil.assert(typeof poolAlias === 'string' || typeof poolAlias === 'number', 'NJS-005', 1);
errors.assertParamValue(typeof poolAlias === 'string' ||
typeof poolAlias === 'number', 1);
}
poolAlias = poolAlias || defaultPoolAlias;
@ -282,7 +277,7 @@ function getPool(poolAlias) {
pool = poolCache[poolAlias];
if (!pool) {
throw new Error(nodbUtil.getErrorMessage('NJS-047', poolAlias));
errors.throwErr(errors.ERR_POOL_WITH_ALIAS_NOT_FOUND, poolAlias);
}
return pool;
@ -295,9 +290,9 @@ function getPool(poolAlias) {
//-----------------------------------------------------------------------------
function initOracleClient(arg1) {
let options = {};
nodbUtil.checkArgCount(arguments, 0, 1);
errors.assertArgCount(arguments, 0, 1);
if (arg1 !== undefined) {
nodbUtil.assert(nodbUtil.isObject(arg1), 'NJS-005', 1);
errors.assertParamValue(nodbUtil.isObject(arg1), 1);
options = arg1;
}
if (_initOracleClientArgs === undefined) {
@ -332,14 +327,14 @@ async function shutdown(a1, a2) {
let shutdownMode = constants.SHUTDOWN_MODE_DEFAULT;
// verify the number and types of arguments
nodbUtil.checkArgCount(arguments, 0, 2);
errors.assertArgCount(arguments, 0, 2);
if (arguments.length == 2) {
nodbUtil.assert(typeof a1 === 'object', 'NJS-005', 1);
nodbUtil.assert(typeof a2 === 'number', 'NJS-005', 2);
errors.assertParamValue(typeof a1 === 'object', 1);
errors.assertParamValue(typeof a2 === 'number', 2);
connAttr = a1;
shutdownMode = a2;
} else if (arguments.length == 1) {
nodbUtil.assert(typeof a1 === 'object', 'NJS-005', 1);
errors.assertParamValue(typeof a1 === 'object', 1);
connAttr = a1;
}
@ -375,14 +370,14 @@ async function startup(a1, a2) {
let startupAttr = {};
// verify the number and types of arguments
nodbUtil.checkArgCount(arguments, 0, 2);
errors.assertArgCount(arguments, 0, 2);
if (arguments.length == 2) {
nodbUtil.assert (typeof a1 === 'object', 'NJS-005', 1);
nodbUtil.assert (typeof a2 === 'object', 'NJS-005', 2);
errors.assertParamValue(typeof a1 === 'object', 1);
errors.assertParamValue(typeof a2 === 'object', 2);
connAttr = a1;
startupAttr = a2;
} else if (arguments.length == 1) {
nodbUtil.assert(typeof a1 === 'object', 'NJS-005', 1);
errors.assertParamValue(typeof a1 === 'object', 1);
connAttr = a1;
}
@ -731,140 +726,133 @@ module.exports = {
// property setters
set autoCommit(value) {
nodbUtil.assert(typeof value === 'boolean', 'NJS-004', "autoCommit");
errors.assertPropValue(typeof value === 'boolean', "autoCommit");
settings.autoCommit = value;
},
set connectionClass(value) {
nodbUtil.assert(typeof value === 'string', 'NJS-004', "connectionClass");
errors.assertPropValue(typeof value === 'string', "connectionClass");
settings.connectionClass = value;
},
set dbObjectAsPojo(value) {
nodbUtil.assert(typeof value === 'boolean', 'NJS-004', "dbObjectAsPojo");
errors.assertPropValue(typeof value === 'boolean', "dbObjectAsPojo");
settings.dbObjectAsPojo = value;
},
set edition(value) {
nodbUtil.assert(typeof value === 'string', 'NJS-004', "edition");
errors.assertPropValue(typeof value === 'string', "edition");
settings.edition = value;
},
set errorOnConcurrentExecute(value) {
nodbUtil.assert(typeof value === 'boolean', 'NJS-004',
errors.assertPropValue(typeof value === 'boolean',
"errorOnConcurrentExecute");
settings.errorOnConcurrentExecute = value;
},
set events(value) {
nodbUtil.assert(typeof value === 'boolean', 'NJS-004', "events");
errors.assertPropValue(typeof value === 'boolean', "events");
settings.events = value;
},
set externalAuth(value) {
nodbUtil.assert(typeof value === 'boolean', 'NJS-004', "externalAuth");
errors.assertPropValue(typeof value === 'boolean', "externalAuth");
settings.externalAuth = value;
},
set fetchArraySize(value) {
nodbUtil.assert(Number.isInteger(value) && value > 0, 'NJS-004',
errors.assertPropValue(Number.isInteger(value) && value > 0,
"fetchArraySize");
settings.fetchArraySize = value;
},
set fetchAsBuffer(value) {
nodbUtil.assert(Array.isArray(value), 'NJS-004', "fetchAsBuffer");
errors.assertPropValue(Array.isArray(value), "fetchAsBuffer");
for (const element of value) {
nodbUtil.assert(Number.isInteger(element) && element > 0, 'NJS-004',
"fetchAsBuffer");
if (element !== constants.DB_TYPE_BLOB) {
throw new Error(nodbUtil.getErrorMessage('NJS-021'));
errors.throwErr(errors.ERR_INVALID_TYPE_FOR_CONVERSION);
}
}
settings.fetchAsBuffer = value;
},
set fetchAsString(value) {
nodbUtil.assert(Array.isArray(value), 'NJS-004', "fetchAsString");
errors.assertPropValue(Array.isArray(value), "fetchAsString");
for (const element of value) {
nodbUtil.assert(Number.isInteger(element) && element > 0, 'NJS-004',
"fetchAsString");
if (element != constants.DB_TYPE_NUMBER &&
element != constants.DB_TYPE_TIMESTAMP_LTZ &&
element != constants.DB_TYPE_RAW &&
element != constants.DB_TYPE_CLOB &&
element != constants.DB_TYPE_NCLOB &&
element != constants.DB_TYPE_JSON) {
throw new Error(nodbUtil.getErrorMessage('NJS-021'));
errors.throwErr(errors.ERR_INVALID_TYPE_FOR_CONVERSION);
}
}
settings.fetchAsString = value;
},
set lobPrefetchSize(value) {
nodbUtil.assert(Number.isInteger(value) && value >= 0, 'NJS-004',
errors.assertPropValue(Number.isInteger(value) && value >= 0,
"lobPrefetchSize");
settings.lobPrefetchSize = value;
},
set maxRows(value) {
nodbUtil.assert(Number.isInteger(value) && value >= 0, 'NJS-004',
"maxRows");
errors.assertPropValue(Number.isInteger(value) && value >= 0, "maxRows");
settings.maxRows = value;
},
set outFormat(value) {
if (value !== constants.OUT_FORMAT_ARRAY &&
value !== constants.OUT_FORMAT_OBJECT) {
throw new Error(nodbUtil.getErrorMessage('NJS-004', "outFormat"));
errors.throwErr(errors.ERR_INVALID_PROPERTY_VALUE, "outFormat");
}
settings.outFormat = value;
},
set poolIncrement(value) {
nodbUtil.assert(Number.isInteger(value) && value >= 0, 'NJS-004',
errors.assertPropValue(Number.isInteger(value) && value >= 0,
"poolIncrement");
settings.poolIncrement = value;
},
set poolMax(value) {
nodbUtil.assert(Number.isInteger(value) && value >= 0, 'NJS-004',
"poolMax");
errors.assertPropValue(Number.isInteger(value) && value >= 0, "poolMax");
settings.poolMax = value;
},
set poolMaxPerShard(value) {
nodbUtil.assert(Number.isInteger(value) && value >= 0, 'NJS-004',
errors.assertPropValue(Number.isInteger(value) && value >= 0,
"poolMaxPerShard");
settings.poolMaxPerShard = value;
},
set poolMin(value) {
nodbUtil.assert(Number.isInteger(value) && value >= 0, 'NJS-004',
"poolMin");
errors.assertPropValue(Number.isInteger(value) && value >= 0, "poolMin");
settings.poolMin = value;
},
set poolPingInterval(value) {
nodbUtil.assert(Number.isInteger(value) && value < 2 ** 31 &&
value >= (-2) ** 31, 'NJS-004', "poolPingInterval");
errors.assertPropValue(Number.isInteger(value) && value < 2 ** 31 &&
value >= (-2) ** 31, "poolPingInterval");
settings.poolPingInterval = value;
},
set poolTimeout(value) {
nodbUtil.assert(Number.isInteger(value) && value >= 0, 'NJS-004',
errors.assertPropValue(Number.isInteger(value) && value >= 0,
"poolTimeout");
settings.poolTimeout = value;
},
set prefetchRows(value) {
nodbUtil.assert(Number.isInteger(value) && value >= 0, 'NJS-004',
errors.assertPropValue(Number.isInteger(value) && value >= 0,
"prefetchRows");
settings.prefetchRows = value;
},
set stmtCacheSize(value) {
nodbUtil.assert(Number.isInteger(value) && value >= 0, 'NJS-004',
errors.assertPropValue(Number.isInteger(value) && value >= 0,
"stmtCacheSize");
settings.stmtCacheSize = value;
},

View File

@ -21,6 +21,7 @@
const EventEmitter = require('events');
const constants = require('./constants.js');
const errors = require('./errors.js');
const settings = require('./settings.js');
const nodbUtil = require('./util.js');
const PoolStatistics = require('./poolStatistics.js');
@ -68,14 +69,13 @@ class Pool extends EventEmitter {
// appropriate exception if not.
//---------------------------------------------------------------------------
_checkPoolOpen(ignoreReconfiguring) {
// if already in reconfiguring status, nothing to do.
if (this.status === constants.POOL_STATUS_DRAINING) {
throw new Error(nodbUtil.getErrorMessage('NJS-064'));
errors.throwErr(errors.ERR_POOL_CLOSING);
} else if (this.status === constants.POOL_STATUS_CLOSED) {
throw new Error(nodbUtil.getErrorMessage('NJS-065'));
errors.throwErr(errors.ERR_POOL_CLOSED);
} else if (!ignoreReconfiguring) {
if (this.status === constants.POOL_STATUS_RECONFIGURING) {
throw new Error(nodbUtil.getErrorMessage('NJS-082'));
errors.throwErr(errors.ERR_POOL_RECONFIGURING);
}
}
}
@ -294,14 +294,14 @@ class Pool extends EventEmitter {
let forceClose = false;
// check arguments
nodbUtil.checkArgCount(arguments, 0, 1);
errors.assertArgCount(arguments, 0, 1);
if (arguments.length == 1) {
// drain time must be a valid number; timeouts larger than a 32-bit signed
// integer are not supported
nodbUtil.assert(typeof a1 === 'number', 'NJS-005', 1);
errors.assertParamValue(typeof a1 === 'number', 1);
if (a1 < 0 || isNaN(a1) || a1 > 2 ** 31) {
throw new Error(nodbUtil.getErrorMessage('NJS-005', 1));
errors.throwErr(errors.ERR_INVALID_PARAMETER_VALUE, 1);
}
// no need to worry about drain time if no connections are out!
@ -349,7 +349,7 @@ class Pool extends EventEmitter {
logStatistics() {
const stats = this.getStatistics();
if (stats === null) {
throw new Error(nodbUtil.getErrorMessage('NJS-083'));
errors.throwErr(errors.ERR_POOL_STATISTICS_DISABLED);
}
stats.logStatistics();
}
@ -367,9 +367,9 @@ class Pool extends EventEmitter {
let options = {};
// check arguments
nodbUtil.checkArgCount(arguments, 0, 1);
errors.assertArgCount(arguments, 0, 1);
if (arguments.length == 1) {
nodbUtil.assert(nodbUtil.isObject(a1), 'NJS-005', 1);
errors.assertParamValue(nodbUtil.isObject(a1), 1);
options = a1;
}
@ -402,7 +402,7 @@ class Pool extends EventEmitter {
if (this._enableStatistics) {
this._totalRequestsRejected += 1;
}
throw new Error(nodbUtil.getErrorMessage('NJS-076', this._queueMax));
errors.throwErr(errors.ERR_QUEUE_MAX_EXCEEDED, this._queueMax);
}
// if too many connections are out, wait until room is made available or
@ -425,8 +425,12 @@ class Pool extends EventEmitter {
this._totalRequestTimeouts += 1;
this._updateWaitStatistics(payload);
}
reject(new Error(nodbUtil.getErrorMessage('NJS-040',
this._queueTimeout)));
try {
errors.throwErr(errors.ERR_CONN_REQUEST_TIMEOUT,
this._queueTimeout);
} catch (err) {
reject(err);
}
}, this._queueTimeout);
}
@ -524,27 +528,27 @@ class Pool extends EventEmitter {
async reconfigure(options) {
// check arguments
nodbUtil.checkArgCount(arguments, 1, 1);
nodbUtil.assert(nodbUtil.isObject(options));
errors.assertArgCount(arguments, 1, 1);
errors.assertParamValue(nodbUtil.isObject(options));
// reconfiguration can happen only when status is OPEN
this._checkPoolOpen(false);
if ((options.queueMax !== undefined) &&
(typeof options.queueMax !== "number"))
throw new Error(nodbUtil.getErrorMessage('NJS-004', "queueMax"));
errors.throwErr(errors.ERR_INVALID_PROPERTY_VALUE, "queueMax");
if ((options.queueTimeout !== undefined) &&
(typeof options.queueTimeout !== "number"))
throw new Error(nodbUtil.getErrorMessage('NJS-004', "queueTimeout"));
errors.throwErr(errors.ERR_INVALID_PROPERTY_VALUE, "queueTimeout");
if ((options.enableStatistics !== undefined) &&
(typeof options.enableStatistics !== "boolean"))
throw new Error(nodbUtil.getErrorMessage('NJS-004', "enableStatistics"));
errors.throwErr(errors.ERR_INVALID_PROPERTY_VALUE, "enableStatistics");
if ((options.resetStatistics !== undefined) &&
(typeof options.resetStatistics != "boolean"))
throw new Error(nodbUtil.getErrorMessage('NJS-004', "resetStatistics"));
errors.throwErr(errors.ERR_INVALID_PROPERTY_VALUE, "resetStatistics");
this._status = constants.POOL_STATUS_RECONFIGURING;
try {
@ -586,8 +590,8 @@ class Pool extends EventEmitter {
// Set parameters for token based authentication.
//---------------------------------------------------------------------------
async setAccessToken(options) {
nodbUtil.checkArgCount(arguments, 1, 1);
nodbUtil.assert(nodbUtil.isObject(options), 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 1);
errors.assertParamValue(nodbUtil.isObject(options), 1);
await this._setAccessToken(options);
}

View File

@ -21,8 +21,9 @@
const QueryStream = require('./queryStream.js');
const nodbUtil = require('./util.js');
const settings = require('./settings.js');
const constants = require('./constants.js');
const errors = require('./errors.js');
const settings = require('./settings.js');
const Connection = require('./connection.js');
class ResultSet {
@ -132,10 +133,10 @@ class ResultSet {
// Close the result set and make it unusable for further operations.
//---------------------------------------------------------------------------
async close() {
nodbUtil.checkArgCount(arguments, 0, 0);
errors.assertArgCount(arguments, 0, 0);
if (this._convertedToStream) {
throw new Error(nodbUtil.getErrorMessage('NJS-042'));
errors.throwErr(errors.ERR_CANNOT_INVOKE_RS_METHODS);
}
this._processingStarted = true;
@ -150,10 +151,10 @@ class ResultSet {
// through the thread pool that would be required if implemented in C.
//---------------------------------------------------------------------------
async getRow() {
nodbUtil.checkArgCount(arguments, 0, 0);
errors.assertArgCount(arguments, 0, 0);
if (this._convertedToStream && !this._allowGetRowCall) {
throw new Error(nodbUtil.getErrorMessage('NJS-042'));
errors.throwErr(errors.ERR_CANNOT_INVOKE_RS_METHODS);
}
this._allowGetRowCall = false;
@ -177,17 +178,16 @@ class ResultSet {
async getRows(numRows) {
let rowsNeeded;
nodbUtil.checkArgCount(arguments, 0, 1);
errors.assertArgCount(arguments, 0, 1);
if (arguments.length == 0) {
numRows = 0;
} else {
nodbUtil.assert(Number.isInteger(numRows), 'NJS-005', 1);
nodbUtil.assert(numRows >= 0, 'NJS-005', 1);
errors.assertParamValue(Number.isInteger(numRows) && numRows >= 0, 1);
}
if (this._convertedToStream) {
throw new Error(nodbUtil.getErrorMessage('NJS-042'));
errors.throwErr(errors.ERR_CANNOT_INVOKE_RS_METHODS);
}
this._processingStarted = true;
@ -227,14 +227,14 @@ class ResultSet {
// Converts a result set to a QueryStream object.
//---------------------------------------------------------------------------
toQueryStream() {
nodbUtil.checkArgCount(arguments, 0, 0);
errors.assertArgCount(arguments, 0, 0);
if (this._processingStarted) {
throw new Error(nodbUtil.getErrorMessage('NJS-041'));
errors.throwErr(errors.ERR_CANNOT_CONVERT_RS_TO_STREAM);
}
if (this._convertedToStream) {
throw new Error(nodbUtil.getErrorMessage('NJS-043'));
errors.throwErr(errors.ERR_RS_ALREADY_CONVERTED);
}
this._convertedToStream = true;
@ -257,7 +257,7 @@ class ResultSet {
}
nodbUtil.wrap_fns(ResultSet.prototype, "NJS-017",
nodbUtil.wrap_fns(ResultSet.prototype, errors.ERR_BUSY_RS,
"close",
"getRow",
"getRows");

View File

@ -19,6 +19,7 @@
'use strict';
const errors = require('./errors.js');
const nodbUtil = require('./util.js');
class SodaCollection {
@ -28,7 +29,7 @@ class SodaCollection {
}
find() {
nodbUtil.checkArgCount(arguments, 0, 0);
errors.assertArgCount(arguments, 0, 0);
return this._find();
}
@ -42,8 +43,8 @@ class SodaCollection {
// Create an index on the collection.
//---------------------------------------------------------------------------
async createIndex(spec) {
nodbUtil.checkArgCount(arguments, 1, 1);
nodbUtil.assert(nodbUtil.isObject(spec), 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 1);
errors.assertParamValue(nodbUtil.isObject(spec), 1);
return await this._createIndex(JSON.stringify(spec));
}
@ -53,7 +54,7 @@ class SodaCollection {
// Drop the collection.
//---------------------------------------------------------------------------
async drop() {
nodbUtil.checkArgCount(arguments, 0, 0);
errors.assertArgCount(arguments, 0, 0);
return await this._drop();
}
@ -65,10 +66,10 @@ class SodaCollection {
async dropIndex(indexName, a2) {
let options = {};
nodbUtil.checkArgCount(arguments, 1, 2);
nodbUtil.assert(typeof indexName === 'string', 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 2);
errors.assertParamValue(typeof indexName === 'string', 1);
if (arguments.length == 2) {
nodbUtil.assert(typeof a2 === 'object', 'NJS-005', 2);
errors.assertParamValue(typeof a2 === 'object', 2);
options = a2;
}
@ -80,7 +81,7 @@ class SodaCollection {
// Return the data guide for the collection.
//---------------------------------------------------------------------------
async getDataGuide() {
nodbUtil.checkArgCount(arguments, 0, 0);
errors.assertArgCount(arguments, 0, 0);
return await this._getDataGuide();
}
@ -90,12 +91,8 @@ class SodaCollection {
// Insert an array of documents into the collection in a single round-trip.
//---------------------------------------------------------------------------
async insertMany(docs) {
nodbUtil.checkArgCount(arguments, 1, 1);
nodbUtil.assert(Array.isArray(docs), 'NJS-005', 1);
if (docs.length == 0) {
throw new Error(nodbUtil.getErrorMessage('NJS-005', 1));
}
errors.assertArgCount(arguments, 1, 1);
errors.assertParamValue(Array.isArray(docs) && docs.length > 0, 1);
let actualDocs = Array(docs.length);
for (let i = 0; i < docs.length; i++) {
@ -118,18 +115,14 @@ class SodaCollection {
async insertManyAndGet(docs, a2) {
let options = {};
nodbUtil.checkArgCount(arguments, 1, 2);
nodbUtil.assert(Array.isArray(docs), 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 2);
errors.assertParamValue(Array.isArray(docs) && docs.length > 0, 1);
if (arguments.length == 2) {
nodbUtil.assert(nodbUtil.isObject(a2), 'NJS-005', 2);
errors.assertParamValue(nodbUtil.isObject(a2), 2);
options = a2;
}
if (docs.length == 0) {
throw new Error(nodbUtil.getErrorMessage('NJS-005', 1));
}
let actualDocs = Array(docs.length);
for (let i = 0; i < docs.length; i++) {
let content = docs[i];
@ -148,9 +141,9 @@ class SodaCollection {
// Inserts a single document into the collection.
//---------------------------------------------------------------------------
async insertOne(content) {
nodbUtil.checkArgCount(arguments, 1, 1);
nodbUtil.assert(nodbUtil.isObject(content) ||
nodbUtil.isSodaDocument(content), 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 1);
errors.assertParamValue(nodbUtil.isObject(content) ||
nodbUtil.isSodaDocument(content), 1);
if (!nodbUtil.isSodaDocument(content)) {
content = Buffer.from(JSON.stringify(content));
@ -168,12 +161,12 @@ class SodaCollection {
async insertOneAndGet(content, a2) {
let options = {};
nodbUtil.checkArgCount(arguments, 1, 2);
nodbUtil.assert(nodbUtil.isObject(content) ||
nodbUtil.isSodaDocument(content), 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 2);
errors.assertParamValue(nodbUtil.isObject(content) ||
nodbUtil.isSodaDocument(content), 1);
if (arguments.length == 2) {
nodbUtil.assert(nodbUtil.isObject(a2), 'NJS-005', 2);
errors.assertParamValue(nodbUtil.isObject(a2), 2);
options = a2;
}
@ -190,9 +183,9 @@ class SodaCollection {
// Saves a single document into the collection.
//---------------------------------------------------------------------------
async save(content) {
nodbUtil.checkArgCount(arguments, 1, 1);
nodbUtil.assert(nodbUtil.isObject(content) ||
nodbUtil.isSodaDocument(content), 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 1);
errors.assertParamValue(nodbUtil.isObject(content) ||
nodbUtil.isSodaDocument(content), 1);
if (!nodbUtil.isSodaDocument(content)) {
content = Buffer.from(JSON.stringify(content));
@ -210,12 +203,12 @@ class SodaCollection {
async saveAndGet(content, a2) {
let options = {};
nodbUtil.checkArgCount(arguments, 1, 2);
nodbUtil.assert(nodbUtil.isObject(content) ||
nodbUtil.isSodaDocument(content), 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 2);
errors.assertParamValue(nodbUtil.isObject(content) ||
nodbUtil.isSodaDocument(content), 1);
if (arguments.length == 2) {
nodbUtil.assert(nodbUtil.isObject(a2), 'NJS-005', 2);
errors.assertParamValue(nodbUtil.isObject(a2), 2);
options = a2;
}
@ -232,7 +225,7 @@ class SodaCollection {
// Remove all of the documents from a collection.
//---------------------------------------------------------------------------
async truncate() {
nodbUtil.checkArgCount(arguments, 0, 0);
errors.assertArgCount(arguments, 0, 0);
await this._truncate();
}

View File

@ -19,6 +19,7 @@
'use strict';
const errors = require('./errors.js');
const nodbUtil = require('./util.js');
class SodaDatabase {
@ -35,16 +36,15 @@ class SodaDatabase {
async createCollection(name, a2) {
let options = {};
nodbUtil.checkArgCount(arguments, 1, 2);
nodbUtil.assert(typeof name === 'string', 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 2);
errors.assertParamValue(typeof name === 'string', 1);
if (arguments.length == 2) {
nodbUtil.assert(nodbUtil.isObject(a2), 'NJS-005', 2);
errors.assertParamValue(nodbUtil.isObject(a2), 2);
options = a2;
if (options.metaData) {
if (!nodbUtil.isObject(options.metaData)) {
throw new Error(nodbUtil.getErrorMessage('NJS-005', 2));
}
errors.assertParamPropValue(nodbUtil.isObject(options.metaData), 2,
"metaData");
options.metaData = JSON.stringify(options.metaData);
}
}
@ -60,11 +60,11 @@ class SodaDatabase {
createDocument(content, a2) {
let options = {};
nodbUtil.checkArgCount(arguments, 1, 2);
nodbUtil.assert(Buffer.isBuffer(content) || typeof content === 'string' ||
nodbUtil.isObject(content), 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 2);
errors.assertParamValue(Buffer.isBuffer(content) ||
typeof content === 'string' || nodbUtil.isObject(content), 1);
if (arguments.length > 1) {
nodbUtil.assert(nodbUtil.isObject(a2), 'NJS-005', 2);
errors.assertParamValue(nodbUtil.isObject(a2), 2);
options = a2;
}
@ -85,9 +85,9 @@ class SodaDatabase {
async getCollectionNames(a1) {
let options = {};
nodbUtil.checkArgCount(arguments, 0, 1);
errors.assertArgCount(arguments, 0, 1);
if (arguments.length == 1) {
nodbUtil.assert(nodbUtil.isObject(a1), 'NJS-005', 1);
errors.assertParamValue(nodbUtil.isObject(a1), 1);
options = a1;
}
return await this._getCollectionNames(options);
@ -98,8 +98,8 @@ class SodaDatabase {
// Open an existing SODA collection and return it to the caller.
//---------------------------------------------------------------------------
async openCollection(name) {
nodbUtil.checkArgCount(arguments, 1, 1);
nodbUtil.assert(typeof name === 'string', 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 1);
errors.assertParamValue(typeof name === 'string', 1);
return await this._openCollection(name);
}

View File

@ -19,9 +19,9 @@
'use strict';
const errors = require('./errors.js');
const nodbUtil = require('./util.js');
class SodaDocCursor {
_getConnection() {
@ -33,7 +33,7 @@ class SodaDocCursor {
// Return the new document available from the cursor.
//---------------------------------------------------------------------------
async getNext() {
nodbUtil.checkArgCount(arguments, 0, 0);
errors.assertArgCount(arguments, 0, 0);
return await this._getNext();
}
@ -43,7 +43,7 @@ class SodaDocCursor {
// Close the cursor and make it unusable for further operations.
//--------------------------------------------------------------------------
async close() {
nodbUtil.checkArgCount(arguments, 0, 0);
errors.assertArgCount(arguments, 0, 0);
await this._close();
}

View File

@ -19,6 +19,7 @@
'use strict';
const errors = require('./errors.js');
const nodbUtil = require('./util.js');
class SodaOperation {
@ -37,7 +38,7 @@ class SodaOperation {
// Return a count of the number of documents that match the search criteria.
//---------------------------------------------------------------------------
async count() {
nodbUtil.checkArgCount(arguments, 0, 0);
errors.assertArgCount(arguments, 0, 0);
return await this._count(this._options);
}
@ -48,7 +49,7 @@ class SodaOperation {
// criteria.
//---------------------------------------------------------------------------
async getCursor() {
nodbUtil.checkArgCount(arguments, 0, 0);
errors.assertArgCount(arguments, 0, 0);
return await this._getCursor(this._options);
}
@ -57,7 +58,7 @@ class SodaOperation {
// Return an array of documents that match the search criteria.
//---------------------------------------------------------------------------
async getDocuments() {
nodbUtil.checkArgCount(arguments, 0, 0);
errors.assertArgCount(arguments, 0, 0);
return await this._getDocuments(this._options);
}
@ -67,7 +68,7 @@ class SodaOperation {
// Return the first document that matches the search criteria.
//---------------------------------------------------------------------------
async getOne() {
nodbUtil.checkArgCount(arguments, 0, 0);
errors.assertArgCount(arguments, 0, 0);
return await this._getOne(this._options);
}
@ -78,9 +79,9 @@ class SodaOperation {
// specified document.
//---------------------------------------------------------------------------
async replaceOne(content) {
nodbUtil.checkArgCount(arguments, 1, 1);
nodbUtil.assert(nodbUtil.isObject(content) ||
nodbUtil.isSodaDocument(content), 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 1);
errors.assertParamValue(nodbUtil.isObject(content) ||
nodbUtil.isSodaDocument(content), 1);
if (!nodbUtil.isSodaDocument(content)) {
content = Buffer.from(JSON.stringify(content));
@ -96,9 +97,9 @@ class SodaOperation {
// specified document and then return a result document containing metadata.
//---------------------------------------------------------------------------
async replaceOneAndGet(content) {
nodbUtil.checkArgCount(arguments, 1, 1);
nodbUtil.assert(nodbUtil.isObject(content) ||
nodbUtil.isSodaDocument(content), 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 1);
errors.assertParamValue(nodbUtil.isObject(content) ||
nodbUtil.isSodaDocument(content), 1);
if (!nodbUtil.isSodaDocument(content)) {
content = Buffer.from(JSON.stringify(content));
@ -114,38 +115,38 @@ class SodaOperation {
// and return information about the operation to the caller.
//---------------------------------------------------------------------------
async remove() {
nodbUtil.checkArgCount(arguments, 0, 0);
errors.assertArgCount(arguments, 0, 0);
return await this._remove(this._options);
}
// fetchArraySize - a non-terminal function that can chain further
fetchArraySize(n) {
nodbUtil.checkArgCount(arguments, 1, 1);
nodbUtil.assert(typeof n === 'number', 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 1);
errors.assertParamValue(typeof n === 'number', 1);
this._options.fetchArraySize = n;
return this;
}
// filter property - a non-terminal function and can chain further
filter(f) {
nodbUtil.checkArgCount (arguments, 1, 1);
nodbUtil.assert(nodbUtil.isObject(f), 'NJS-005', 1);
errors.assertArgCount (arguments, 1, 1);
errors.assertParamValue(nodbUtil.isObject(f), 1);
this._options.filter = JSON.stringify(f);
return this;
}
// hint - a non-terminal function and can chain further
hint(val) {
nodbUtil.checkArgCount(arguments, 1, 1);
nodbUtil.assert(typeof val === 'string', 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 1);
errors.assertParamValue(typeof val === 'string', 1);
this._options.hint = val;
return this;
}
// key - a non-terminal function and can chain further
key(k) {
nodbUtil.checkArgCount(arguments, 1, 1);
nodbUtil.assert(typeof k === 'string', 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 1);
errors.assertParamValue(typeof k === 'string', 1);
this._options.key = k;
this._options.keys = undefined;
return this;
@ -153,11 +154,11 @@ class SodaOperation {
// keys - a non-terminal function and can chain further
keys(arr) {
nodbUtil.checkArgCount(arguments, 1, 1);
nodbUtil.assert(Array.isArray(arr), 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 1);
errors.assertParamValue(Array.isArray(arr), 1);
for (let i = 0; i < arr.length; i++) {
nodbUtil.assert(typeof arr[i] === 'string', 'NJS-005', 1);
errors.assertParamValue(typeof arr[i] === 'string', 1);
}
this._options.keys = arr;
@ -167,24 +168,24 @@ class SodaOperation {
// limit property - a non-terminal function and can chain further
limit(n) {
nodbUtil.checkArgCount(arguments, 1, 1);
nodbUtil.assert(typeof n === 'number', 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 1);
errors.assertParamValue(typeof n === 'number', 1);
this._options.limit = n;
return this;
}
// skip property - a non-terminal function and can chain further
skip(n) {
nodbUtil.checkArgCount(arguments, 1, 1);
nodbUtil.assert(typeof n === 'number', 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 1);
errors.assertParamValue(typeof n === 'number', 1);
this._options.skip = n;
return this;
}
// version property - a non-terminal function and can chain further
version(v) {
nodbUtil.checkArgCount(arguments, 1, 1);
nodbUtil.assert(typeof v === 'string', 'NJS-005', 1);
errors.assertArgCount(arguments, 1, 1);
errors.assertParamValue(typeof v === 'string', 1);
this._options.version = v;
return this;
}

View File

@ -19,7 +19,7 @@
'use strict';
const util = require('util');
const errors = require('./errors.js');
// node-oracledb version number
let packageJSON;
@ -43,38 +43,6 @@ module.exports.BINARY_FILE = BINARY_FILE;
const STAGING_DIR = 'package/Staging';
module.exports.STAGING_DIR = STAGING_DIR;
// errorMessages is for NJS error messages used in the JavaScript layer
const errorMessages = {
'NJS-002': 'NJS-002: invalid pool',
'NJS-004': 'NJS-004: invalid value for property %s',
'NJS-005': 'NJS-005: invalid value for parameter %d',
'NJS-009': 'NJS-009: invalid number of parameters',
'NJS-017': 'NJS-017: concurrent operations on ResultSet are not allowed',
'NJS-021': 'NJS-021: invalid type for conversion specified',
'NJS-023': 'NJS-023: concurrent operations on LOB are not allowed',
'NJS-037': 'NJS-037: incompatible type of value provided',
'NJS-040': 'NJS-040: connection request timeout. Request exceeded queueTimeout of %d',
'NJS-041': 'NJS-041: cannot convert ResultSet to QueryStream after invoking methods',
'NJS-042': 'NJS-042: cannot invoke ResultSet methods after converting to QueryStream',
'NJS-043': 'NJS-043: ResultSet already converted to QueryStream',
'NJS-045': 'NJS-045: cannot load a node-oracledb binary for Node.js ' + process.versions.node + ' (' + process.platform + ' ' + process.arch + ') %s',
'NJS-046': 'NJS-046: poolAlias "%s" already exists in the connection pool cache',
'NJS-047': 'NJS-047: poolAlias "%s" not found in the connection pool cache',
'NJS-064': 'NJS-064: connection pool is closing',
'NJS-065': 'NJS-065: connection pool was closed',
'NJS-067': 'NJS-067: a pre-built node-oracledb binary was not found for %s',
'NJS-069': 'NJS-069: node-oracledb %s requires Node.js %s or later',
'NJS-076': 'NJS-076: connection request rejected. Pool queue length queueMax %d reached',
'NJS-081': 'NJS-081: concurrent operations on a connection are disabled',
'NJS-082': 'NJS-082: connection pool is being reconfigured',
'NJS-083': 'NJS-083: pool statistics not enabled',
'NJS-084': 'NJS-084: invalid access token',
'NJS-085': 'NJS-085: invalid connection pool configuration with token based authentication. The homogeneous and externalAuth attributes must be set to true',
'NJS-086': 'NJS-086: invalid standalone configuration with token based authentication. The externalAuth attribute must be set to true',
'NJS-087': 'NJS-087: access token has expired',
'NJS-088': 'NJS-088: accessTokenCallback cannot be specified when accessToken is a function'
};
// getInstallURL returns a string with installation URL
function getInstallURL() {
return ('Node-oracledb installation instructions: https://oracle.github.io/node-oracledb/INSTALL.html');
@ -137,39 +105,6 @@ function getInstallHelp() {
module.exports.getInstallHelp = getInstallHelp;
// getErrorMessage is used to get and format error messages to make throwing
// errors a little more convenient.
function getErrorMessage(errorCode) {
let args = Array.prototype.slice.call(arguments);
args[0] = errorMessages[errorCode];
return util.format.apply(util, args);
}
module.exports.getErrorMessage = getErrorMessage;
// assert is typically used at the beginning of public functions to assert
// preconditions for the function to execute. Most commonly it is used to
// validate the number of arguments and their types and throw an error if they
// don't match what is expected.
function assert(condition, errorCode, messageArg1) {
if (!condition) {
throw new Error(getErrorMessage(errorCode, messageArg1));
}
}
module.exports.assert = assert;
// checkArgCount is used to validate the number of arguments, particularly with
// optional parameters (range of number of parameters). If the number of
// arguments is not within the given range, an error is thrown.
function checkArgCount(args, minArgCount, maxArgCount) {
if (args.length < minArgCount || args.length > maxArgCount)
throw new Error(getErrorMessage('NJS-009'));
}
module.exports.checkArgCount = checkArgCount;
// The callbackify function is used to wrap async methods to add optional
// callback support. If the last parameter passed to a method is a function,
// then it is assumed that the callback pattern is being used and the promise
@ -230,7 +165,7 @@ module.exports.serialize = serialize;
function preventConcurrent(func, errorCode) {
return async function() {
if (this._isActive)
throw new Error(getErrorMessage(errorCode));
errors.throwErr(errorCode);
this._isActive = true;
try {
return await func.apply(this, arguments);
@ -250,7 +185,7 @@ module.exports.preventConcurrent = preventConcurrent;
function wrap_fns(proto) {
let nameIndex = 1;
let preventConcurrentErrorCode;
if (arguments[1].startsWith('NJS-')) {
if (typeof arguments[1] === 'number') {
nameIndex = 2;
preventConcurrentErrorCode = arguments[1];
}
@ -293,9 +228,9 @@ function isXid(value) {
module.exports.isXid = isXid;
function isTokenExpired(token) {
assert(typeof token === 'string', 'NJS-084');
errors.assert(typeof token === 'string', errors.ERR_TOKEN_BASED_AUTH);
if (token.split('.')[1] === undefined) {
throw new Error(getErrorMessage('NJS-084'));
errors.throwErr(errors.ERR_TOKEN_BASED_AUTH);
}
const base64Url = token.split('.')[1];
@ -304,7 +239,7 @@ function isTokenExpired(token) {
const payloadInit = buff.toString('ascii');
let expiry = JSON.parse(payloadInit).exp;
assert(expiry != undefined, 'NJS-084');
errors.assert(expiry != undefined, errors.ERR_TOKEN_BASED_AUTH);
expiry = expiry * 1000;
return (new Date().getTime() > expiry);
@ -316,7 +251,7 @@ function isTokenValid(accessToken) {
switch (typeof accessToken) {
case 'string':
if (accessToken === '') {
throw new Error(getErrorMessage('NJS-084'));
errors.throwErr(errors.ERR_TOKEN_BASED_AUTH);
}
return !isTokenExpired(accessToken);
@ -325,12 +260,12 @@ function isTokenValid(accessToken) {
accessToken.token === '' ||
accessToken.privateKey === undefined ||
accessToken.privateKey === '') {
throw new Error(getErrorMessage('NJS-084'));
errors.throwErr(errors.ERR_TOKEN_BASED_AUTH);
}
return !isTokenExpired(accessToken.token);
default:
throw new Error(getErrorMessage('NJS-084'));
errors.throwErr(errors.ERR_TOKEN_BASED_AUTH);
}
}
@ -347,7 +282,7 @@ async function checkToken(attrs) {
accessToken = attrs.accessToken;
}
if (!isTokenValid(accessToken)) {
throw new Error(getErrorMessage('NJS-087'));
errors.throwErr(errors.ERR_TOKEN_HAS_EXPIRED);
}
if (typeof accessToken === 'string') {
attrs.token = accessToken;

View File

@ -376,21 +376,21 @@ describe('86. fetchClobAsString3.js', function() {
done();
}); // 86.2.7
it('86.2.8 undefined in fetchAsString will throw NJS-004', function() {
it('86.2.8 undefined in fetchAsString will throw NJS-021', function() {
should.throws(
function() {
oracledb.fetchAsString = [ undefined ];
},
/NJS-004:/
/NJS-021:/
);
}); // 86.2.8
it('86.2.9 Random string in fetchAsString will throw NJS-004', function() {
it('86.2.9 Random string in fetchAsString will throw NJS-021', function() {
should.throws(
function() {
oracledb.fetchAsString = [ "foobar" ];
},
/NJS-004:/
/NJS-021:/
);
}); // 86.2.9
@ -403,39 +403,39 @@ describe('86. fetchClobAsString3.js', function() {
);
}); // 86.2.10
it('86.2.11 Negative integer in fetchAsString will throw NJS-004', function() {
it('86.2.11 Negative integer in fetchAsString will throw NJS-021', function() {
should.throws(
function() {
oracledb.fetchAsString = [ -1 ];
},
/NJS-004:/
/NJS-021:/
);
}); // 86.2.11
it('86.2.12 Random float in fetchAsString will throw NJS-004', function() {
it('86.2.12 Random float in fetchAsString will throw NJS-021', function() {
should.throws(
function() {
oracledb.fetchAsString = [ 3.1415 ];
},
/NJS-004:/
/NJS-021:/
);
}); // 86.2.12
it('86.2.13 Array in fetchAsString will throw NJS-004', function() {
it('86.2.13 Array in fetchAsString will throw NJS-021', function() {
should.throws(
function() {
oracledb.fetchAsString = [ [3] ];
},
/NJS-004:/
/NJS-021:/
);
}); // 86.2.13
it('86.2.14 Object in fetchAsString will throw NJS-004', function() {
it('86.2.14 Object in fetchAsString will throw NJS-021', function() {
should.throws(
function() {
oracledb.fetchAsString = [ {1:1} ];
},
/NJS-004:/
/NJS-021:/
);
}); // 86.2.14

View File

@ -166,7 +166,7 @@ describe('67. poolCache.js', function() {
oracledb.createPool(dbConfig, function(err, pool) {
should.exist(err);
(err.message).should.startWith('NJS-004:');
(err.message).should.startWith('NJS-007:');
should.not.exist(pool);
@ -554,7 +554,7 @@ describe('67. poolCache.js', function() {
oracledb.createPool(dbConfig, function(err) {
should.exist(err);
(err.message).should.startWith('NJS-004:');
(err.message).should.startWith('NJS-007:');
done();
});
@ -567,8 +567,8 @@ describe('67. poolCache.js', function() {
oracledb.createPool(dbConfig, function(err) {
should.exist(err);
(err.message).should.startWith('NJS-004:');
// NJS-004: invalid value for property poolAttrs.poolAlias
(err.message).should.startWith('NJS-007:');
done();
});
});
@ -580,7 +580,7 @@ describe('67. poolCache.js', function() {
oracledb.createPool(dbConfig, function(err) {
should.exist(err);
(err.message).should.startWith('NJS-004:');
(err.message).should.startWith('NJS-007:');
done();
});
@ -593,7 +593,7 @@ describe('67. poolCache.js', function() {
oracledb.createPool(dbConfig, function(err) {
should.exist(err);
(err.message).should.startWith('NJS-004:');
(err.message).should.startWith('NJS-007:');
done();
});
@ -606,7 +606,7 @@ describe('67. poolCache.js', function() {
oracledb.createPool(dbConfig, function(err) {
should.exist(err);
(err.message).should.startWith('NJS-004:');
(err.message).should.startWith('NJS-007:');
done();
});
@ -619,7 +619,7 @@ describe('67. poolCache.js', function() {
oracledb.createPool(dbConfig, function(err) {
should.exist(err);
(err.message).should.startWith('NJS-004:');
(err.message).should.startWith('NJS-007:');
done();
});
@ -632,7 +632,7 @@ describe('67. poolCache.js', function() {
oracledb.createPool(dbConfig, function(err) {
should.exist(err);
(err.message).should.startWith('NJS-004:');
(err.message).should.startWith('NJS-007:');
done();
});

View File

@ -432,7 +432,7 @@ describe('164. soda1.js', () => {
await testsUtil.assertThrowsAsync(
async () => await sd.createCollection(t_collname, options),
/NJS-005:/
/NJS-007:/
);
} catch (err) {

View File

@ -338,10 +338,7 @@ describe('14. stream2.js', function() {
var metaDataRead = false;
stream.on('metadata', function(metaData) {
should.deepEqual(
metaData,
[ { name: 'EMPLOYEE_NAME' } ]
);
should.equal(metaData[0].name, 'EMPLOYEE_NAME');
metaDataRead = true;
});
@ -567,10 +564,8 @@ describe('14. stream2.js', function() {
var metaDataRead = false;
stream.on('metadata', function(metaData) {
should.deepEqual(
metaData,
[ { name: 'A' }, { name: 'B' } ]
);
should.equal(metaData[0].name, 'A');
should.equal(metaData[1].name, 'B');
metaDataRead = true;
});