Skip to content

Commit 08ddf81

Browse files
committed
Add AQ support in Thin mode (1st release)
1 parent 6f2ce2d commit 08ddf81

File tree

28 files changed

+1791
-87
lines changed

28 files changed

+1791
-87
lines changed

doc/src/release_notes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ Thin Mode Changes
5454
#) Fixed bug which results in error ``ORA-01652: unable to extend temp segment``
5555
when bind type CLOB or BLOB is used and bind value passed is not a LOB object.
5656

57+
#) Added support for :ref:`Advanced Queuing <aq>` in Thin Mode.
58+
5759
Thick Mode Changes
5860
++++++++++++++++++
5961

examples/aqmulti.js

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2019, 2024, Oracle and/or its affiliates. */
1+
/* Copyright (c) 2019, 2025, Oracle and/or its affiliates. */
22

33
/******************************************************************************
44
*
@@ -42,22 +42,26 @@ const oracledb = require('oracledb');
4242
const dbConfig = require('./dbconfig.js');
4343
const aqUtil = require('./aqutil.js');
4444

45-
// This example requires node-oracledb Thick mode.
45+
// This example runs in both node-oracledb Thin and Thick modes.
4646
//
47-
// Thick mode requires Oracle Client or Oracle Instant Client libraries. On
48-
// Windows and macOS you can specify the directory containing the
49-
// libraries at runtime or before Node.js starts. On other platforms (where
50-
// Oracle libraries are available) the system library search path must always
51-
// include the Oracle library path before Node.js starts. If the search path
52-
// is not correct, you will get a DPI-1047 error. See the node-oracledb
53-
// installation documentation.
54-
let clientOpts = {};
55-
// On Windows and macOS platforms, set the environment variable
56-
// NODE_ORACLEDB_CLIENT_LIB_DIR to the Oracle Client library path
57-
if (process.platform === 'win32' || process.platform === 'darwin') {
58-
clientOpts = { libDir: process.env.NODE_ORACLEDB_CLIENT_LIB_DIR };
47+
// Optionally run in node-oracledb Thick mode
48+
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
49+
50+
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
51+
// On Windows and macOS you can specify the directory containing the
52+
// libraries at runtime or before Node.js starts. On other platforms (where
53+
// Oracle libraries are available) the system library search path must always
54+
// include the Oracle library path before Node.js starts. If the search path
55+
// is not correct, you will get a DPI-1047 error. See the node-oracledb
56+
// installation documentation.
57+
let clientOpts = {};
58+
// On Windows and macOS platforms, set the environment variable
59+
// NODE_ORACLEDB_CLIENT_LIB_DIR to the Oracle Client library path
60+
if (process.platform === 'win32' || process.platform === 'darwin') {
61+
clientOpts = { libDir: process.env.NODE_ORACLEDB_CLIENT_LIB_DIR };
62+
}
63+
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
5964
}
60-
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
6165

6266
const queueName = "DEMO_RAW_QUEUE";
6367
const RAW_TABLE = "NODB_RAW_QUEUE_TAB";
@@ -99,7 +103,10 @@ async function enq() {
99103
try {
100104
connection = await oracledb.getConnection(credentials);
101105
const queue = await connection.getQueue(queueName);
102-
queue.enqOptions.visibility = oracledb.AQ_VISIBILITY_IMMEDIATE; // Send a message without requiring a commit
106+
107+
/* Thin mode doesn't support visibility options */
108+
if (!oracledb.thin)
109+
queue.enqOptions.visibility = oracledb.AQ_VISIBILITY_IMMEDIATE;
103110

104111
console.log('Enqueuing 4 messages');
105112

@@ -113,6 +120,7 @@ async function enq() {
113120
"Message 4"
114121
];
115122
await queue.enqMany(messages); // !! Review the enqMany() documentation's caveat before using it !!
123+
await connection.commit(); // Required for thin mode
116124

117125
} catch (err) {
118126
console.error(err);
@@ -132,7 +140,10 @@ async function deq() {
132140
try {
133141
connection = await oracledb.getConnection(credentials);
134142
const queue = await connection.getQueue(queueName);
135-
queue.deqOptions.visibility = oracledb.AQ_VISIBILITY_IMMEDIATE; // Change the visibility so no explicit commit is required
143+
144+
/* Thin mode doesn't support visibility options */
145+
if (!oracledb.thin)
146+
queue.enqOptions.visibility = oracledb.AQ_VISIBILITY_IMMEDIATE;
136147

137148
console.log('Dequeuing messages');
138149

@@ -142,6 +153,8 @@ async function deq() {
142153
console.log(msg.payload.toString());
143154
}
144155

156+
await connection.commit(); // Required for thin mode
157+
145158
} catch (err) {
146159
console.error(err);
147160
} finally {

examples/aqobject.js

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2019, 2024, Oracle and/or its affiliates. */
1+
/* Copyright (c) 2019, 2025, Oracle and/or its affiliates. */
22

33
/******************************************************************************
44
*
@@ -42,22 +42,26 @@ const oracledb = require('oracledb');
4242
const dbConfig = require('./dbconfig.js');
4343
const aqUtil = require('./aqutil.js');
4444

45-
// This example requires node-oracledb Thick mode.
45+
// This example runs in both node-oracledb Thin and Thick modes.
4646
//
47-
// Thick mode requires Oracle Client or Oracle Instant Client libraries. On
48-
// Windows and macOS you can specify the directory containing the
49-
// libraries at runtime or before Node.js starts. On other platforms (where
50-
// Oracle libraries are available) the system library search path must always
51-
// include the Oracle library path before Node.js starts. If the search path
52-
// is not correct, you will get a DPI-1047 error. See the node-oracledb
53-
// installation documentation.
54-
let clientOpts = {};
55-
// On Windows and macOS platforms, set the environment variable
56-
// NODE_ORACLEDB_CLIENT_LIB_DIR to the Oracle Client library path
57-
if (process.platform === 'win32' || process.platform === 'darwin') {
58-
clientOpts = { libDir: process.env.NODE_ORACLEDB_CLIENT_LIB_DIR };
47+
// Optionally run in node-oracledb Thick mode
48+
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
49+
50+
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
51+
// On Windows and macOS you can specify the directory containing the
52+
// libraries at runtime or before Node.js starts. On other platforms (where
53+
// Oracle libraries are available) the system library search path must always
54+
// include the Oracle library path before Node.js starts. If the search path
55+
// is not correct, you will get a DPI-1047 error. See the node-oracledb
56+
// installation documentation.
57+
let clientOpts = {};
58+
// On Windows and macOS platforms, set the environment variable
59+
// NODE_ORACLEDB_CLIENT_LIB_DIR to the Oracle Client library path
60+
if (process.platform === 'win32' || process.platform === 'darwin') {
61+
clientOpts = { libDir: process.env.NODE_ORACLEDB_CLIENT_LIB_DIR };
62+
}
63+
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
5964
}
60-
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
6165

6266
const queueName = "ADDR_QUEUE";
6367
const ADDR_TABLE = "ADDR_QUEUE_TAB";

examples/aqoptions.js

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,22 +42,26 @@ const oracledb = require('oracledb');
4242
const dbConfig = require('./dbconfig.js');
4343
const aqUtil = require('./aqutil.js');
4444

45-
// This example requires node-oracledb Thick mode.
45+
// This example runs in both node-oracledb Thin and Thick modes.
4646
//
47-
// Thick mode requires Oracle Client or Oracle Instant Client libraries. On
48-
// Windows and macOS you can specify the directory containing the
49-
// libraries at runtime or before Node.js starts. On other platforms (where
50-
// Oracle libraries are available) the system library search path must always
51-
// include the Oracle library path before Node.js starts. If the search path
52-
// is not correct, you will get a DPI-1047 error. See the node-oracledb
53-
// installation documentation.
54-
let clientOpts = {};
55-
// On Windows and macOS platforms, set the environment variable
56-
// NODE_ORACLEDB_CLIENT_LIB_DIR to the Oracle Client library path
57-
if (process.platform === 'win32' || process.platform === 'darwin') {
58-
clientOpts = { libDir: process.env.NODE_ORACLEDB_CLIENT_LIB_DIR };
47+
// Optionally run in node-oracledb Thick mode
48+
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
49+
50+
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
51+
// On Windows and macOS you can specify the directory containing the
52+
// libraries at runtime or before Node.js starts. On other platforms (where
53+
// Oracle libraries are available) the system library search path must always
54+
// include the Oracle library path before Node.js starts. If the search path
55+
// is not correct, you will get a DPI-1047 error. See the node-oracledb
56+
// installation documentation.
57+
let clientOpts = {};
58+
// On Windows and macOS platforms, set the environment variable
59+
// NODE_ORACLEDB_CLIENT_LIB_DIR to the Oracle Client library path
60+
if (process.platform === 'win32' || process.platform === 'darwin') {
61+
clientOpts = { libDir: process.env.NODE_ORACLEDB_CLIENT_LIB_DIR };
62+
}
63+
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
5964
}
60-
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
6165

6266
const queueName = "DEMO_RAW_QUEUE";
6367
const RAW_TABLE = "NODB_RAW_QUEUE_TAB";

examples/aqraw.js

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2019, 2024, Oracle and/or its affiliates. */
1+
/* Copyright (c) 2019, 2025, Oracle and/or its affiliates. */
22

33
/******************************************************************************
44
*
@@ -42,22 +42,26 @@ const oracledb = require('oracledb');
4242
const dbConfig = require('./dbconfig.js');
4343
const aqUtil = require('./aqutil.js');
4444

45-
// This example requires node-oracledb Thick mode.
45+
// This example runs in both node-oracledb Thin and Thick modes.
4646
//
47-
// Thick mode requires Oracle Client or Oracle Instant Client libraries. On
48-
// Windows and macOS you can specify the directory containing the
49-
// libraries at runtime or before Node.js starts. On other platforms (where
50-
// Oracle libraries are available) the system library search path must always
51-
// include the Oracle library path before Node.js starts. If the search path
52-
// is not correct, you will get a DPI-1047 error. See the node-oracledb
53-
// installation documentation.
54-
let clientOpts = {};
55-
// On Windows and macOS platforms, set the environment variable
56-
// NODE_ORACLEDB_CLIENT_LIB_DIR to the Oracle Client library path
57-
if (process.platform === 'win32' || process.platform === 'darwin') {
58-
clientOpts = { libDir: process.env.NODE_ORACLEDB_CLIENT_LIB_DIR };
47+
// Optionally run in node-oracledb Thick mode
48+
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
49+
50+
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
51+
// On Windows and macOS you can specify the directory containing the
52+
// libraries at runtime or before Node.js starts. On other platforms (where
53+
// Oracle libraries are available) the system library search path must always
54+
// include the Oracle library path before Node.js starts. If the search path
55+
// is not correct, you will get a DPI-1047 error. See the node-oracledb
56+
// installation documentation.
57+
let clientOpts = {};
58+
// On Windows and macOS platforms, set the environment variable
59+
// NODE_ORACLEDB_CLIENT_LIB_DIR to the Oracle Client library path
60+
if (process.platform === 'win32' || process.platform === 'darwin') {
61+
clientOpts = { libDir: process.env.NODE_ORACLEDB_CLIENT_LIB_DIR };
62+
}
63+
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
5964
}
60-
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
6165

6266
const queueName = "DEMO_RAW_QUEUE";
6367
const RAW_TABLE = "NODB_RAW_QUEUE_TAB";

lib/impl/datahandlers/buffer.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,18 @@ class BaseBuffer {
397397
return buf;
398398
}
399399

400+
//---------------------------------------------------------------------------
401+
// readBytesAndLength()
402+
//
403+
// Reads the UB4 length from the buffer and then returns a Buffer containing
404+
// the specified number of bytes.
405+
//---------------------------------------------------------------------------
406+
readBytesAndLength() {
407+
const numBytes = this.readUB4();
408+
if (numBytes > 0)
409+
return this.readBytesWithLength();
410+
}
411+
400412
//---------------------------------------------------------------------------
401413
// readBytesWithLength()
402414
//
@@ -548,6 +560,17 @@ class BaseBuffer {
548560
return Buffer.from(buf).swap16().toString('utf16le');
549561
}
550562

563+
//---------------------------------------------------------------------------
564+
// readStrAndLength()
565+
//
566+
// Reads a length from the buffer and then, if the length is non-zero, reads
567+
// string from the buffer and returns it.
568+
//---------------------------------------------------------------------------
569+
readStrAndLength() {
570+
const buf = this.readBytesAndLength();
571+
return buf ? buf.toString() : null;
572+
}
573+
551574
//---------------------------------------------------------------------------
552575
// readUB2()
553576
//
@@ -997,6 +1020,32 @@ class BaseBuffer {
9971020
this.buf.writeInt32BE(n, pos);
9981021
}
9991022

1023+
//---------------------------------------------------------------------------
1024+
// writeSB4()
1025+
//
1026+
// Writes a signed integer (up to 4 bytes in length) in variable length
1027+
// format to the buffer.
1028+
//---------------------------------------------------------------------------
1029+
writeSB4(value) {
1030+
let sign = 0;
1031+
if (value < 0) {
1032+
value = -value;
1033+
sign = 0x80;
1034+
}
1035+
if (value === 0) {
1036+
this.writeUInt8(0);
1037+
} else if (value <= 0xff) {
1038+
this.writeUInt8(1 | sign);
1039+
this.writeUInt8(value);
1040+
} else if (value <= 0xffff) {
1041+
this.writeUInt8(2 | sign);
1042+
this.writeUInt16BE(value);
1043+
} else {
1044+
this.writeUInt8(4 | sign);
1045+
this.writeUInt32BE(value);
1046+
}
1047+
}
1048+
10001049
//---------------------------------------------------------------------------
10011050
// writeUB4()
10021051
//

0 commit comments

Comments
 (0)