Skip to content

Commit 1950872

Browse files
committed
Network code formatting and error updates, test case, examples and documentation corrections
1 parent fafeb65 commit 1950872

22 files changed

+306
-116
lines changed

doc/src/release_notes.rst

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,23 @@ Common Changes
2323
Thin Mode Changes
2424
+++++++++++++++++
2525

26-
#) Fixed issue which stopped applications from connecting to Oracle Database
27-
with distinct TNS aliases from more than one tnsnames.ora file.
28-
29-
#) Fixed bug that fails to throw an error, when fetching data greater
30-
than the ``maxSize`` property of outbinds in Oracle Database 12.1.
26+
#) Fixed issue which stopped applications from connecting to Oracle Database
27+
with distinct TNS aliases from more than one
28+
:ref:`tnsnames.ora <tnsadmin>` file.
29+
30+
#) Fixed bug that fails to throw an error, when fetching data greater
31+
than the :ref:`maxSize <executebindparammaxsize>` property of outbinds in
32+
Oracle Database 12.1.
33+
34+
#) Fixed bug that throws incorrect error message when invalid ``retryCount``
35+
parameter is specified in the connect string.
36+
37+
#) Throw error in case of TLS initialization failure when resend response
38+
network packets are received.
39+
40+
#) Added new error message, when invalid or unresolvable host name is
41+
provided in the connect string.
42+
See `Issue #1673 <https://github.com/oracle/node-oracledb/issues/1673>`__.
3143

3244
node-oracledb `v6.7.0 <https://github.com/oracle/node-oracledb/compare/v6.6.0...v6.7.0>`__ (18 Nov 2024)
3345
---------------------------------------------------------------------------------------------------------

examples/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ File Name | Description
6565
[`aqraw.js`](aqraw.js) | Basic Oracle Advanced Queuing (AQ) example passing text messages
6666
[`aqutil.js`](aqutil.js) | Common file to setup the user credentials for all the Advanced Queuing (AQ) examples.
6767
[`blobhttp.js`](blobhttp.js) | Simple web app that streams an image
68-
[`azureConfigProvider.js`](azureConfigProvider.js) | Show how to connect to an Oracle Database using Azure Configuration Providers
68+
[`azureConfigProvider.js`](azureConfigProvider.js) | Show how to connect to Oracle Database using Azure Configuration Provider
6969
[`calltimeout.js`](calltimeout.js) | Shows how to cancel a SQL statement if it doesn't complete in a specified time
7070
[`connect.js`](connect.js) | Basic example for creating a standalone (non-pooled) connection
7171
[`connectionpool.js`](connectionpool.js) | Basic example creating a pool of connections
@@ -102,7 +102,8 @@ File Name | Description
102102
[`lobstream2.js`](lobstream2.js) | Shows using Stream data events to fetch a CLOB
103103
[`lowercasecolumns.js`](lowercasecolumns.js) | Shows how a type handler can convert column names to lower case
104104
[`metadata.js`](metadata.js) | Shows the metadata available after executing SELECT statements
105-
[`ociConfigProvider.js`](ociConfigProvider.js) | Show how to connect to an Oracle Database using OCI Configuration Providers
105+
[`ociConfigProvider.js`](ociConfigProvider.js) | Show how to connect to Oracle Database using OCI Config Provider
106+
[`ociConfigProviderPool.js`](ociConfigProviderPool.js) | Show how to connect with custom pool settings to Oracle Database using OCI Config Provider
106107
[`plsqlarray.js`](plsqlarray.js) | Examples of binding PL/SQL "INDEX BY" tables
107108
[`plsqlfunc.js`](plsqlfunc.js) | How to call a PL/SQL function
108109
[`plsqlproc.js`](plsqlproc.js) | How to call a PL/SQL procedure

examples/ociConfigProviderPool.js

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/* Copyright (c) 2024, Oracle and/or its affiliates. */
2+
3+
/******************************************************************************
4+
*
5+
* This software is dual-licensed to you under the Universal Permissive License
6+
* (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
7+
* 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
8+
* either license.
9+
*
10+
* If you elect to accept the software under the Apache License, Version 2.0,
11+
* the following applies:
12+
*
13+
* Licensed under the Apache License, Version 2.0 (the "License");
14+
* you may not use this file except in compliance with the License.
15+
* You may obtain a copy of the License at
16+
*
17+
* https://www.apache.org/licenses/LICENSE-2.0
18+
*
19+
* Unless required by applicable law or agreed to in writing, software
20+
* distributed under the License is distributed on an "AS IS" BASIS,
21+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22+
* See the License for the specific language governing permissions and
23+
* limitations under the License.
24+
*
25+
* NAME
26+
* ociConfigProviderPool.js
27+
*
28+
* DESCRIPTION
29+
* Sample program using connection pool to connect to the database using
30+
* DB connect string, username and password fetched from the OCI
31+
* Configuration Providers using the OCI Object Store Connect String URL.
32+
*
33+
*****************************************************************************/
34+
35+
'use strict';
36+
37+
Error.stackTraceLimit = 50;
38+
39+
const oracledb = require('oracledb');
40+
41+
// This example runs in both node-oracledb Thin and Thick modes.
42+
//
43+
// Optionally run in node-oracledb Thick mode
44+
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
45+
46+
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
47+
// On Windows and macOS Intel you can specify the directory containing the
48+
// libraries at runtime or before Node.js starts. On other platforms (where
49+
// Oracle libraries are available) the system library search path must always
50+
// include the Oracle library path before Node.js starts. If the search path
51+
// is not correct, you will get a DPI-1047 error. See the node-oracledb
52+
// installation documentation.
53+
let clientOpts = {};
54+
// On Windows and macOS Intel platforms, set the environment
55+
// variable NODE_ORACLEDB_CLIENT_LIB_DIR to the Oracle Client library path
56+
if (process.platform === 'win32' || (process.platform === 'darwin' && process.arch === 'x64')) {
57+
clientOpts = { libDir: process.env.NODE_ORACLEDB_CLIENT_LIB_DIR };
58+
}
59+
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
60+
}
61+
62+
console.log(oracledb.thin ? 'Running in thin mode' : 'Running in thick mode');
63+
64+
async function run() {
65+
// Replace the connect string with correct OCI Config Store URL
66+
// Replace xxxx in the connect string with the correct authentication parameter values
67+
let pool, connection;
68+
const options = {
69+
connectString: 'config-ociobject://test.region.oraclecloud.com/n/testnamespace/b/testbucket/o/testobject?oci_tenancy=xxxx&oci_user=xxxx&oci_fingerprint=xxxx&oci_key_file=xxxx',
70+
};
71+
try {
72+
// Create a pool and get a connection from the pool
73+
pool = await oracledb.createPool(options);
74+
console.log('Pool Created Successfully');
75+
76+
console.log('pool.stmtCacheSize:', pool.stmtCacheSize);
77+
console.log('pool.poolMin:', pool.poolMin);
78+
console.log('pool.poolMax', pool.poolMax);
79+
console.log('pool.poolIncrement:', pool.poolIncrement);
80+
console.log('pool.poolTimeout:', pool.poolTimeout);
81+
console.log('pool.poolPingInterval:', pool.poolPingInterval);
82+
console.log('pool.poolPingTimeout:', pool.poolPingTimeout);
83+
84+
connection = await pool.getConnection(options);
85+
console.log('\nCreated connection from the pool successfully!');
86+
87+
} catch (err) {
88+
console.error(err);
89+
} finally {
90+
if (connection) {
91+
try {
92+
await connection.close();
93+
} catch (err) {
94+
console.error(err);
95+
}
96+
}
97+
98+
if (pool) {
99+
try {
100+
await pool.close();
101+
} catch (err) {
102+
console.error(err);
103+
}
104+
}
105+
}
106+
}
107+
108+
run();

lib/errors.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ const ERR_OCIOBJECT_CONFIG_PROVIDER_AUTH_FAILED = 526;
195195
const ERR_AZURE_VAULT_AUTH_FAILED = 527;
196196
const ERR_AZURE_SERVICE_PRINCIPAL_AUTH_FAILED = 528;
197197
const ERR_WALLET_TYPE_NOT_SUPPORTED = 529;
198+
const ERR_HOST_NOT_FOUND = 530;
198199

199200
// Oracle SUCCESS_WITH_INFO warning start from 700
200201
const WRN_COMPILATION_CREATE = 700;
@@ -527,6 +528,8 @@ messages.set(ERR_AZURE_SERVICE_PRINCIPAL_AUTH_FAILED, // NJS-528
527528
'Azure service principal authentication requires either a client certificate path or a client secret string');
528529
messages.set(ERR_WALLET_TYPE_NOT_SUPPORTED, // NJS-529
529530
'Invalid wallet content format. Supported format is PEM');
531+
messages.set(ERR_HOST_NOT_FOUND, // NJS-530
532+
'The host addresses or URLs provided by the connect string are incorrect or unresolvable in your network.');
530533

531534
// Oracle SUCCESS_WITH_INFO warning
532535
messages.set(WRN_COMPILATION_CREATE, // NJS-700
@@ -844,6 +847,7 @@ module.exports = {
844847
ERR_CONFIG_PROVIDER_NOT_SUPPORTED,
845848
ERR_CONFIG_PROVIDER_LOAD_FAILED,
846849
ERR_WALLET_TYPE_NOT_SUPPORTED,
850+
ERR_HOST_NOT_FOUND,
847851
ERR_INVALID_BIND_NAME,
848852
ERR_WRONG_NUMBER_OF_BINDS,
849853
ERR_BUFFER_LENGTH_INSUFFICIENT,

lib/thin/sqlnet/connStrategy.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2022, 2023, Oracle and/or its affiliates.
1+
// Copyright (c) 2022, 2024, Oracle and/or its affiliates.
22

33
//-----------------------------------------------------------------------------
44
//
@@ -90,6 +90,7 @@ class ConnStrategy {
9090
this.descriptionList.push(this.currentDescription);
9191
this.currentDescription = null;
9292
}
93+
9394
/**
9495
* Execute the Connection Options from the array. When a refuse packet is received from
9596
* server this method is called again and the next connect option is tried.
@@ -148,8 +149,8 @@ class ConnStrategy {
148149
}
149150
// sleep time expects milliseconds
150151

151-
152152
}
153+
153154
function sleep(time) {
154155
return new Promise((resolve) => setTimeout(resolve, time));
155156
}

lib/thin/sqlnet/navNodes.js

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2022, 2023, Oracle and/or its affiliates.
1+
// Copyright (c) 2022, 2024, Oracle and/or its affiliates.
22

33
//-----------------------------------------------------------------------------
44
//
@@ -315,6 +315,7 @@ class Description {
315315
}
316316
}
317317
}
318+
318319
toString() {
319320
let s = new String(""), child ;
320321

@@ -428,9 +429,6 @@ class DescriptionList {
428429
}
429430

430431

431-
432-
433-
434432
/**
435433
* Class that contains information about a possible connection.
436434
*/
@@ -453,23 +451,25 @@ const NavSchemaObject = {
453451
const options = {
454452
all: true,
455453
};
454+
456455
/**
457456
* Class that navigates the address node in the tree.
458457
*/
459458
class NavAddress extends Address {
460459
constructor() {
461460
super();
462461
}
462+
463463
/**
464464
* Set the connection option to this address.
465465
* @param {object} cs
466466
*/
467467
async navigate(cs) {
468468
let addresses;
469-
let nullHost = 0;
469+
let nullHost = false;
470470
let needToCloseDescription = false;
471471
if (!this.host) {
472-
nullHost = 1;
472+
nullHost = true;
473473
this.host = os.hostname();
474474
try {
475475
await dnsPromises.lookup(this.host, options);
@@ -495,7 +495,7 @@ class NavAddress extends Address {
495495
co.httpsProxyPort = this.httpsProxyPort;
496496
co.desc = cs.getcurrentDescription();
497497
co.CNdata.push(cs.sBuf.join(""));
498-
if (nullHost == 1)
498+
if (nullHost)
499499
co.CNdata.push('(address=(protocol=' + this.prot + ')(host=' + this.host + ')(port=' + this.port + '))');
500500
else
501501
co.CNdata.push(this.toString());
@@ -505,6 +505,8 @@ class NavAddress extends Address {
505505
}
506506
} catch {
507507
// do nothing
508+
// Any error in the try block is ignored, because we want to try
509+
// the next address
508510
}
509511
} else {
510512
const co = new ConnOption();
@@ -527,8 +529,6 @@ class NavAddress extends Address {
527529

528530
}
529531

530-
531-
532532
/**
533533
* AddToString is used to construct a string representation of the TNS
534534
* Address. Constructing a string is mainly needed when source route is ON.
@@ -557,10 +557,10 @@ class NavAddressList extends AddressList {
557557
}
558558

559559
/**
560-
* Method decides how to traverse and sets the active children based on
561-
* the loadbalancing, failover values.
562-
* @param {object} cs
563-
*/
560+
* Method decides how to traverse and sets the active children based on
561+
* the loadbalancing, failover values.
562+
* @param {object} cs
563+
*/
564564
async navigate(cs) {
565565
await this.navigate2(cs, 0);
566566
}
@@ -592,6 +592,7 @@ class NavAddressList extends AddressList {
592592
cs.sBuf.length = this.sBuflength;
593593

594594
}
595+
595596
addToString(cs) {
596597
const NVString = this.toString();
597598
let cOpts = new Array();
@@ -604,7 +605,6 @@ class NavAddressList extends AddressList {
604605
}
605606
}
606607

607-
608608
getChildrenSize() {
609609
let size = 0;
610610
for (let i = 0; i < this.activeChildren.length; i++) {
@@ -762,7 +762,6 @@ class NavDescription extends Description {
762762
}
763763

764764
closeNVPair(cs) {
765-
766765
if (cs.getcurrentDescription() == null)
767766
return;
768767
let cOpts = new Array();
@@ -812,11 +811,9 @@ class NavDescription extends Description {
812811
}
813812

814813
getIntValue(stringInt, defaultValue) {
815-
try {
814+
if (/^\d+$/.test(stringInt))
816815
return parseInt(stringInt);
817-
} catch (exception) {
818-
return defaultValue;
819-
}
816+
return defaultValue;
820817
}
821818

822819
}
@@ -884,7 +881,5 @@ class NavDescriptionList extends DescriptionList {
884881

885882
}
886883

887-
888-
889884
}
890885
module.exports = {NavAddress, NavAddressList, NavDescription, NavDescriptionList};

lib/thin/sqlnet/networkSession.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ class NetworkSession {
143143
async getAddress(addressNode, userConfig) {
144144
/* Get the next address */
145145
const address = await addressNode.execute(userConfig);
146+
146147
/* Prepare connection attributes */
147148
const uuid = this.sAtts ? this.sAtts.uuid : null;
148149
this.sAtts = new SessionAtts(uuid);
@@ -196,8 +197,10 @@ class NetworkSession {
196197
}
197198

198199
/**
199-
* Establish network session .Make transport level connection, send NSPTCN(connect packet) and read the response.
200-
* @returns NetError.(connection successfully established(NetError.CONNECTED) or reason for failure)
200+
* Establish network session. Make transport level connection, send
201+
* NSPTCN(connect packet) and read the response. @returns NetError.
202+
* (connection successfully established(NetError.CONNECTED)
203+
* or reason for failure)
201204
*/
202205
async connect2(address, userConfig) {
203206
/* Sanitise SDU */
@@ -534,8 +537,8 @@ class NetworkSession {
534537
try {
535538
address = await this.getAddress(addressNode, userConfig);
536539
} catch (err) {
537-
if (err.message == "All options tried") /* Not even one valid Address */
538-
errors.throwErr(errors.ERR_INVALID_CONNECT_STRING_PARAMETERS, "Ensure the ADDRESS parameters have been entered correctly, the most likely incorrect parameter is the host name");
540+
if (err.message == "All options tried") /* Not even one valid address */
541+
errors.throwErr(errors.ERR_HOST_NOT_FOUND);
539542
else
540543
errors.throwErr(errors.ERR_INVALID_CONNECT_STRING_PARAMETERS, err.message);
541544
}
@@ -617,7 +620,8 @@ class NetworkSession {
617620
/**
618621
* receive inband notification
619622
* @param {Object} obj Return the notification into user provided object
620-
* @returns Error number sent from server, or error on the connection. returns 0 if healthy connection
623+
* @returns Error number sent from server, or error on the connection.
624+
* returns 0 if healthy connection
621625
*/
622626
recvInbandNotif() {
623627
let error = 0;

0 commit comments

Comments
 (0)