Thin mode support and new examples

This commit is contained in:
Sharad Chandran R 2023-05-23 19:50:06 +05:30
parent 310203de4e
commit a8658f059a
187 changed files with 16250 additions and 1615 deletions

View File

@ -1,5 +1,6 @@
.github
.nycrc
.gitattributes
.gitmodules
.eslintrc
INSTALL.md
@ -8,7 +9,9 @@ Makefile
Makefile.win32
*.tgz
/doc
/examples
/examples/*
!/examples/example.js
!/examples/dbconfig.js
/test
/build/Release/oracledb.node
/build/oracledb.target.mk
@ -33,6 +36,5 @@ Makefile.win32
/odpi/test
/odpi/.git
/odpi/.github
/odpi/.gitattributes
/odpi/util
\#*

View File

@ -1,4 +1,4 @@
# node-oracledb version 6.0.0-dev
# node-oracledb version 6.0.0-dev6
**This release is under development and information may be incomplete**
@ -6,7 +6,7 @@ The node-oracledb add-on for Node.js powers high performance Oracle Database
applications. Applications can be written in TypeScript, or directly in
JavaScript.
Use node-oracledb 6.0.0-dev to connect Node.js 14.6, or later, to Oracle
Use node-oracledb 6.0.0-dev6 to connect Node.js 14.6, or later, to Oracle
Database. Older versions of node-oracledb may work with older versions of
Node.js.

View File

@ -10,11 +10,33 @@ node-oracledb `v6.0.0 <https://github.com/oracle/node-oracledb/compare/v5.5.0...
**This release is under development**
#) node-oracledb is now a 'Thin' driver by default that connects directly
to Oracle Database. Optional use of Oracle Client libraries enables a
:ref:`'Thick' mode <enablingthick>` with some additional functionality.
#) Added a new ``oracledb.fetchTypeHandler`` and equivalent execution option
allowing a user function to be specified that can make custom alterations
to SQL query data before it is returned to the app.
#) Deprecated execution option attribute ``fetchInfo``. Use the new
``fetchTypeHandler`` functionality instead.
#) Changed ``oracledb.DB_TYPE_*`` constants to be ``DbType`` objects
instead of numbers.
#) Added support for the Oracle Database 23c BOOLEAN SQL type.
#) Bumped the minimum Node.js version required to 14.6 so Node-API version 6
and ``FinalizationRegistry`` can be used in the driver implementation.
#) Re-licensed to dual Apache 2.0 or UPL 1.0 licenses, see `LICENSE.txt
<https://github.com/oracle/node-oracledb/blob/main/LICENSE.txt>`__.
#) Allow ``package/prunebinaries.js`` to optionally remove all the Thick mode
binaries to enable a Thin-mode only installation.
#) Allow ``npm run buildpackage`` to create a package without Thick mode
binaries.
#) Re-licensed to dual Apache 2.0 or UPL 1.0 licenses, see
`LICENSE.txt <https://github.com/oracle/node-oracledb/blob/main/LICENSE.txt>`__.
#) Internal change: reorganized code to move functionality from C to JavaScript.

View File

@ -1,6 +1,6 @@
# Node-oracledb Examples
This directory contains [node-oracledb](https://www.npmjs.com/package/oracledb)
The directory in node-oracledb's [Github repository](https://github.com/oracle/node-oracledb/tree/main/examples) contains a lot of [node-oracledb](https://www.npmjs.com/package/oracledb)
examples. Documentation is
[here](https://node-oracledb.readthedocs.io/en/latest/).
@ -8,20 +8,12 @@ To run the examples:
- [Install node-oracledb](https://node-oracledb.readthedocs.io/en/latest/user_guide/installation.html#quickstart).
- Edit `dbconfig.js` and set your username and the database connection string,
for example:
- Ensure that you navigate to the `examples` directory in your terminal window
or IDE, where you are running the samples.
```
module.exports = {
user: "hr",
password: process.env.NODE_ORACLEDB_PASSWORD,
connectString:"localhost/orclpdb1"
};
```
- In a terminal window, set the environment variable `NODE_ORACLEDB_PASSWORD` to
the value of your database password.
- Review `dbconfig.js`. In your terminal window or IDE, set the environment
variables. For example, set `NODE_ORACLEDB_PASSWORD` to the value of your
database password.
- Review the samples and then run them individually. For example, to see what
the file `example.js` does, use:
@ -37,6 +29,11 @@ To run the examples:
node demodrop.js
```
Many examples can be run in either node-oracledb Thin (the default) or Thick
modes. Thin mode is a pure JavaScript implementation of node-oracledb.
Setting the environment variable `NODE_ORACLEDB_DRIVER_MODE` to `'thick'` will
change node-oracledb to use Thick mode.
## Example Overview
If this is your first time with node-oracledb, start with
@ -70,7 +67,6 @@ File Name | Description
[`em_rowcounts.js`](em_rowcounts.js) | `executeMany()` example showing how to find the number of rows affected by each input row
[`endtoend.js`](endtoend.js) | Example showing setting tracing attributes
[`example.js`](example.js) | Basic example showing creating a table, inserting multiple rows, and querying rows
[`fetchinfo.js`](fetchinfo.js) | Show how numbers and dates can be returned as strings using `fetchAsString` and `fetchInfo`
[`impres.js`](impres.js) | Shows PL/SQL 'Implict Results' returning multiple query results from PL/SQL code.
[`insert1.js`](insert1.js) | Basic example creating a table and inserting data. Shows DDL and DML
[`insert2.js`](insert2.js) | Basic example showing auto commit behavior
@ -83,6 +79,7 @@ File Name | Description
[`lobselect.js`](lobselect.js) | Shows basic, non-streaming CLOB and BLOB queries
[`lobstream1.js`](lobstream1.js) | Shows how to stream LOBs to files
[`lobstream2.js`](lobstream2.js) | Shows using Stream data events to fetch a CLOB
[`lowercasecolumns.js`](lowercasecolumns.js) | Shows how a type handler can convert column names to lower case
[`metadata.js`](metadata.js) | Shows the metadata available after executing SELECT statements
[`plsqlarray.js`](plsqlarray.js) | Examples of binding PL/SQL "INDEX BY" tables
[`plsqlfunc.js`](plsqlfunc.js) | How to call a PL/SQL function
@ -109,5 +106,7 @@ File Name | Description
[`sessiontagging1.js`](sessiontagging1.js) | Simple pooled connection tagging for setting session state
[`sessiontagging2.js`](sessiontagging2.js) | More complex example of pooled connection tagging for setting session state
[`soda1.js`](soda1.js) | Basic Simple Oracle Document Access (SODA) example
[`typehandlerdate.js`](typehandlerdate.js) | Show how a type handler can format a queried date in a locale-specific way
[`typehandlernum.js`](typehandlernum.js) | Show how a type handler can format a queried number in a locale-specific way
[`version.js`](version.js) | Shows the node-oracledb version attributes
[`webapp.js`](webapp.js) | A simple web application using a connection pool

View File

@ -31,30 +31,32 @@
* Before running this, a queue allowing RAW payloads must be
* created, see https://node-oracledb.readthedocs.io/en/latest/user_guide/aq.html#aqrawexample
*
* This example requires node-oracledb 4 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example requires node-oracledb Thick mode.
//
// Thick mode requires Oracle Client or Oracle Instant Client libraries. On
// Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
const queueName = "DEMO_RAW_QUEUE";
@ -66,7 +68,7 @@ async function enq() {
const queue = await connection.getQueue(queueName);
queue.enqOptions.visibility = oracledb.AQ_VISIBILITY_IMMEDIATE; // Send a message without requiring a commit
console.log('Enqueuing messages');
console.log('Enqueuing 4 messages');
const messages = [
"Message 1",

View File

@ -32,30 +32,31 @@
* payload must be created, see
* https://node-oracledb.readthedocs.io/en/latest/user_guide/aq.html#aqobjexample
*
* This example requires node-oracledb 4 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example requires node-oracledb Thick mode.
//
// Thick mode requires Oracle Client or Oracle Instant Client libraries. On
// Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
const queueName = "ADDR_QUEUE";

View File

@ -31,30 +31,31 @@
* Before running this, a queue allowing RAW payloads must be created, see
* https://node-oracledb.readthedocs.io/en/latest/user_guide/aq.html#aqrawexample
*
* This example requires node-oracledb 4 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example requires node-oracledb Thick mode.
//
// Thick mode requires Oracle Client or Oracle Instant Client libraries. On
// Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
const queueName = "DEMO_RAW_QUEUE";

View File

@ -31,30 +31,31 @@
* Before running this, a queue allowing RAW payloads must be created, see
* https://node-oracledb.readthedocs.io/en/latest/user_guide/aq.html#aqrawexample
*
* This example requires node-oracledb 4 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example requires node-oracledb Thick mode.
//
// Thick mode requires Oracle Client or Oracle Instant Client libraries. On
// Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
const queueName = "DEMO_RAW_QUEUE";

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2015, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2015, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -32,30 +32,37 @@
* Start the listener with 'node blobhttp.js' and then use a browser
* to load http://localhost:7000/getimage
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const url = require('url');
const http = require('http');
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const demoSetup = require('./demosetup.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
const httpPort = 7000;

View File

@ -36,23 +36,36 @@
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require("oracledb");
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
if (oracledb.oracleClientVersion < 1800000000) {
throw new Error("Oracle Client libraries must be 18c or later");
}
}
const dboptime = 4; // seconds the simulated database operation will take
@ -64,10 +77,6 @@ async function run() {
try {
if (oracledb.oracleClientVersion < 1800000000) {
throw new Error("Oracle Client libraries must be 18c or later");
}
connection = await oracledb.getConnection(dbConfig);
connection.callTimeout = timeout * 1000; // milliseconds
@ -79,7 +88,7 @@ async function run() {
console.log("Database operation successfully completed");
} catch (err) {
if (err.message.startsWith('DPI-1067:') || err.errorNum === 3114)
if (err.message.startsWith('NJS-123:') || err.errorNum === 3114)
console.log('Database operation was stopped after exceeding the call timeout');
else
console.error(err);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2015, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2015, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -31,29 +31,34 @@
*
* For a connection pool example see connectionpool.js
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
'use strict';
const fs = require('fs');
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
async function run() {

View File

@ -38,10 +38,12 @@
*
* In production applications, set poolMin=poolMax (and poolIncrement=0)
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
'use strict';
Error.stackTraceLimit = 50;
// If you increase poolMax, you must increase UV_THREADPOOL_SIZE before Node.js
// starts its thread pool. If you set UV_THREADPOOL_SIZE too late, the value is
// ignored and the default size of 4 is used.
@ -49,23 +51,28 @@
// running your application.
// process.env.UV_THREADPOOL_SIZE = 4;
const fs = require('fs');
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
async function init() {
@ -110,7 +117,7 @@ async function dostuff() {
try {
// Get a connection from the default pool
connection = await oracledb.getConnection();
const sql = `SELECT sysdate FROM dual WHERE :b = 1`;
const sql = `SELECT CURRENT_DATE FROM dual WHERE :b = 1`;
const binds = [1];
const options = { outFormat: oracledb.OUT_FORMAT_OBJECT };
const result = await connection.execute(sql, binds, options);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2018, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2018, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -30,37 +30,38 @@
* method to be invoked when a data set changes.
*
* The user must have been granted CHANGE NOTIFICATION.
* The node-oracledb host must be resolvable by the database host.
* See https://node-oracledb.readthedocs.io/en/latest/user_guide/cqn.html
*
* Run this script and then, after the subscription has been created, run
* these statements in a SQL*Plus session:
* INSERT INTO NO_CQNTABLE VALUES (101);
* COMMIT;
*
* This example requires node-oracledb 2.3 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require("oracledb");
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example requires node-oracledb Thick mode.
//
// Thick mode requires Oracle Client or Oracle Instant Client libraries. On
// Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
dbConfig.events = true; // CQN needs events mode

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2018, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2018, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -32,36 +32,38 @@
*
* The user must have been granted CHANGE NOTIFICATION.
* The node-oracledb host must be resolvable by the database host.
* See https://node-oracledb.readthedocs.io/en/latest/user_guide/cqn.html
*
* Run this script and when the subscription has been created, run
* these statements in a SQL*Plus session:
* INSERT INTO NO_CQNTABLE VALUES (1);
* COMMIT;
*
* This example requires node-oracledb 2.3 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require("oracledb");
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example requires node-oracledb Thick mode.
//
// Thick mode requires Oracle Client or Oracle Instant Client libraries. On
// Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
dbConfig.events = true; // CQN needs events mode

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2015, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2015, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -32,32 +32,40 @@
* TIMESTAMP WITH LOCAL TIMEZONE. Similarly for queries, TIMESTAMP
* and DATE columns are fetched as TIMESTAMP WITH LOCAL TIMEZONE.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************///
// Using a fixed Oracle time zone helps avoid machine and deployment differences
process.env.ORA_SDTZ = 'UTC';
'use strict';
Error.stackTraceLimit = 50;
// Using a fixed Oracle time zone helps avoid machine and deployment differences
// process.env.ORA_SDTZ = 'UTC';
const fs = require('fs');
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries. On
// Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
// clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
console.log(oracledb.thin ? 'Running in thin mode' : 'Running in thick mode');
oracledb.outFormat = oracledb.OUT_FORMAT_OBJECT;
async function run() {
@ -92,7 +100,7 @@ async function run() {
}
// When bound, JavaScript Dates are inserted using TIMESTAMP WITH LOCAL TIMEZONE
date = new Date();
date = new Date(1995, 11, 17); // 17th Dec 1995
console.log('Inserting JavaScript date: ' + date);
result = await connection.execute(
`INSERT INTO no_datetab (id, timestampcol, timestamptz, timestampltz, datecol)
@ -111,7 +119,7 @@ async function run() {
console.log('Altering session time zone');
await connection.execute(`ALTER SESSION SET TIME_ZONE='+5:00'`); // resets ORA_SDTZ value
date = new Date();
date = new Date(); // Current Date
console.log('Inserting JavaScript date: ' + date);
result = await connection.execute(
`INSERT INTO no_datetab (id, timestampcol, timestamptz, timestampltz, datecol)

View File

@ -31,7 +31,7 @@
* External Authentication to avoid hard coded credentials.
*
* To create a database user see
* https://blogs.oracle.com/sql/how-to-create-users-grant-them-privileges-and-remove-them-in-oracle-database
* https://blogs.oracle.com/sql/post/how-to-create-users-grant-them-privileges-and-remove-them-in-oracle-database
*
* Applications can set the connectString value to an Easy Connect
* string, or a Net Service Name from a tnsnames.ora file or
@ -81,7 +81,7 @@
*****************************************************************************/
module.exports = {
user : process.env.NODE_ORACLEDB_USER || "hr",
user : process.env.NODE_ORACLEDB_USER,
// Get the password from the environment variable
// NODE_ORACLEDB_PASSWORD. The password could also be a hard coded
@ -92,9 +92,9 @@ module.exports = {
// For information on connection strings see:
// https://node-oracledb.readthedocs.io/en/latest/user_guide/connection_handling.html#connectionstrings
connectString : process.env.NODE_ORACLEDB_CONNECTIONSTRING || "localhost/orclpdb1",
connectString : process.env.NODE_ORACLEDB_CONNECTIONSTRING,
// Setting externalAuth is optional. It defaults to false. See:
// https://node-oracledb.readthedocs.io/en/latest/user_guide/connection_handling.html#extauth
externalAuth : process.env.NODE_ORACLEDB_EXTERNALAUTH ? true : false
externalAuth : process.env.NODE_ORACLEDB_EXTERNALAUTH ? true : false,
};

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2015, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2015, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -30,27 +30,34 @@
*
* The alternate method shown in dbmsoutputpipe.js is more efficient.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
async function run() {

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2015, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2015, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -28,27 +28,34 @@
* DESCRIPTION
* Displays PL/SQL DBMS_OUTPUT using a pipelined table.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
async function run() {

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2019, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2019, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -30,25 +30,13 @@
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
}
async function run() {
let connection;
@ -121,6 +109,8 @@ async function run() {
`DROP TABLE no_nc_address PURGE`,
`DROP TABLE no_typehandler_tab PURGE`,
`CALL DBMS_AQADM.STOP_QUEUE('DEMO_RAW_QUEUE')`,
`CALL DBMS_AQADM.DROP_QUEUE('DEMO_RAW_QUEUE')`,

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2019, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2019, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -30,6 +30,10 @@
*
*****************************************************************************/
'use strict';
Error.stackTraceLimit = 50;
const fs = require('fs');
//

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2015, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2015, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -30,27 +30,34 @@
* The ROWIDs of the changed records are returned. This is how to get
* the 'last insert id' of multiple rows. For a single row, use "lastRowid".
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
async function run() {

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2018, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2018, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -32,30 +32,35 @@
* errors. However valid rows are part of a transaction that can be committed
* if desired.
*
* This example requires node-oracledb 2.2 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const demoSetup = require('./demosetup.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
const sql = "INSERT INTO no_em_childtab VALUES (:1, :2, :3)";
@ -64,10 +69,10 @@ const binds = [
[1016, 10, "Child 2 of Parent A"],
[1017, 10, "Child 3 of Parent A"],
[1018, 20, "Child 4 of Parent B"],
[1018, 20, "Child 4 of Parent B"], // duplicate key
[1018, 20, "Duplicate Child"], // duplicate key
[1019, 30, "Child 3 of Parent C"],
[1020, 40, "Child 4 of Parent D"],
[1021, 75, "Child 1 of Parent F"], // parent does not exist
[1021, 75, "Invalid Parent"], // parent does not exist
[1022, 40, "Child 6 of Parent D"]
];
@ -88,11 +93,23 @@ async function run() {
try {
connection = await oracledb.getConnection(dbConfig);
await demoSetup.setupEm(connection); // create the demo tables
await demoSetup.setupEm(connection); // create the demo table
const result = await connection.executeMany(sql, binds, options);
// Insert data
let result = await connection.executeMany(sql, binds, options);
console.log("Result is:", result);
// Show the invalid data that couldn't be inserted
console.log('Bad rows were:');
for (let i = 0; i < result.batchErrors.length; i++) {
console.log(binds[result.batchErrors[i].offset]);
}
// Show the rows that were successfully inserted
console.log('Table contains:');
result = await connection.execute(`select * from no_em_childtab order by childid`);
console.log(result.rows);
} catch (err) {
console.error(err);
} finally {

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2018, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2018, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -28,30 +28,35 @@
* DESCRIPTION
* executeMany() example of DML RETURNING that returns single values.
*
* This example requires node-oracledb 2.2 or later.
*
* This example uses Node 8's async/await syntax.
*
x *****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const demoSetup = require('./demosetup.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
const sql = "INSERT INTO no_em_tab VALUES (:1, :2) RETURNING ROWID, id, val INTO :3, :4, :5";
@ -80,7 +85,7 @@ async function run() {
try {
connection = await oracledb.getConnection(dbConfig);
await demoSetup.setupEm(connection); // create the demo tables
await demoSetup.setupEm(connection); // create the demo table
const result = await connection.executeMany(sql, binds, options);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2018, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2018, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -28,30 +28,35 @@
* DESCRIPTION
* executeMany() example of DML RETURNING that returns multiple values
*
* This example requires node-oracledb 2.2 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const demoSetup = require('./demosetup.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
const insertSql = "INSERT INTO no_em_tab VALUES (:1, :2)";
@ -96,7 +101,7 @@ async function run() {
try {
connection = await oracledb.getConnection(dbConfig);
await demoSetup.setupEm(connection); // create the demo tables
await demoSetup.setupEm(connection); // create the demo table
await connection.executeMany(insertSql, insertData, insertOptions);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2018, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2018, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -28,30 +28,35 @@
* DESCRIPTION
* Array DML example using executeMany() with bind-by-name syntax.
*
* This example requires node-oracledb 2.2 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const demoSetup = require('./demosetup.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
const sql = "INSERT INTO no_em_tab values (:a, :b)";
@ -80,7 +85,7 @@ async function run() {
try {
connection = await oracledb.getConnection(dbConfig);
await demoSetup.setupEm(connection); // create the demo tables
await demoSetup.setupEm(connection); // create the demo table
const result = await connection.executeMany(sql, binds, options);
console.log("Result is:", result);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2018, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2018, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -28,30 +28,35 @@
* DESCRIPTION
* Array DML example using executeMany() with bind by position.
*
* This example requires node-oracledb 2.2 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const demoSetup = require('./demosetup.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
const sql = "INSERT INTO no_em_tab values (:1, :2)";
@ -80,7 +85,7 @@ async function run() {
try {
connection = await oracledb.getConnection(dbConfig);
await demoSetup.setupEm(connection); // create the demo tables
await demoSetup.setupEm(connection); // create the demo table
const result = await connection.executeMany(sql, binds, options);
console.log("Result is:", result);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2018, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2018, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -31,30 +31,35 @@
* Note that when OUT binds are used with PL/SQL, there may be no performance
* advantages compared with repeating calls to execute().
*
* This example requires node-oracledb 2.2 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const demoSetup = require('./demosetup.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
const sql = "BEGIN no_em_proc(:1, :2, :3); END;";
@ -81,7 +86,7 @@ async function run() {
try {
connection = await oracledb.getConnection(dbConfig);
await demoSetup.setupEm(connection); // create the demo tables
await demoSetup.setupEm(connection); // create the demo table
const result = await connection.executeMany(sql, binds, options);
console.log("Result is:", result);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2018, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2018, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -29,30 +29,35 @@
* executeMany() example showing dmlRowCounts.
* For this example, there no commit so it is re-runnable.
*
* This example requires node-oracledb 2.2 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const demoSetup = require('./demosetup.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
const sql = "DELETE FROM no_em_childtab WHERE parentid = :1";
@ -71,7 +76,7 @@ async function run() {
try {
connection = await oracledb.getConnection(dbConfig);
await demoSetup.setupEm(connection); // create the demo tables
await demoSetup.setupEm(connection); // create the demo table
const result = await connection.executeMany(sql, binds, options);
console.log("Result is:", result);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2015, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2015, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -28,31 +28,40 @@
* DESCRIPTION
* Sets connection metadata for end-to-end tracing and client authorization.
*
* While the script sleeps (keeping the connection open), use SQL*Plus as a privileged user to execute:
* SELECT username, client_identifier, action, module FROM v$session WHERE username IS NOT NULL;
* The end-to-end tracing attributes are shown in various other DBA views and in Enterprise Manager.
* While the script sleeps (keeping the connection open), use SQL*Plus as a
* privileged user to execute the SQL statement displayed.
*
* This example uses Node 8's async/await syntax.
* The end-to-end tracing attributes are shown in various other DBA views and
* in Enterprise Manager.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
async function run() {
@ -68,7 +77,7 @@ async function run() {
connection.module = "End-to-end example";
connection.action = "Query departments";
console.log("Use SQL*Plus as SYSTEM (or ADMIN for Oracle Cloud databases) to execute the query:");
console.log("Use SQL*Plus as SYSTEM (or ADMIN for Oracle Autonomous Database) to execute the query:");
console.log(" SELECT username, client_identifier, action, module FROM v$session WHERE username = UPPER('" + dbConfig.user + "');");
// Sleep 10 seconds to keep the connection open. This allows

View File

@ -26,36 +26,40 @@
* example.js
*
* DESCRIPTION
* A basic node-oracledb example using Node.js 8's async/await syntax.
* A basic node-oracledb example.
*
* For connection pool examples see connectionpool.js and webapp.js
* For a ResultSet example see resultset1.js
* For a query stream example see selectstream.js
*
* This example requires node-oracledb 5 or later.
*
*****************************************************************************/
// Using a fixed Oracle time zone helps avoid machine and deployment differences
process.env.ORA_SDTZ = 'UTC';
'use strict';
Error.stackTraceLimit = 50;
const fs = require('fs');
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
async function run() {
@ -134,15 +138,6 @@ async function run() {
console.log("Query results: ");
console.dir(result.rows, { depth: null });
//
// Show the date. The value of ORA_SDTZ affects the output
//
sql = `SELECT TO_CHAR(CURRENT_DATE, 'DD-Mon-YYYY HH24:MI') AS CD FROM DUAL`;
result = await connection.execute(sql, binds, options);
console.log("Current date query results: ");
console.log(result.rows[0]['CD']);
} catch (err) {
console.error(err);
} finally {

View File

@ -1,95 +0,0 @@
/* Copyright (c) 2015, 2022, Oracle and/or its affiliates. */
/******************************************************************************
*
* This software is dual-licensed to you under the Universal Permissive License
* (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
* 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
* either license.
*
* If you elect to accept the software under the Apache License, Version 2.0,
* the following applies:
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://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.
*
* NAME
* fetchinfo.js
*
* DESCRIPTION
* Show how numbers and dates can be returned as strings using fetchAsString
* and fetchInfo
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const demoSetup = require('./demosetup.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
}
oracledb.fetchAsString = [ oracledb.NUMBER ]; // any number queried will be returned as a string
async function run() {
let connection;
try {
connection = await oracledb.getConnection(dbConfig);
await demoSetup.setupBf(connection); // create the demo table
const result = await connection.execute(
`SELECT id, farmer, picked, weight
FROM no_banana_farmer
WHERE id = :id`,
[2],
{
fetchInfo :
{
"PICKED": { type : oracledb.STRING }, // return the date as a string
"WEIGHT": { type : oracledb.DEFAULT } // override oracledb.fetchAsString
}
});
console.log(result.rows);
} catch (err) {
console.error(err);
} finally {
if (connection) {
try {
await connection.close();
} catch (err) {
console.error(err);
}
}
}
}
run();

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2019, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2019, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -29,31 +29,43 @@
* Shows PL/SQL 'Implict Results' returning multiple query results
* from PL/SQL code.
*
* This example requires node-oracledb 4.0 or later, Oracle Database
* 12c or later, and Oracle Client 12c libraries or later.
*
* This example uses Node 8's async/await syntax.
* This example requires Oracle Database 12c or later. When using
* node-oracledb Thick mode, Oracle Client 12c libraries or later are also
* required.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const demoSetup = require('./demosetup.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
if (oracledb.oracleClientVersion < 1200000000) {
throw new Error('Implicit Results requires Oracle Client libraries 12c or greater');
}
}
oracledb.outFormat = oracledb.OUT_FORMAT_OBJECT;
@ -64,6 +76,9 @@ async function run() {
try {
connection = await oracledb.getConnection(dbConfig);
if (connection.oracleServerVersion < 1200000000) {
throw new Error('Implicit Results requires Oracle Database 12c or greater');
}
await demoSetup.setupBf(connection); // create the demo table

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2015, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2015, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -30,28 +30,34 @@
*
* To insert many records at a time see em_insert1.js
*
* This example requires node-oracledb 4.2 or later.
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
async function run() {

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2015, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2015, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -28,33 +28,40 @@
* DESCRIPTION
* Show the auto commit behavior.
*
* By default, node-oracledb does not commit on execute.
* The driver also has commit() and rollback() methods to explicitly control transactions.
* By default, node-oracledb does not commit on execute. The driver also has
* commit() and rollback() methods to explicitly control transactions.
*
* Note: regardless of the auto commit mode, any open transaction
* will be rolled back when a connection is closed.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
async function run() {

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2021, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2021, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -26,30 +26,37 @@
* lastinsertid.js
*
* DESCRIPTION
* Example of inserting a row and getting it's ROWID.
* Example of inserting a row and getting its ROWID.
* To return application generated identifiers, see dmlrupd.js.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
async function run() {

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2016, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2016, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -33,30 +33,36 @@
* 4) Querying a LOB and binding using PL/SQL IN OUT bind
* 5) PL/SQL OUT bind followed by PL/SQL IN OUT bind
*
* This example requires node-oracledb 1.13 or later.
*
* This example uses Node 8's async/await syntax.
*
******************************************************************************/
'use strict';
Error.stackTraceLimit = 50;
const fs = require('fs');
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const demoSetup = require('./demosetup.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
const clobOutFileName1 = 'lobbindsout1.txt';

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2015, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2015, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -36,30 +36,36 @@
* and V8 handle large data in memory, and on your streaming and
* performance requirements.
*
* This example requires node-oracledb 1.12 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
'use strict';
Error.stackTraceLimit = 50;
const fs = require('fs');
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const demoSetup = require('./demosetup.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
oracledb.autoCommit = true; // for ease of demonstration only

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2015, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2015, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -30,28 +30,36 @@
*
* For smaller LOBs you will probably prefer the method shown in lobinsert1.js
*
* This example requires node-oracledb 1.12 or later.
*
*****************************************************************************/
'use strict';
Error.stackTraceLimit = 50;
const fs = require('fs');
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const demoSetup = require('./demosetup.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
const inFileName = 'clobexample.txt'; // the file with text to be inserted into the database

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2016, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2016, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -32,30 +32,36 @@
* You may prefer the method shown in lobinsert2.js, which inserts
* directly into the table.
*
* This example requires node-oracledb 1.12 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
'use strict';
Error.stackTraceLimit = 50;
const fs = require('fs');
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const demoSetup = require('./demosetup.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
const inFileName = 'clobexample.txt'; // the file with text to be inserted into the database

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2016, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2016, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -32,30 +32,36 @@
* Smaller amounts of data can be passed directly to PL/SQL without
* needed a temporary LOB. See lobbinds.js
*
* This example requires node-oracledb 1.12.1 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
'use strict';
Error.stackTraceLimit = 50;
const fs = require('fs');
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const demoSetup = require('./demosetup.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
const inFileName = 'clobexample.txt'; // the file with text to be inserted into the database

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2016, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2016, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -31,38 +31,46 @@
*
* 'Large' LOBs should be streamed as shown in lobstream1.js
*
* This example requires node-oracledb 1.13 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
'use strict';
Error.stackTraceLimit = 50;
const fs = require('fs');
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const demoSetup = require('./demosetup.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
const blobOutFileName = 'lobselectout.jpg'; // file to write the BLOB to
// force all queried CLOBs to be returned as Strings
// (An alternative is to use a fetch type handler)
oracledb.fetchAsString = [ oracledb.CLOB ];
// force all queried BLOBs to be returned as Buffers
// (An alternative is to use a fetch type handler)
oracledb.fetchAsBuffer = [ oracledb.BLOB ];
async function run() {
@ -76,13 +84,25 @@ async function run() {
let result;
// An alternative to oracledb.fetchAsString and oracledb.fetchAsBuffer is
// to pass the execute() option fetchTypeHandler and in it tell the
// database to return any LOB column as a string or buffer, not as a Lob
// object
/*
function fth(metaData) {
if (metaData.dbType === oracledb.DB_TYPE_CLOB) {
return {type: oracledb.DB_TYPE_VARCHAR};
} else if (metaData.dbType === oracledb.DB_TYPE_BLOB) {
return {type: oracledb.DB_TYPE_LONG_RAW};
}
};
*/
// Fetch a CLOB
result = await connection.execute(
`SELECT c FROM no_lobs WHERE id = :idbv`,
[1]
// An alternative to oracledb.fetchAsString is to pass execute()
// options and use fetchInfo on the column:
//, { fetchInfo: {"C": {type: oracledb.STRING}} }
[1],
// { fetchTypeHandler: fth } // alternative to using oracledb.fetchAsString
);
if (result.rows.length === 0)
@ -96,9 +116,8 @@ async function run() {
// Fetch a BLOB
result = await connection.execute(
`SELECT b FROM no_lobs WHERE id = :idbv`,
[2]
// An alternative to oracledb.fetchAsBuffer is to use fetchInfo on the column:
// , { fetchInfo: {"B": {type: oracledb.BUFFER}} }
[2],
// { fetchTypeHandler: fth } // alternative to using oracledb.fetchAsBuffer
);
if (result.rows.length === 0)

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2015, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2015, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -28,30 +28,36 @@
* DESCRIPTION
* SELECTs a CLOB and a BLOB and streams to files.
*
* This example requires node-oracledb 1.12 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
'use strict';
Error.stackTraceLimit = 50;
const fs = require('fs');
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const demoSetup = require('./demosetup.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
// Stream a LOB to a file

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2016, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2016, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -28,30 +28,35 @@
* DESCRIPTION
* SELECTs a CLOB, streams it using 'data' events, and then displays it to the screen
*
* This example requires node-oracledb 1.12 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const demoSetup = require('./demosetup.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
async function run() {
@ -91,7 +96,8 @@ async function run() {
});
clob.on('data', (chunk) => {
// Build up the string. For larger LOBs you might want to print or use each chunk separately
// Build up the string. For larger LOBs you might want to print or use
// each chunk separately
// console.log("clob.on 'data' event. Got %d bytes of data", chunk.length);
myclob += chunk; // or use Buffer.concat() for BLOBS
});

View File

@ -0,0 +1,98 @@
/* Copyright (c) 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
* This software is dual-licensed to you under the Universal Permissive License
* (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
* 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
* either license.
*
* If you elect to accept the software under the Apache License, Version 2.0,
* the following applies:
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://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.
*
* NAME
* lowercasecolumns.js
*
* DESCRIPTION
* Shows how a type handler can convert column names to lower case.
*
*****************************************************************************/
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
// Fetch each row as an object
oracledb.outFormat = oracledb.OUT_FORMAT_OBJECT;
// The fetch type handler is called once per column in the SELECT list.
// It converts each column name to lowercase.
function fth(metaData) {
metaData.name = metaData.name.toLowerCase();
}
async function run() {
let connection;
try {
connection = await oracledb.getConnection(dbConfig);
// Without the type handler the column names use the database casing
const sql = `SELECT 1 AS col1, 2 AS COL2 FROM dual`;
let result = await connection.execute(sql);
console.dir(result.rows, {depth: null});
// With the type handler the column names are converted to lowercase
result = await connection.execute(sql, [], { fetchTypeHandler: fth });
console.dir(result.rows, {depth: null});
} catch (err) {
console.error(err);
} finally {
if (connection) {
try {
await connection.close();
} catch (err) {
console.error(err);
}
}
}
}
run();

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2016, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2016, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -26,32 +26,37 @@
* metadata.js
*
* DESCRIPTION
* Shows default and extended query column metadata
*
* This example requires node-oracledb 1.10 or later.
*
* This example uses Node 8's async/await syntax.
* Shows query column metadata
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const demoSetup = require('./demosetup.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
async function run() {
@ -63,20 +68,12 @@ async function run() {
await demoSetup.setupBf(connection); // create the demo table
console.log('Default query metadata');
console.log('Query metadata');
let result = await connection.execute(
`SELECT id, farmer, picked
FROM no_banana_farmer`);
console.dir(result.metaData, { depth: null });
console.log('Extended query metadata');
result = await connection.execute(
`SELECT id, farmer, picked
FROM no_banana_farmer`,
{}, // no binds
{ extendedMetaData: true }); // enable the extra metadata
console.dir(result.metaData, { depth: null });
} catch (err) {
console.error(err);
} finally {

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2016, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2016, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -32,29 +32,34 @@
* that table and returns the values. The third procedure accepts
* arrays, and returns the values sorted by the beach name.
*
* This example requires node-oracledb 1.6 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
async function run() {

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2015, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2015, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -28,27 +28,34 @@
* DESCRIPTION
* Shows how to call a PL/SQL function.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
async function run() {

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2015, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2015, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -28,27 +28,34 @@
* DESCRIPTION
* Show calling a PL/SQL procedure and binding parameters in various ways.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
async function run() {

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2019, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2019, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -28,32 +28,31 @@
* DESCRIPTION
* Shows binding of PL/SQL RECORDS
*
* This example requires node-oracledb 4 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
'use strict';
const fs = require('fs');
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example requires node-oracledb Thick mode.
//
// Thick mode requires Oracle Client or Oracle Instant Client libraries. On
// Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
async function run() {
let connection, binds, options, result, obj;

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2019, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2019, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -28,32 +28,31 @@
* DESCRIPTION
* Shows binding a VARRAY of RECORD in PL/SQL
*
* This example requires node-oracledb 4 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
'use strict';
const fs = require('fs');
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example requires node-oracledb Thick mode.
//
// Thick mode requires Oracle Client or Oracle Instant Client libraries. On
// Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
async function run() {
let connection;

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2015, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2015, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -28,29 +28,34 @@
* DESCRIPTION
* Shows using a Buffer to insert and select a RAW.
*
* This example requires node-oracledb 1.2 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
async function run() {

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2015, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2015, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -29,28 +29,35 @@
* Shows using a ResultSet to fetch rows from a REF CURSOR using getRows().
* Streaming is also possible, see refcursortoquerystream.js
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const demoSetup = require('./demosetup.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
async function run() {
@ -103,7 +110,7 @@ async function run() {
const rows1 = await resultSet1.getRows(); // no parameter means get all rows
console.log(rows1);
await resultSet1.close(); // always close the ResultSet
await resultSet1.close(); // always close the ResultSet
//
// Fetch rows from a REF CURSOR using multiple getRows() calls to fetch

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2016, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2016, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -30,30 +30,35 @@
* This is an alternative means of processing instead of using
* resultSet.getRows() shown in refcursor.js.
*
* This example requires node-oracledb 1.9 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const demoSetup = require('./demosetup.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
async function run() {

View File

@ -28,30 +28,35 @@
* DESCRIPTION
* Executes a query and uses a ResultSet to fetch rows with getRow().
*
* This example requires node-oracledb 2.0.15 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const demoSetup = require('./demosetup.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
async function run() {

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2015, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2015, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -29,28 +29,35 @@
* Executes a query and uses a ResultSet to fetch batches of rows
* with getRows(). Also shows setting the fetch array size.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const demoSetup = require('./demosetup.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
// Number of rows to return from each call to getRows()

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2016, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2016, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -29,28 +29,35 @@
* Converts a ResultSet returned from execute() into a Readable Stream.
* This is an alternative to using resultset.getRows().
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const demoSetup = require('./demosetup.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
async function run() {

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2015, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2015, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -34,28 +34,35 @@
* prevent badly coded queries from over-consuming Node.js resources, or when
* the number of rows to be selected is a known, small value.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const demoSetup = require('./demosetup.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
const myoffset = 1; // number of rows to skip
@ -87,7 +94,7 @@ async function run() {
{ prefetchRows: mymaxnumrows + 1, fetchArraySize: mymaxnumrows }
);
console.log("Executed: " + sql);
console.log(`Executed: "${sql}" with offset ${myoffset} and maxnumrows ${mymaxnumrows}`);
console.log("Number of rows returned: " + result.rows.length);
console.log(result.rows);

View File

@ -32,30 +32,35 @@
* For a ResultSet example see resultset2.js
* For a query stream example see selectstream.js
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
'use strict';
const fs = require('fs');
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const demoSetup = require('./demosetup.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
async function run() {
@ -89,8 +94,8 @@ async function run() {
//, fetchArraySize: 100 // internal buffer allocation size for tuning
});
console.log(result.metaData); // [ { name: 'FARMER' }, { name: 'PICKED' }, { name: 'RIPENESS' } ]
console.log(result.rows); // [ [ 'Mindy', 2019-07-16T03:30:00.000Z, 'More Yellow than Green' ] ]
console.log("Query metadata:", result.metaData);
console.log("Query rows:", result.rows);
} catch (err) {
console.error(err);

View File

@ -29,30 +29,35 @@
* Executes queries to show array and object output formats.
* Gets results directly without using a ResultSet.
*
* This example uses Node 8's async/await syntax.
*
******************************************************************************/
'use strict';
const fs = require('fs');
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const demoSetup = require('./demosetup.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
// Oracledb properties are applicable to all connections and SQL

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2019, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2019, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -28,32 +28,29 @@
* DESCRIPTION
* Insert and query Oracle Spatial geometries.
*
* This example requires node-oracledb 4 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
'use strict';
const fs = require('fs');
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example requires node-oracledb Thick mode.
//
// On Windows and macOS Intel, you can specify the directory containing the
// Oracle Client Libraries at runtime, or before Node.js starts. On other
// platforms the system library search path must always be set before Node.js
// is started. See the node-oracledb installation documentation. If the
// search path is not correct, you will get a DPI-1047 error.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts);
// If each object's attributes are accessed multiple times, it may be more
// efficient to fetch as simple JavaScriptobjects.

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2015, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2015, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -31,32 +31,35 @@
*
* For JSON with older databases see selectjsonblob.js
*
* This example requires node-oracledb 5.1 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
}
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
oracledb.extendedMetaData = true;
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
async function run() {
@ -66,8 +69,11 @@ async function run() {
connection = await oracledb.getConnection(dbConfig);
if (connection.oracleServerVersion < 2100000000) {
throw new Error('This example requires Oracle Database 21.1 or later. Try selectjsonblob.js.');
console.log(connection.oracleServerVersion);
console.log(connection.thin);
if (!connection.thin && connection.oracleServerVersion < 2100000000) {
throw new Error('Running this example in Thick mode requires Oracle Database 21.1 or later. Try selectjsonblob.js.');
}
console.log('1. Creating Table');
@ -85,10 +91,10 @@ async function run() {
const inssql = `INSERT INTO no_purchaseorder (po_document) VALUES (:bv)`;
const data = { "userId": 1, "userName": "Anna", "location": "Australia" };
if (oracledb.oracleClientVersion >= 2100000000) {
if (connection.thin || oracledb.oracleClientVersion >= 2100000000) {
await connection.execute(inssql, { bv: { val: data, type: oracledb.DB_TYPE_JSON } });
} else {
// With older client versions, insert as a JSON string
// When Thick mode uses older client versions, insert as a JSON string
const s = JSON.stringify(data);
const b = Buffer.from(s, 'utf8');
await connection.execute(inssql, { bv: { val: b } });

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2015, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2015, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -34,30 +34,35 @@
* Requires Oracle Database 12.1.0.2 or later.
* See https://www.oracle.com/pls/topic/lookup?ctx=dblatest&id=ADJSN
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
}
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
oracledb.extendedMetaData = true;
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
async function run() {
@ -89,7 +94,8 @@ async function run() {
const inssql = `INSERT INTO no_purchaseorder_b (po_document) VALUES (:bv)`;
const data = { "userId": 1, "userName": "Anna", "location": "Australia" };
if (oracledb.oracleClientVersion >= 2100000000 && connection.oracleServerVersion >= 2100000000) {
if ((connection.thin || oracledb.oracleClientVersion >= 2100000000)
&& connection.oracleServerVersion >= 2100000000) {
// Take advantage of direct binding of JavaScript objects
await connection.execute(inssql, { bv: { val: data, type: oracledb.DB_TYPE_JSON } });
} else {

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2020, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2020, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -29,27 +29,34 @@
* An example of querying nested cursors that shows names of people living in
* countries.
*
* This example requires node-oracledb 5.0.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
async function run() {

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2019, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2019, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -29,32 +29,31 @@
* Insert and query a named Oracle database object.
* Shows various ways to work with objects.
*
* This example requires node-oracledb 4 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
'use strict';
const fs = require('fs');
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example requires node-oracledb Thick mode.
//
// Thick mode requires Oracle Client or Oracle Instant Client libraries. On
// Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
// If each object's attributes are accessed multiple times, it may be more
// efficient to fetch as simple JavaScriptobjects.

View File

@ -28,30 +28,35 @@
* DESCRIPTION
* Executes a basic query using a Readable Stream.
*
* This example requires node-oracledb 1.8 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const demoSetup = require('./demosetup.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
async function run() {

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2019, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2019, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -28,32 +28,31 @@
* DESCRIPTION
* Shows inserting and selecting from a VARRAY column
*
* This example requires node-oracledb 4 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
'use strict';
const fs = require('fs');
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example requires node-oracledb Thick mode.
//
// Thick mode requires Oracle Client or Oracle Instant Client libraries. On
// Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
async function run() {
let connection;

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2018, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2018, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -42,31 +42,36 @@
* The function initSession() will be called just once per connection
* in the pool.
*
* This example requires node-oracledb 3.1 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const http = require('http');
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const httpPort = 7000;
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
// initSession() will be invoked internally when each brand new pooled
@ -77,8 +82,15 @@ if (libPath && fs.existsSync(libPath)) {
// If you have multiple SQL statements to execute, put them in a
// single, anonymous PL/SQL block for efficiency.
function initSession(connection, requestedTag, callbackFn) {
console.log('In initSession');
connection.execute(`ALTER SESSION SET TIME_ZONE = 'UTC'`, callbackFn);
// Your session initialization code would be here. This example just queries
// the session id to show that the callback is invoked once per session.
connection.execute(
`SELECT SYS_CONTEXT('USERENV','SID') FROM DUAL`,
function(err, result) {
const sid = result.rows[0][0]; // session id
console.log(`initSession invoked for session ${sid}`);
callbackFn();
});
}
async function init() {
@ -113,8 +125,9 @@ async function handleRequest(request, response) {
try {
// Get a connection from the default connection pool
connection = await oracledb.getConnection();
const result = await connection.execute(`SELECT TO_CHAR(CURRENT_DATE, 'DD-Mon-YYYY HH24:MI') FROM DUAL`);
console.log(result.rows[0][0]);
const sql = `SELECT CURRENT_TIMESTAMP, SYS_CONTEXT('USERENV','SID') FROM DUAL`;
const result = await connection.execute(sql);
console.log(`Query at time ${result.rows[0][0]} used session ${result.rows[0][1]}`);
} catch (err) {
console.error(err.message);
} finally {

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2019, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2019, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -45,32 +45,33 @@
* send 20 requests with a concurrency of 4:
* ab -n 20 -c 4 http://127.0.0.1:7000/
*
* This example requires node-oracledb 3.1 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const http = require('http');
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const httpPort = 7000;
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example requires node-oracledb Thick mode.
//
// Thick mode requires Oracle Client or Oracle Instant Client libraries. On
// Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
// initSession() will be invoked internally when each brand new pooled
// connection is first used, or when a getConnection() call requests a

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2018, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2018, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -45,32 +45,33 @@
* send 20 requests with a concurrency of 4:
* ab -n 20 -c 4 http://127.0.0.1:7000/
*
* This example requires node-oracledb 3.1 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const http = require('http');
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const httpPort = 7000;
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example requires node-oracledb Thick mode.
//
// Thick mode requires Oracle Client or Oracle Instant Client libraries. On
// Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
// initSession() will be invoked internally when each brand new pooled
// connection is first used, or when a getConnection() call requests a

View File

@ -28,34 +28,35 @@
* DESCRIPTION
* Basic Simple Oracle Document Access (SODA) example.
*
* Requires Oracle Database and Client 18.3, or higher.
* Requires Oracle Database and Oracle Client 18.3, or higher.
* The user must have been granted the SODA_APP and CREATE TABLE privileges.
* https://node-oracledb.readthedocs.io/en/latest/user_guide/soda.html#sodaoverview
*
* This example requires node-oracledb 3.0 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example requires node-oracledb Thick mode.
//
// Thick mode requires Oracle Client or Oracle Instant Client libraries. On
// Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
// The general recommendation for simple SODA usage is to enable autocommit
oracledb.autoCommit = true;

128
examples/typehandlerdate.js Normal file
View File

@ -0,0 +1,128 @@
/* Copyright (c) 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
* This software is dual-licensed to you under the Universal Permissive License
* (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
* 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
* either license.
*
* If you elect to accept the software under the Apache License, Version 2.0,
* the following applies:
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://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.
*
* NAME
* typehandlerdate.js
*
* DESCRIPTION
* Show how a type handler can format a queried date in a locale-specific
* way.
*
*****************************************************************************/
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
// The fetch type handler is called once per column in the SELECT list.
// If the metadata name & type tests are satified, then the returned
// converter function is enabled for that column. Data in this column will
// be processed by the converter function before it is returned to the
// application.
function fth(metaData) {
if (metaData.name == 'D_COL' && metaData.dbType === oracledb.DB_TYPE_DATE) {
return {converter: formatDate};
}
}
// Format dates using a German display format
function formatDate(val) {
if (val !== null) {
val = val.toLocaleString('de-DE');
}
return val;
}
async function run() {
let connection;
try {
connection = await oracledb.getConnection(dbConfig);
console.log('1. Creating Table');
try {
await connection.execute(`DROP TABLE no_typehandler_tab`);
} catch (e) {
if (e.errorNum != 942)
console.error(e);
}
await connection.execute(
`CREATE TABLE no_typehandler_tab (d_col DATE)`);
const data = new Date(1995, 11, 17); // 17th Dec 1995
console.log('2. Inserting date ' + data);
const inssql = `INSERT INTO no_typehandler_tab (d_col) VALUES (:bv)`;
await connection.execute(inssql, { bv: data });
console.log('3. Selecting the date');
const result = await connection.execute(
"select d_col from no_typehandler_tab",
[],
{ fetchTypeHandler: fth }
);
console.log(`Column ${result.metaData[0].name} is formatted as ${result.rows[0][0]}`);
} catch (err) {
console.error(err);
} finally {
if (connection) {
try {
await connection.close();
} catch (err) {
console.error(err);
}
}
}
}
run();

130
examples/typehandlernum.js Normal file
View File

@ -0,0 +1,130 @@
/* Copyright (c) 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
* This software is dual-licensed to you under the Universal Permissive License
* (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
* 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
* either license.
*
* If you elect to accept the software under the Apache License, Version 2.0,
* the following applies:
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://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.
*
* NAME
* typehandlernum.js
*
* DESCRIPTION
* Show how a type handler can format a queried number in a locale-specific
* way.
*
*****************************************************************************/
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
// The fetch type handler is called once per column in the SELECT list.
// If the metadata name & type tests are satified, then the returned
// converter function is enabled for that column. Data in this column will
// be processed by the converter function before it is returned to the
// application.
function fth(metaData) {
if (metaData.name == 'N_COL' && metaData.dbType === oracledb.DB_TYPE_NUMBER) {
return {converter: formatNumber};
}
}
// Format numbers using a German display format with "." as the thousands
// separator and "," as the decimal separator
function formatNumber(val) {
if (val !== null) {
val = val.toLocaleString('de-DE');
}
return val;
}
async function run() {
let connection;
try {
connection = await oracledb.getConnection(dbConfig);
console.log('1. Creating Table');
try {
await connection.execute(`DROP TABLE no_typehandler_tab`);
} catch (e) {
if (e.errorNum != 942)
console.error(e);
}
await connection.execute(
`CREATE TABLE no_typehandler_tab (n_col NUMBER)`);
const data = 123456.78;
console.log('2. Inserting number ' + data);
const inssql = `INSERT INTO no_typehandler_tab (n_col) VALUES (:bv)`;
await connection.execute(inssql, { bv: data });
console.log('3. Selecting the number');
const result = await connection.execute(
"select n_col from no_typehandler_tab",
[],
{ fetchTypeHandler: fth }
);
console.log(`Column ${result.metaData[0].name} is formatted as ${result.rows[0][0]}`);
} catch (err) {
console.error(err);
} finally {
if (connection) {
try {
await connection.close();
} catch (err) {
console.error(err);
}
}
}
}
run();

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2015, 2022, Oracle and/or its affiliates. */
/* Copyright (c) 2015, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
@ -28,29 +28,34 @@
* DESCRIPTION
* Shows the node-oracledb version attributes
*
* This example requires node-oracledb 2.2 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
const fs = require('fs');
'use strict';
Error.stackTraceLimit = 50;
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
console.log("Run at: " + new Date());
@ -60,8 +65,10 @@ console.log("Node-oracledb version:", oracledb.versionString); // version (inclu
// console.log("Node-oracledb version:", oracledb.version); // numeric version format is useful for comparisons
// console.log("Node-oracledb version suffix:", oracledb.versionSuffix); // e.g. "-beta.1", or empty for production releases
console.log("Oracle Client library version:", oracledb.oracleClientVersionString);
//console.log("Oracle Client library version:", oracledb.oracleClientVersion); // numeric version format
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
console.log("Oracle Client library version:", oracledb.oracleClientVersionString);
// console.log("Oracle Client library version:", oracledb.oracleClientVersion); // numeric version format
}
async function run() {
@ -73,6 +80,12 @@ async function run() {
console.log("Oracle Database version:", connection.oracleServerVersionString);
// console.log("Oracle Database version:", connection.oracleServerVersion); // numeric version format
const result = await connection.execute(
`SELECT UNIQUE CLIENT_DRIVER
FROM V$SESSION_CONNECT_INFO
WHERE SID = SYS_CONTEXT('USERENV', 'SID')`);
console.log(result.rows[0][0]);
} catch (err) {
console.error(err);
} finally {

View File

@ -37,12 +37,12 @@
*
* In production applications, set poolMin=poolMax (and poolIncrement=0)
*
* This example requires node-oracledb 5 or later.
*
* This example uses Node 8's async/await syntax.
*
*****************************************************************************/
'use strict';
Error.stackTraceLimit = 50;
// If you increase poolMax, you must increase UV_THREADPOOL_SIZE before Node.js
// starts its thread pool. If you set UV_THREADPOOL_SIZE too late, the value is
// ignored and the default size of 4 is used.
@ -51,25 +51,30 @@
// Note on Windows you must set the UV_THREADPOOL_SIZE environment variable before
// running your application.
const fs = require('fs');
const http = require('http');
const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');
const demoSetup = require('./demosetup.js');
// On Windows and macOS, you can specify the directory containing the Oracle
// Client Libraries at runtime, or before Node.js starts. On other platforms
// the system library search path must always be set before Node.js is started.
// See the node-oracledb installation documentation.
// If the search path is not correct, you will get a DPI-1047 error.
let libPath;
if (process.platform === 'win32') { // Windows
libPath = 'C:\\oracle\\instantclient_19_12';
} else if (process.platform === 'darwin') { // macOS
libPath = process.env.HOME + '/Downloads/instantclient_19_8';
}
if (libPath && fs.existsSync(libPath)) {
oracledb.initOracleClient({ libDir: libPath });
// This example runs in both node-oracledb Thin and Thick modes.
//
// Optionally run in node-oracledb Thick mode
if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
// Thick mode requires Oracle Client or Oracle Instant Client libraries.
// On Windows and macOS Intel you can specify the directory containing the
// libraries at runtime or before Node.js starts. On other platforms (where
// Oracle libraries are available) the system library search path must always
// include the Oracle library path before Node.js starts. If the search path
// is not correct, you will get a DPI-1047 error. See the node-oracledb
// installation documentation.
let clientOpts = {};
if (process.platform === 'win32') { // Windows
clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
}
const httpPort = 7000;

View File

@ -984,6 +984,16 @@ class Connection extends EventEmitter {
this._impl.setDbOp(value);
}
//---------------------------------------------------------------------------
// thin()
//
// return true, if driver mode is thin while acquiring connection
// return false, if driver mode is thick while acquiring connection
//---------------------------------------------------------------------------
get thin() {
return settings.thin;
}
//---------------------------------------------------------------------------
// ecid
//

View File

@ -156,6 +156,11 @@ module.exports = {
POOL_STATUS_CLOSED: 6002,
POOL_STATUS_RECONFIGURING: 6003,
// purity values
PURITY_DEFAULT: 0,
PURITY_NEW: 1,
PURITY_SELF: 2,
// AQ dequeue wait options
AQ_DEQ_NO_WAIT: 0,
AQ_DEQ_WAIT_FOREVER: 4294967295,

View File

@ -1,5 +1,5 @@
// Copyright (c) 2019, 2023, Oracle and/or its affiliates.
//
//----------------------------------------------------------------------------
//
// This software is dual-licensed to you under the Universal Permissive License

View File

@ -32,7 +32,6 @@ const util = require('util');
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;
@ -65,7 +64,6 @@ 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;
@ -82,15 +80,9 @@ 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;
@ -105,24 +97,64 @@ const ERR_MISSING_FILE = 91;
const ERR_INVALID_NUMBER_OF_CONNECTIONS = 92;
const ERR_EXEC_MODE_ONLY_FOR_DML = 95;
const ERR_INVALID_BIND_NAME = 97;
const ERR_WRONG_NUMBER_OF_POSITIONAL_BINDS = 98;
const ERR_BUFFER_LENGTH_INSUFFICIENT = 99;
const ERR_NCHAR_CS_NOT_SUPPORTED = 100;
const ERR_MISSING_CREDENTIALS = 101;
const ERR_UNEXPECTED_END_OF_DATA = 102;
const ERR_UNEXPECTED_MESSAGE_TYPE = 103;
const ERR_POOL_HAS_BUSY_CONNECTIONS = 104;
const ERR_NAN_VALUE = 105;
const ERR_INTERNAL = 106;
const ERR_INVALID_REF_CURSOR = 107;
const ERR_LOB_CLOSED = 108;
const ERR_INVALID_TYPE_NUM = 109;
const ERR_INVALID_ORACLE_TYPE_NUM = 110;
const ERR_UNEXPECTED_NEGATIVE_INTEGER = 111;
const ERR_INTEGER_TOO_LARGE = 112;
const ERR_UNEXPECTED_DATA = 113;
const ERR_OSON_FIELD_NAME_LIMITATION = 114;
const ERR_ORACLE_NUMBER_NO_REPR = 115;
const ERR_UNSUPPORTED_VERIFIER_TYPE = 116;
const ERR_INVALID_PRIVATE_KEY = 117;
const ERR_THIN_CONNECTION_ALREADY_CREATED = 118;
const ERR_UNSUPPORTED_CONVERSION = 119;
const ERR_FETCH_TYPE_HANDLER_RETURN_VALUE = 120;
const ERR_FETCH_TYPE_HANDLER_TYPE = 121;
const ERR_FETCH_TYPE_HANDLER_CONVERTER = 122;
const ERR_CALL_TIMEOUT_EXCEEDED = 123;
const ERR_EMPTY_CONNECTION_STRING = 125;
const ERR_OSON_VERSION_NOT_SUPPORTED = 126;
const ERR_UNKOWN_SERVER_SIDE_PIGGYBACK = 127;
// Oracle Net layer errors start from 500
const ERR_CONNECTION_CLOSED = 500;
const ERR_CONNECTION_LOSTCONTACT = 501;
const ERR_CONNECTION_INCOMPLETE = 503;
const ERR_PROXY_CONNECT_FAILURE = 504;
const ERR_TLS_INIT_FAILURE = 505;
const ERR_TLS_AUTH_FAILURE = 506;
const ERR_TLS_DNMATCH_FAILURE = 507;
const ERR_TLS_HOSTMATCH_FAILURE = 508;
const ERR_INVALID_PACKET = 509;
const ERR_CONNECTION_TIMEDOUT = 510;
const ERR_CONNECTION_REFUSED = 511;
const ERR_INVALID_ADDRESS = 512;
const ERR_CONNECTION_INBAND = 513;
const ERR_INVALID_CONNECT_STRING_SYNTAX = 514;
const ERR_INVALID_EZCONNECT_SYNTAX = 515;
const ERR_NO_CONFIG_DIR = 516;
const ERR_TNS_ENTRY_NOT_FOUND = 517;
const ERR_INVALID_SERVICE_NAME = 518;
const ERR_INVALID_SID = 519;
const ERR_TNS_NAMES_FILE_MISSING = 520;
const ERR_CONNECTION_EOF = 521;
// define mapping for ODPI-C errors that need to be wrapped with NJS errors
const adjustErrorXref = new Map();
adjustErrorXref.set("DPI-1010", ERR_CONNECTION_CLOSED);
adjustErrorXref.set("DPI-1040", ERR_LOB_CLOSED);
adjustErrorXref.set("DPI-1044", ERR_ORACLE_NUMBER_NO_REPR);
adjustErrorXref.set("DPI-1055", ERR_NAN_VALUE);
adjustErrorXref.set("DPI-1063", ERR_EXEC_MODE_ONLY_FOR_DML);
adjustErrorXref.set("DPI-1067", [ERR_CALL_TIMEOUT_EXCEEDED, "call timeout of ([0-9]+) ms"]);
@ -135,187 +167,243 @@ adjustErrorXref.set("ORA-25708", ERR_TOKEN_HAS_EXPIRED);
// define mapping for error messages
const messages = new Map();
messages.set(ERR_INVALID_CONNECTION,
'invalid connection');
messages.set(ERR_INVALID_POOL,
messages.set(ERR_INVALID_POOL, // NJS-002
'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,
messages.set(ERR_INVALID_CONNECTION, // NJS-003
'invalid connection');
messages.set(ERR_INVALID_PROPERTY_VALUE, // NJS-004
'invalid value for property "%s"');
messages.set(ERR_INVALID_PARAMETER_VALUE, // NJS-005
'invalid value for parameter %d');
messages.set(ERR_INVALID_PROPERTY_VALUE_IN_PARAM,
messages.set(ERR_INVALID_PROPERTY_VALUE_IN_PARAM, // NJS-007
'invalid value for "%s" in parameter %d');
messages.set(ERR_INVALID_NUMBER_OF_PARAMETERS,
messages.set(ERR_INVALID_NUMBER_OF_PARAMETERS, // NJS-009
'invalid number of parameters');
// used in C -- keep synchronized!
messages.set(ERR_UNSUPPORTED_DATA_TYPE,
messages.set(ERR_UNSUPPORTED_DATA_TYPE, // NJS-010
'unsupported data type %d in column %d');
messages.set(ERR_BIND_VALUE_AND_TYPE_MISMATCH,
messages.set(ERR_BIND_VALUE_AND_TYPE_MISMATCH, // NJS-011
'encountered bind value and type mismatch');
messages.set(ERR_INVALID_BIND_DATA_TYPE,
messages.set(ERR_INVALID_BIND_DATA_TYPE, // NJS-012
'encountered invalid bind data type in parameter %d');
messages.set(ERR_INVALID_BIND_DIRECTION,
messages.set(ERR_INVALID_BIND_DIRECTION, // NJS-013
'invalid bind direction');
messages.set(ERR_NO_TYPE_FOR_CONVERSION,
messages.set(ERR_NO_TYPE_FOR_CONVERSION, // NJS-015
'type was not specified for conversion');
// used in C -- keep synchronized!
messages.set(ERR_INSUFFICIENT_BUFFER_FOR_BINDS,
messages.set(ERR_INSUFFICIENT_BUFFER_FOR_BINDS, // NJS-016
'buffer is too small for OUT binds');
messages.set(ERR_BUSY_RS,
messages.set(ERR_BUSY_RS, // NJS-017
'concurrent operations on ResultSet are not allowed');
messages.set(ERR_INVALID_RS,
messages.set(ERR_INVALID_RS, // NJS-018
'invalid ResultSet');
messages.set(ERR_NOT_A_QUERY,
messages.set(ERR_NOT_A_QUERY, // NJS-019
'ResultSet cannot be returned for non-query statements');
messages.set(ERR_INVALID_TYPE_FOR_CONVERSION,
messages.set(ERR_INVALID_TYPE_FOR_CONVERSION, // NJS-021
'invalid type for conversion specified');
messages.set(ERR_INVALID_LOB,
messages.set(ERR_INVALID_LOB, // NJS-022
'invalid Lob');
messages.set(ERR_BUSY_LOB,
'concurrent operations on LOB are not allowed');
messages.set(ERR_BUSY_LOB, // NJS-023
'concurrent operations on a Lob are not allowed');
// used in C -- keep synchronized!
messages.set(ERR_INSUFFICIENT_MEMORY,
messages.set(ERR_INSUFFICIENT_MEMORY, // NJS-024
'memory allocation failed');
messages.set(ERR_INVALID_TYPE_FOR_ARRAY_BIND,
messages.set(ERR_INVALID_TYPE_FOR_ARRAY_BIND, // NJS-034
'data type is unsupported for array bind');
messages.set(ERR_REQUIRED_MAX_ARRAY_SIZE,
messages.set(ERR_REQUIRED_MAX_ARRAY_SIZE, // NJS-035
'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,
messages.set(ERR_INVALID_ARRAY_SIZE, // NJS-036
'length of given array is greater than "maxArraySize"');
messages.set(ERR_INCOMPATIBLE_TYPE_ARRAY_BIND, // NJS-037
'invalid data type at array index %d for bind ":%s"');
messages.set(ERR_CONN_REQUEST_TIMEOUT,
'connection request timeout. Request exceeded queueTimeout of %d');
messages.set(ERR_CANNOT_CONVERT_RS_TO_STREAM,
messages.set(ERR_CONN_REQUEST_TIMEOUT, // NJS-040
'connection request timeout. Request exceeded "queueTimeout" of %d');
messages.set(ERR_CANNOT_CONVERT_RS_TO_STREAM, // NJS-041
'cannot convert ResultSet to QueryStream after invoking methods');
messages.set(ERR_CANNOT_INVOKE_RS_METHODS,
messages.set(ERR_CANNOT_INVOKE_RS_METHODS, // NJS-042
'cannot invoke ResultSet methods after converting to QueryStream');
messages.set(ERR_RS_ALREADY_CONVERTED,
messages.set(ERR_RS_ALREADY_CONVERTED, // NJS-043
'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 Thick mode binary for Node.js %s');
messages.set(ERR_POOL_WITH_ALIAS_ALREADY_EXISTS,
messages.set(ERR_INVALID_BIND_UNIT, // NJS-044
'bind object must contain one of the following attributes: "dir", "type", "maxSize", or "val"');
messages.set(ERR_CANNOT_LOAD_BINARY, // NJS-045
'cannot load a node-oracledb Thick mode binary for Node.js. Please try using Thin mode. %s');
messages.set(ERR_POOL_WITH_ALIAS_ALREADY_EXISTS, // NJS-046
'pool alias "%s" already exists in the connection pool cache');
messages.set(ERR_POOL_WITH_ALIAS_NOT_FOUND,
messages.set(ERR_POOL_WITH_ALIAS_NOT_FOUND, // NJS-047
'pool alias "%s" not found in connection pool cache');
messages.set(ERR_INCOMPATIBLE_TYPE_ARRAY_INDEX_BIND,
messages.set(ERR_INCOMPATIBLE_TYPE_ARRAY_INDEX_BIND, // NJS-052
'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,
messages.set(ERR_MIXED_BIND, // NJS-055
'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,
messages.set(ERR_MISSING_MAX_SIZE_BY_POS, // NJS-056
'maxSize for bind position %d must be specified and be greater than zero');
messages.set(ERR_MISSING_MAX_SIZE_BY_NAME, // NJS-057
'maxSize for bind "%s" must be specified and greater than zero');
messages.set(ERR_MAX_SIZE_TOO_SMALL, // NJS-058
'maxSize of %d is too small for value of length %d in row %d');
messages.set(ERR_MISSING_TYPE_BY_POS,
messages.set(ERR_MISSING_TYPE_BY_POS, // NJS-059
'type must be specified for bind position %d');
messages.set(ERR_MISSING_TYPE_BY_NAME,
messages.set(ERR_MISSING_TYPE_BY_NAME, // NJS-060
'type must be specified for bind "%s"');
messages.set(ERR_INVALID_SUBSCR,
messages.set(ERR_INVALID_SUBSCR, // NJS-061
'invalid subscription');
messages.set(ERR_MISSING_SUBSCR_CALLBACK,
messages.set(ERR_MISSING_SUBSCR_CALLBACK, // NJS-062
'subscription notification callback missing');
messages.set(ERR_MISSING_SUBSCR_SQL,
messages.set(ERR_MISSING_SUBSCR_SQL, // NJS-063
'subscription notification SQL missing');
messages.set(ERR_POOL_CLOSING,
messages.set(ERR_POOL_CLOSING, // NJS-064
'connection pool is closing');
messages.set(ERR_POOL_CLOSED,
messages.set(ERR_POOL_CLOSED, // NJS-065
'connection pool was closed');
messages.set(ERR_INVALID_SODA_DOC_CURSOR,
messages.set(ERR_INVALID_SODA_DOC_CURSOR, // NJS-066
'invalid SODA document cursor');
messages.set(ERR_NO_BINARY_AVAILABLE,
messages.set(ERR_NO_BINARY_AVAILABLE, // NJS-067
'a pre-built node-oracledb Thick mode binary was not found for %s');
messages.set(ERR_INVALID_ERR_NUM,
messages.set(ERR_INVALID_ERR_NUM, // NJS-068
'invalid error number %d supplied');
messages.set(ERR_NODE_TOO_OLD,
messages.set(ERR_NODE_TOO_OLD, // NJS-069
'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_INVALID_AQ_MESSAGE, // NJS-070
'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_DBL_CONNECT_STRING, // NJS-075
'only one of "connectString" and "connectionString" can be used');
messages.set(ERR_QUEUE_MAX_EXCEEDED, // NJS-076
'connection request rejected. Pool queue length "queueMax" %d reached');
// used in C -- keep synchronized!
messages.set(ERR_UNSUPPORTED_DATA_TYPE_IN_JSON,
messages.set(ERR_UNSUPPORTED_DATA_TYPE_IN_JSON, // NJS-078
'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,
messages.set(ERR_DBL_USER, // NJS-080
'only one of "user" and "username" can be used');
messages.set(ERR_CONCURRENT_OPS, // NJS-081
'concurrent operations on a connection are disabled');
messages.set(ERR_POOL_RECONFIGURING,
messages.set(ERR_POOL_RECONFIGURING, // NJS-082
'connection pool is being reconfigured');
messages.set(ERR_POOL_STATISTICS_DISABLED,
'pool statistics not enabled');
messages.set(ERR_TOKEN_BASED_AUTH,
messages.set(ERR_POOL_STATISTICS_DISABLED, // NJS-083
'pool statistics are not enabled');
messages.set(ERR_TOKEN_BASED_AUTH, // NJS-084
'invalid access token');
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,
messages.set(ERR_POOL_TOKEN_BASED_AUTH, // NJS-085
'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, // NJS-086
'invalid standalone configuration with token-based authentication. The "externalAuth" attribute must be set to true');
messages.set(ERR_TOKEN_HAS_EXPIRED, // NJS-087
'access token has expired');
messages.set(ERR_NOT_IMPLEMENTED,
'%s is not implemented');
messages.set(ERR_INIT_ORACLE_CLIENT_ARGS,
'initOracleClient() was already called with different arguments!');
messages.set(ERR_MISSING_FILE,
messages.set(ERR_NOT_IMPLEMENTED, // NJS-089
'%s is not supported by node-oracledb in Thin mode');
messages.set(ERR_INIT_ORACLE_CLIENT_ARGS, // NJS-090
'initOracleClient() was already called with different arguments');
messages.set(ERR_MISSING_FILE, // NJS-091
'file %s is missing');
messages.set(ERR_INVALID_BIND_NAME,
'no bind placeholder named: :%s was found in the SQL text');
messages.set(ERR_INVALID_NUMBER_OF_CONNECTIONS,
'poolMax [%d] must be greater than or equal to poolMin [%d]');
messages.set(ERR_EXEC_MODE_ONLY_FOR_DML,
'setting batchErrors to true is only permitted with DML');
messages.set(ERR_POOL_HAS_BUSY_CONNECTIONS,
messages.set(ERR_INVALID_NUMBER_OF_CONNECTIONS, // NJS-092
'"poolMax" %d must be greater than or equal to "poolMin" %d');
messages.set(ERR_EXEC_MODE_ONLY_FOR_DML, // NJS-095
'setting "batchErrors" or "dmlRowCounts" to true is only permitted for DML statements');
messages.set(ERR_INVALID_BIND_NAME, // NJS-097
'no bind placeholder named ":%s" was found in the SQL text');
messages.set(ERR_WRONG_NUMBER_OF_POSITIONAL_BINDS, // NJS-098
'%s positional bind values are required but %s were provided');
messages.set(ERR_BUFFER_LENGTH_INSUFFICIENT, // NJS-099
'internal error: buffer of length %s insufficient to hold %s bytes');
messages.set(ERR_NCHAR_CS_NOT_SUPPORTED, // NJS-100
'national character set id %d is not supported by node-oracledb in Thin mode');
messages.set(ERR_MISSING_CREDENTIALS, // NJS-101
'no credentials specified');
messages.set(ERR_UNEXPECTED_END_OF_DATA, // NJS-102
'unexpected end of data: want %d bytes but only %d bytes are available');
messages.set(ERR_UNEXPECTED_MESSAGE_TYPE, // NJS-103
'unexpected message type %d received');
messages.set(ERR_POOL_HAS_BUSY_CONNECTIONS, // NJS-104
'connection pool cannot be closed because connections are busy');
messages.set(ERR_NAN_VALUE,
'value is not a number (NaN) and cannot be used in Oracle numbers');
messages.set(ERR_INVALID_REF_CURSOR,
messages.set(ERR_NAN_VALUE, // NJS-105
'value is not a number (NaN) and cannot be used in Oracle Database numbers');
messages.set(ERR_INTERNAL, // NJS-106
'internal error: %s');
messages.set(ERR_INVALID_REF_CURSOR, // NJS-107
'invalid cursor');
messages.set(ERR_LOB_CLOSED,
messages.set(ERR_LOB_CLOSED, // NJS-108
'LOB was already closed');
messages.set(ERR_INVALID_TYPE_NUM,
messages.set(ERR_INVALID_TYPE_NUM, // NJS-109
'invalid type number %d');
messages.set(ERR_INVALID_ORACLE_TYPE_NUM,
messages.set(ERR_INVALID_ORACLE_TYPE_NUM, // NJS-110
'invalid Oracle type number %d [csfrm: %d]');
messages.set(ERR_INVALID_PRIVATE_KEY,
messages.set(ERR_UNEXPECTED_NEGATIVE_INTEGER, // NJS-111
'internal error: read a negative integer when expecting a positive integer');
messages.set(ERR_INTEGER_TOO_LARGE, // NJS-112
'internal error: read integer of length %d when expecting integer of no more than length %d');
messages.set(ERR_UNEXPECTED_DATA, // NJS-113
'unexpected data received: %s');
messages.set(ERR_OSON_FIELD_NAME_LIMITATION, // NJS-114
'OSON field names may not exceed 255 UTF-8 encoded bytes');
messages.set(ERR_ORACLE_NUMBER_NO_REPR, // NJS-115
'value cannot be represented as an Oracle Database number');
messages.set(ERR_UNSUPPORTED_VERIFIER_TYPE, // NJS-116
'password verifier type 0x%s is not supported by node-oracledb in Thin mode');
messages.set(ERR_INVALID_PRIVATE_KEY, // NJS-117
'invalid private key. Headers and footers are not allowed');
messages.set(ERR_UNSUPPORTED_CONVERSION,
messages.set(ERR_THIN_CONNECTION_ALREADY_CREATED, // NJS-118
'node-oracledb Thick mode cannot be used because a Thin mode connection has already been created');
messages.set(ERR_UNSUPPORTED_CONVERSION, // NJS-119
'conversion from type %s to type %s is not supported');
messages.set(ERR_FETCH_TYPE_HANDLER_RETURN_VALUE,
messages.set(ERR_FETCH_TYPE_HANDLER_RETURN_VALUE, // NJS-120
'fetchTypeHandler return value must be an object');
messages.set(ERR_FETCH_TYPE_HANDLER_TYPE,
messages.set(ERR_FETCH_TYPE_HANDLER_TYPE, // NJS-121
'fetchTypeHandler return value attribute "type" must be a valid database type');
messages.set(ERR_FETCH_TYPE_HANDLER_CONVERTER,
messages.set(ERR_FETCH_TYPE_HANDLER_CONVERTER, // NJS-122
'fetchTypeHandler return value attribute "converter" must be a function');
messages.set(ERR_CALL_TIMEOUT_EXCEEDED,
messages.set(ERR_CALL_TIMEOUT_EXCEEDED, // NJS-123
'call timeout of %d ms exceeded');
messages.set(ERR_CONNECTION_CLOSED,
'connection to the Oracle Database was broken. End-of-file on communication channel');
messages.set(ERR_EMPTY_CONNECTION_STRING, // NJS-125
'"connectString" cannot be empty or undefined. Bequeath connections are not supported in Thin mode');
messages.set(ERR_OSON_VERSION_NOT_SUPPORTED, // NJS-126
'OSON version %s is not supported');
messages.set(ERR_UNKOWN_SERVER_SIDE_PIGGYBACK, // NJS-127
'internal error: unknown server side piggyback opcode %s');
// Oracle Net layer errors
messages.set(ERR_CONNECTION_CLOSED, // NJS-500
'connection to the Oracle Database was broken');
messages.set(ERR_CONNECTION_LOSTCONTACT, // NJS-501
'connection to host %s port %d terminated unexpectedly. (CONNECTION_ID=%s)\n%s');
messages.set(ERR_CONNECTION_INCOMPLETE, // NJS-503
'connection to host %s port %d could not be established. (CONNECTION_ID=%s)\n%s');
messages.set(ERR_PROXY_CONNECT_FAILURE, // NJS-504
'connection establishment through a web proxy at host %s port %d failed. (CONNECTION_ID=%s)\n%s');
messages.set(ERR_TLS_INIT_FAILURE, // NJS-505
'unable to initiate TLS connection. Please check if wallet credentials are valid');
messages.set(ERR_TLS_AUTH_FAILURE, // NJS-506
'connection to host %s port %d encountered TLS handshake failure. (CONNECTION_ID=%s)\n%s');
messages.set(ERR_TLS_DNMATCH_FAILURE, // NJS-507
'TLS detected an invalid certificate. Server DN in certificate does not match the specified DN');
messages.set(ERR_TLS_HOSTMATCH_FAILURE, // NJS-508
'TLS detected an invalid certificate. %s not present in certificate');
messages.set(ERR_INVALID_PACKET, // NJS-509
'internal error: invalid packet type or malformed packet received');
messages.set(ERR_CONNECTION_TIMEDOUT, // NJS-510
'connection to host %s port %d timed out. Request exceeded "%s" of %d seconds. (CONNECTION_ID=%s)');
messages.set(ERR_CONNECTION_REFUSED, // NJS-511
'connection to listener at host %s port %d was refused. (CONNECTION_ID=%s)\nCause: %s');
messages.set(ERR_INVALID_ADDRESS, // NJS-512
'invalid address specified. %s %s');
messages.set(ERR_CONNECTION_INBAND, // NJS-513
'error received through in-band notification: %s');
messages.set(ERR_INVALID_CONNECT_STRING_SYNTAX, // NJS-514
'syntax error in connection string');
messages.set(ERR_INVALID_EZCONNECT_SYNTAX, // NJS-515
'error in Easy Connect connection string: %s: %s');
messages.set(ERR_NO_CONFIG_DIR, // NJS-516
'no configuration directory set or available to search for tnsnames.ora');
messages.set(ERR_TNS_ENTRY_NOT_FOUND, // NJS-517
'cannot connect to Oracle Database. Unable to find "%s" in "%s"');
messages.set(ERR_INVALID_SERVICE_NAME, // NJS-518
'cannot connect to Oracle Database. Service "%s" is not registered with the listener at host %s port %s. (CONNECTION_ID=%s)');
messages.set(ERR_INVALID_SID, // NJS-519
'cannot connect to Oracle Database. SID "%s" is not registered with the listener at host %s port %s. (CONNECTION_ID=%s)');
messages.set(ERR_TNS_NAMES_FILE_MISSING, // NJS-520
'cannot connect to Oracle Database. File tnsnames.ora not found in %s');
messages.set(ERR_CONNECTION_EOF, // NJS-521
'connection to host %s port %d received end-of-file on communication channel. (CONNECTION_ID=%s)');
//-----------------------------------------------------------------------------
// assert()
@ -469,8 +557,7 @@ function throwErr() {
//-----------------------------------------------------------------------------
// throwNotImplemented()
//
// Throws an error with the given error number after formatting it with the
// given arguments.
// Throws an error that the feature is not supported in Thin mode
//-----------------------------------------------------------------------------
function throwNotImplemented(feature) {
throwErr(ERR_NOT_IMPLEMENTED, feature);
@ -517,7 +604,6 @@ function transformErr(err, fnOpt) {
// define exports
module.exports = {
ERR_MISSING_CALLBACK,
ERR_INVALID_POOL,
ERR_INVALID_CONNECTION,
ERR_INVALID_PROPERTY_VALUE,
@ -550,7 +636,6 @@ module.exports = {
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,
@ -567,15 +652,9 @@ module.exports = {
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,
@ -589,20 +668,58 @@ module.exports = {
ERR_MISSING_FILE,
ERR_INVALID_NUMBER_OF_CONNECTIONS,
ERR_EXEC_MODE_ONLY_FOR_DML,
ERR_POOL_HAS_BUSY_CONNECTIONS,
ERR_NAN_VALUE,
ERR_CONNECTION_CLOSED,
ERR_CONNECTION_LOSTCONTACT,
ERR_CONNECTION_INCOMPLETE,
ERR_PROXY_CONNECT_FAILURE,
ERR_TLS_INIT_FAILURE,
ERR_TLS_AUTH_FAILURE,
ERR_TLS_DNMATCH_FAILURE,
ERR_TLS_HOSTMATCH_FAILURE,
ERR_INVALID_PACKET,
ERR_CONNECTION_TIMEDOUT,
ERR_CONNECTION_REFUSED,
ERR_INVALID_ADDRESS,
ERR_CONNECTION_INBAND,
ERR_INVALID_CONNECT_STRING_SYNTAX,
ERR_INVALID_EZCONNECT_SYNTAX,
ERR_NO_CONFIG_DIR,
ERR_TNS_ENTRY_NOT_FOUND,
ERR_CONNECTION_EOF,
ERR_INVALID_BIND_NAME,
ERR_WRONG_NUMBER_OF_POSITIONAL_BINDS,
ERR_BUFFER_LENGTH_INSUFFICIENT,
ERR_NCHAR_CS_NOT_SUPPORTED,
ERR_MISSING_CREDENTIALS,
ERR_UNEXPECTED_END_OF_DATA,
ERR_UNEXPECTED_MESSAGE_TYPE,
ERR_POOL_HAS_BUSY_CONNECTIONS,
ERR_INTERNAL,
ERR_INVALID_REF_CURSOR,
ERR_UNSUPPORTED_VERIFIER_TYPE,
ERR_NAN_VALUE,
ERR_LOB_CLOSED,
ERR_ORACLE_NUMBER_NO_REPR,
ERR_INVALID_SERVICE_NAME,
ERR_INVALID_SID,
ERR_TNS_NAMES_FILE_MISSING,
ERR_INVALID_TYPE_NUM,
ERR_INVALID_ORACLE_TYPE_NUM,
ERR_UNEXPECTED_NEGATIVE_INTEGER,
ERR_INTEGER_TOO_LARGE,
ERR_UNEXPECTED_DATA,
ERR_OSON_FIELD_NAME_LIMITATION,
ERR_OSON_VERSION_NOT_SUPPORTED,
ERR_INVALID_PRIVATE_KEY,
ERR_THIN_CONNECTION_ALREADY_CREATED,
ERR_UNSUPPORTED_CONVERSION,
ERR_FETCH_TYPE_HANDLER_RETURN_VALUE,
ERR_FETCH_TYPE_HANDLER_TYPE,
ERR_FETCH_TYPE_HANDLER_CONVERTER,
ERR_CALL_TIMEOUT_EXCEEDED,
ERR_CONNECTION_CLOSED,
ERR_EMPTY_CONNECTION_STRING,
ERR_UNKOWN_SERVER_SIDE_PIGGYBACK,
ERR_CONNECTION_CLOSED_CODE: `${ERR_PREFIX}-${ERR_CONNECTION_CLOSED}`,
assert,
assertArgCount,
assertParamPropBool,

View File

@ -1,5 +1,5 @@
// Copyright (c) 2022, Oracle and/or its affiliates.
//
// Copyright (c) 2022, 2023, Oracle and/or its affiliates.
//----------------------------------------------------------------------------
//
// This software is dual-licensed to you under the Universal Permissive License

View File

@ -66,6 +66,7 @@ const defaultPoolAlias = 'default';
// save arguments for call to initOracleClient()
let _initOracleClientArgs;
let _thinDriverInitialized = false;
// Load the Oracledb binary
@ -109,6 +110,11 @@ function _initCLib() {
// top-level functions
function _initializeThinDriver() {
require('./thin');
_thinDriverInitialized = true;
}
//---------------------------------------------------------------------------
// _isPrivilege()
//
@ -172,6 +178,20 @@ async function _verifyOptions(options, inCreatePool) {
outOptions.connectString = options.connectionString;
}
// wallet password must be string
if (options.walletPassword !== undefined) {
errors.assertParamPropValue(typeof options.walletPassword === 'string', 1,
"walletPassword");
outOptions.walletPassword = options.walletPassword;
}
//wallet location must be a string
if (options.walletLocation !== undefined) {
errors.assertParamPropValue(typeof options.walletLocation === 'string', 1,
"walletLocation");
outOptions.walletLocation = options.walletLocation;
}
// edition must be a string
if (options.edition !== undefined) {
errors.assertParamPropValue(typeof options.edition === 'string', 1,
@ -208,6 +228,91 @@ async function _verifyOptions(options, inCreatePool) {
outOptions.poolAlias = options.poolAlias;
}
// configDir must be a string
if (options.configDir !== undefined) {
errors.assertParamPropValue(typeof options.configDir === 'string',
1, "configDir");
outOptions.configDir = options.configDir;
}
// sslServerServerCertDN must be a string
if (options.sslServerCertDN !== undefined) {
errors.assertParamPropValue(typeof options.sslServerCertDN === 'string',
1, "sslServerCertDN");
outOptions.sslServerCertDN = options.sslServerCertDN;
}
// sslServerServerDNMatch must be a boolean
if (options.sslServerDNMatch !== undefined) {
errors.assertParamPropValue(typeof options.sslServerDNMatch === 'boolean',
1, "sslServerDNMatch");
outOptions.sslServerDNMatch = options.sslServerDNMatch;
}
// httpsProxy must be a string
if (options.httpsProxy !== undefined) {
errors.assertParamPropValue(typeof options.httpsProxy === 'string',
1, "httpsProxy");
outOptions.httpsProxy = options.httpsProxy;
}
// httpsProxyPort must be an integer (>= 0)
if (options.httpsProxyPort !== undefined) {
errors.assertParamPropValue(Number.isInteger(options.httpsProxyPort) &&
options.httpsProxyPort >= 0, 1, "httpsProxyPort");
outOptions.httpsProxyPort = options.httpsProxyPort;
}
//retryCount must be an integer (>=0)
if (options.retryCount !== undefined) {
errors.assertParamPropValue(Number.isInteger(options.retryCount) &&
options.retryCount >= 0, 1, "retryCount");
outOptions.retryCount = options.retryCount;
}
//retryDelay must be an integer (>=0)
if (options.retryDelay !== undefined) {
errors.assertParamPropValue(Number.isInteger(options.retryDelay) &&
options.retryDelay >= 0, 1, "retryDelay");
outOptions.retryDelay = options.retryDelay;
}
// connectTimeout must be an integer (>= 0)
if (options.connectTimeout !== undefined) {
errors.assertParamPropValue(Number.isInteger(options.connectTimeout) &&
options.connectTimeout >= 0, 1, "connectTimeout");
outOptions.connectTimeout = options.connectTimeout;
}
// transportConnectTimeout must be an integer (>= 0)
if (options.transportConnectTimeout !== undefined) {
errors.assertParamPropValue(Number.isInteger(options.transportConnectTimeout) &&
options.transportConnectTimeout >= 0, 1, "transportConnectTimeout");
outOptions.transportConnectTimeout = options.transportConnectTimeout;
}
// expireTime must be an integer (>= 0)
if (options.expireTime !== undefined) {
errors.assertParamPropValue(Number.isInteger(options.expireTime) &&
options.expireTime >= 0, 1, "expireTime");
outOptions.expireTime = options.expireTime;
}
// sdu must be an integer (> 0)
if (options.sdu !== undefined) {
errors.assertParamPropValue(Number.isInteger(options.sdu) &&
options.sdu > 0, 1, "sdu");
outOptions.sdu = options.sdu;
}
// connectionIDPrefix must be a string
if (options.connectionIDPrefix !== undefined) {
errors.assertParamPropValue(typeof options.connectionIDPrefix === 'string',
1, "connectionIDPrefix");
outOptions.connectionIDPrefix = options.connectionIDPrefix;
}
// check pool specific options
if (inCreatePool) {
@ -437,8 +542,8 @@ async function createPool(options) {
}
// initialize the Oracle client, if necessary
if (_initOracleClientArgs === undefined) {
initOracleClient();
if (_initOracleClientArgs === undefined && !_thinDriverInitialized) {
_initializeThinDriver();
}
// Need to prevent another call in the same stack from succeeding, otherwise
@ -510,9 +615,10 @@ async function getConnection(a1) {
"events",
"externalAuth",
"stmtCacheSize");
if (_initOracleClientArgs === undefined) {
initOracleClient();
if (_initOracleClientArgs === undefined && !_thinDriverInitialized) {
_initializeThinDriver();
}
const conn = new Connection();
conn._impl = new impl.ConnectionImpl();
await conn._impl.connect(options);
@ -562,10 +668,13 @@ function initOracleClient(arg1) {
errors.assertParamPropString(options, 1, "errorUrl");
errors.assertParamPropString(options, 1, "driverName");
}
if (_thinDriverInitialized) {
errors.throwErr(errors.ERR_THIN_CONNECTION_ALREADY_CREATED);
}
if (_initOracleClientArgs === undefined) {
const oracledbCLib = _initCLib();
if (options.driverName === undefined)
options.driverName = constants.DEFAULT_DRIVER_NAME;
options.driverName = constants.DEFAULT_DRIVER_NAME + " thk";
if (options.errorUrl === undefined)
options.errorUrl = constants.DEFAULT_ERROR_URL;
try {
@ -580,6 +689,10 @@ function initOracleClient(arg1) {
} else if (!util.isDeepStrictEqual(_initOracleClientArgs, options)) {
errors.throwErr(errors.ERR_INIT_ORACLE_CLIENT_ARGS);
}
// driver mode initialization
// _initOracleClientArgs is populated and thin connection not created
settings.thin = false;
}
@ -934,14 +1047,14 @@ module.exports = {
get oracleClientVersion() {
if (_initOracleClientArgs === undefined) {
initOracleClient();
errors.throwNotImplemented("getting the Oracle Client version");
}
return settings.oracleClientVersion;
},
get oracleClientVersionString() {
if (_initOracleClientArgs === undefined) {
initOracleClient();
errors.throwNotImplemented("getting the Oracle Client version");
}
return settings.oracleClientVersionString;
},
@ -982,6 +1095,10 @@ module.exports = {
return settings.stmtCacheSize;
},
get thin() {
return settings.thin;
},
get version() {
return constants.VERSION_MAJOR * 10000 + constants.VERSION_MINOR * 100 +
constants.VERSION_PATCH;

View File

@ -312,6 +312,16 @@ class Pool extends EventEmitter {
return this._connectString;
}
//---------------------------------------------------------------------------
// thin()
//
// return true, if driver mode is thin while creating pool
// return false, if driver mode is thick while creating pool
//---------------------------------------------------------------------------
get thin() {
return settings.thin;
}
//---------------------------------------------------------------------------
// edition
//

View File

@ -1,4 +1,5 @@
// Copyright (c) 2021, 2022, Oracle and/or its affiliates.
// Copyright (c) 2021, 2023, Oracle and/or its affiliates.
//-----------------------------------------------------------------------------
//
// This software is dual-licensed to you under the Universal Permissive License
@ -25,6 +26,8 @@
'use strict';
const settings = require('./settings.js');
//-----------------------------------------------------------------------------
// class PoolStatistics
// collection of statistics metrics for Pool object
@ -75,6 +78,7 @@ class PoolStatistics {
this.stmtCacheSize = pool.stmtCacheSize;
this.user = pool.user;
this.threadPoolSize = process.env.UV_THREADPOOL_SIZE;
this.thin = settings.thin;
}
//---------------------------------------------------------------------------
@ -83,7 +87,9 @@ class PoolStatistics {
// To print the statistics metrics of the pool
//---------------------------------------------------------------------------
logStatistics() {
console.log('\nPool statistics:');
console.log('\nDriver:');
console.log('...thin mode:', this.thin);
console.log('Pool statistics:');
console.log('...gathered at:', new Date(this.gatheredDate).toISOString());
console.log('...up time (milliseconds):', this.upTime);
console.log('...up time from last reset (milliseconds)',

View File

@ -56,6 +56,7 @@ class Settings {
this.queueTimeout = 60000;
this.queueMax = 500;
this.stmtCacheSize = 30;
this.thin = true;
this.createFetchTypeMap(this.fetchAsString, this.fetchAsBuffer);
this.fetchTypeHandler = undefined;
}

679
lib/thin/connection.js Normal file
View File

@ -0,0 +1,679 @@
// Copyright (c) 2022, 2023, Oracle and/or its affiliates.
//-----------------------------------------------------------------------------
//
// This software is dual-licensed to you under the Universal Permissive License
// (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
// 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
// either license.
//
// If you elect to accept the software under the Apache License, Version 2.0,
// the following applies:
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://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 ConnectionImpl = require('../impl/connection.js');
const ThinResultSetImpl = require('./resultSet.js');
const ThinLobImpl = require("./lob.js");
const Protocol = require("./protocol/protocol.js");
const {NetworkSession:nsi, getConnectionInfo} = require("./sqlnet/networkSession.js");
const { Statement } = require("./statement");
const thinUtil = require('./util');
const sqlNetConstants = require('./sqlnet/constants.js');
const constants = require('../constants.js');
const protocolConstants = require('./protocol/constants.js');
const types = require('../types.js');
const errors = require("../errors.js");
const messages = require('./protocol/messages');
const finalizationRegistry = new global.FinalizationRegistry((heldValue) => {
heldValue.disconnect();
});
class ThinConnectionImpl extends ConnectionImpl {
/**
* Terminates the connection
*
* @return {Promise}
*/
async close() {
if (this._protocol.txnInProgress) {
await this.rollback();
}
this._protocol.callTimeout = 0; // not applicable for close
if (this._drcpEnabled) {
await this._sessRelease();
this._drcpEstablishSession = true;
}
if (this._pool && !this._dropSess) {
await this._pool.release(this);
} else {
if (!this._drcpEnabled) {
const message = new messages.LogOffMessage(this);
await this._protocol._processMessage(message);
}
this.nscon.disconnect();
}
}
async _sessRelease() {
const message = new messages.SessionReleaseMessage(this);
if (!this.isPooled()) {
message.sessReleaseMode = constants.DRCP_DEAUTHENTICATE;
}
await this._protocol._processMessage(message);
}
async commit() {
const message = new messages.CommitMessage(this);
await this._protocol._processMessage(message);
}
async breakExecution() {
await this._protocol.breakMessage();
}
_healthStatus() {
return this.nscon.recvInbandNotif();
}
isHealthy() {
try {
if (this.nscon.recvInbandNotif() === 0)
return true;
return false;
} catch {
return false;
}
}
isPooled() {
return (this._pool) ? true : false;
}
/**
*
* @param {object} params Configuration of the connection
*
* @return {Promise}
*/
async connect(params) {
if (params.password === undefined && params.token === undefined) {
errors.throwErr(errors.ERR_MISSING_CREDENTIALS);
} else if (!params.connectString) {
errors.throwErr(errors.ERR_EMPTY_CONNECTION_STRING);
}
this.sessionID = 0;
this.serialNum = 0;
this.autoCommit = false;
this.serverVersion = "";
this.statementCache = null;
this.currentSchema = "";
this.invokeSessionCallback = true;
this.statementCache = new Map();
this.statementCacheSize = params.stmtCacheSize;
this._numCursorsToClose = 0;
this._currentSchemaModified = false;
this._cursorsToClose = new Set();
this._tempLobsToClose = [];
this._tempLobsTotalSize = 0;
this._drcpEstablishSession = false;
this._cclass = null;
this._clientIdentifier = "";
this._clientIdentifierModified = false;
this._action = "";
this._actionModified = false;
this._dbOp = "";
this._dbOpModified = false;
this._clientInfo = "";
this._clientInfoModified = false;
this._module = "";
this._moduleModified = false;
this.serviceName = '';
this.remoteAddress = '';
this.privilege = params.privilege;
this.comboKey = null; // used in changePassword API
this.nscon = new nsi();
finalizationRegistry.register(this, this.nscon);
await this.nscon.connect(params);
this._connInfo = (this.isPooled()) ? params._connInfo.map((x) => x) :
await getConnectionInfo(params);
this._drcpEnabled = String(this._connInfo[0]).toLowerCase() === 'pooled';
this.serviceName = this._connInfo[2];
this.purity = this._connInfo[3] | constants.PURITY_DEFAULT;
this.remoteAddress = this.nscon.getOption(sqlNetConstants.REMOTEADDR);
this.connClass = params.connectionClass;
/*
* if drcp is used, use purity = NEW as the default purity for
* standalone connections and purity = SELF for connections that belong
* to a pool
*/
if (this.purity === constants.PURITY_DEFAULT && this._drcpEnabled) {
if (this.isPooled()) {
this.purity = constants.PURITY_SELF;
} else {
this.purity = constants.PURITY_NEW;
}
}
this._protocol = new Protocol(this);
try {
let message = new messages.ProtocolMessage(this);
await this._protocol._processMessage(message);
message = new messages.DataTypeMessage(this);
await this._protocol._processMessage(message);
message = new messages.AuthMessage(this, params);
await this._protocol._processMessage(message); // OSESSKEY
await this._protocol._processMessage(message); // OAUTH
} catch (err) {
this.nscon.disconnect();
throw err;
}
if (params.debugJDWP) {
this.jdwpData = Buffer.from(params.debugJDWP);
} else if (process.env.ORA_DEBUG_JDWP) {
this.jdwpData = Buffer.from(process.env.ORA_DEBUG_JDWP);
}
this._protocol.connInProgress = false;
}
//---------------------------------------------------------------------------
// Sets that a statement is no longer in use
//---------------------------------------------------------------------------
_returnStatement(statement) {
if (statement.bindInfoList) {
statement.bindInfoList.forEach(bindInfo => {
bindInfo.bindVar = null;
});
}
if (statement.queryVars) {
statement.queryVars.forEach(queryVar => {
queryVar.values.fill(null);
});
}
if (statement.returnToCache) {
statement.inUse = false;
this._adjustStatementCache();
} else if (statement.cursorId !== 0) {
this._addCursorToClose(statement);
}
}
//---------------------------------------------------------------------------
// Adds the cursors that needs to be closed to the _cursorsToClose set
//---------------------------------------------------------------------------
_addCursorToClose(stmt) {
if (stmt.cursorId > 0 && this._cursorsToClose.has(stmt.cursorId)) {
const reason = `attempt to close cursor ${stmt.cursorId} twice`;
errors.throwErr(errors.ERR_INTERNAL, reason);
}
if (this.statementCache.has(stmt.sql)) {
this.statementCache.delete(stmt.sql);
this._cursorsToClose.add(stmt.cursorId);
} else if (stmt.cursorId > 0) {
this._cursorsToClose.add(stmt.cursorId);
}
}
//---------------------------------------------------------------------------
// Adjusts the statement cache to remove least recently used statements
//---------------------------------------------------------------------------
_adjustStatementCache() {
while (this.statementCache.size >= this.statementCacheSize) {
let stmt = this.statementCache.get(this.statementCache.keys().next().value);
this.statementCache.delete(this.statementCache.keys().next().value);
if (stmt.inUse) {
stmt.returnToCache = false;
} else if (stmt.cursorId !== 0) {
this._addCursorToClose(stmt);
}
}
}
//---------------------------------------------------------------------------
// Parses the sql statement and puts it into cache if keepInStmtCache
// option is true
//---------------------------------------------------------------------------
_prepare(sql, options) {
let statement = this._getStatement(sql, options.keepInStmtCache);
statement.bufferRowIndex = 0;
statement.bufferRowCount = 0;
statement.lastRowIndex = 0;
statement.moreRowsToFetch = true;
return statement;
}
//---------------------------------------------------------------------------
// Binds the values by user to the statement object
//---------------------------------------------------------------------------
async _bind(stmt, variable, pos = 0) {
let bindInfoDict = stmt.bindInfoDict;
let bindInfoList = stmt.bindInfoList;
/*
* For PL/SQL blocks, if the size of a string or bytes object exceeds
* 32,767 bytes it is converted to a BLOB/CLOB; and conversion
* needs to be established as well to return the string in the way that
* the user expects to get it
*/
if (stmt.isPlSql && variable.maxSize > 32767) {
if (variable.type === types.DB_TYPE_RAW ||
variable.type === types.DB_TYPE_LONG_RAW) {
variable.type = types.DB_TYPE_BLOB;
} else if (variable.type._csfrm === protocolConstants.TNS_CS_NCHAR) {
variable.type = types.DB_TYPE_NCLOB;
} else {
variable.type = types.DB_TYPE_CLOB;
}
const maxSize = variable.maxSize;
delete variable.maxSize;
variable.outConverter = async function(val) {
if (val === null) {
return null;
}
let data = await val.getData();
let len = val._length;
if (data && len > maxSize) {
errors.throwErr(errors.ERR_INSUFFICIENT_BUFFER_FOR_BINDS);
}
return data;
};
}
if (variable.type === types.DB_TYPE_CLOB ||
variable.type === types.DB_TYPE_NCLOB ||
variable.type === types.DB_TYPE_BLOB) {
for (let [index, val] of variable.values.entries()) {
if (!(val instanceof ThinLobImpl)) {
if (val && val.length > 0) {
const lobImpl = new ThinLobImpl();
await lobImpl.create(this, variable.type);
await lobImpl.write(1, val);
variable.values[index] = lobImpl;
} else {
variable.values[index] = null;
}
}
}
}
if (variable.name) {
let normalizedName;
if (variable.name.startsWith('"') && variable.name.endsWith('"')) {
normalizedName = variable.name.substring(1, variable.name.length - 1);
} else {
normalizedName = variable.name.toUpperCase();
}
if (normalizedName.startsWith(':')) {
normalizedName = variable.name.substring(1);
}
if (bindInfoDict[normalizedName] === undefined) {
errors.throwErr(errors.ERR_INVALID_BIND_NAME, normalizedName);
}
bindInfoDict[normalizedName].forEach((bindInfo) => {
stmt._setVariable(bindInfo, variable);
});
} else {
let bindInfo = bindInfoList[pos - 1];
stmt._setVariable(bindInfo, variable);
}
}
//---------------------------------------------------------------------------
// _createResultSet()
//
// Creates a result set and performs any necessary initialization.
//---------------------------------------------------------------------------
_createResultSet(options, statement) {
const resultSet = new ThinResultSetImpl();
if (!statement) {
statement = new Statement();
}
resultSet._resultSetNew(this, statement, options);
if (statement.queryVars.length > 0) {
const metadata = thinUtil.getMetadataMany(statement.queryVars);
resultSet._setup(options, metadata);
}
return resultSet;
}
//---------------------------------------------------------------------------
// Prepares the sql given by user and binds the value to the statement object
//---------------------------------------------------------------------------
async _prepareAndBind(sql, binds, options, isParse = false) {
const stmt = this._prepare(sql, options);
let position = 0;
if (!isParse) {
const numBinds = stmt.bindInfoList.length;
const numVars = binds.length;
if (numBinds !== numVars) {
errors.throwErr(errors.ERR_WRONG_NUMBER_OF_POSITIONAL_BINDS, numBinds, numVars);
}
for (const variable of binds) {
await this._bind(stmt, variable, position + 1);
position += 1;
}
}
return stmt;
}
//---------------------------------------------------------------------------
// Clears the statement cache for the connection
//---------------------------------------------------------------------------
resetStatmentCache() {
this.statementCache.clear();
this._cursorsToClose.clear();
}
//---------------------------------------------------------------------------
// Parses the sql given by User
// calls the OAL8 RPC that parses the SQL statement and returns the metadata
// information for a statment.
//---------------------------------------------------------------------------
async getStatementInfo(sql) {
let options = {};
let result = {};
let statement = await this._prepareAndBind(sql, null, options, true);
options.connection = this;
// parse the statement (but not for DDL which doesn't support it)
if (!statement.isDdl) {
const message = new messages.ExecuteMessage(this, statement, options);
message.parseOnly = true;
await this._protocol._processMessage(message);
}
if (statement.numQueryVars > 0) {
result.metaData = thinUtil.getMetadataMany(statement.queryVars);
}
result.bindNames = Object.keys(statement.bindInfoDict);
result.statementType = statement.statementType;
return result;
}
//---------------------------------------------------------------------------
// Prepares the sql given by the user,
// calls the OAL8 RPC that executes a SQL statement and returns the results.
//---------------------------------------------------------------------------
async execute(sql, numIters, binds, options, executeManyFlag) {
const result = {};
if (executeManyFlag) {
return await this.executeMany(sql, numIters, binds, options);
}
const statement = await this._prepareAndBind(sql, binds, options);
// send the initial request to the database
const message = new messages.ExecuteMessage(this, statement, options);
message.numExecs = 1;
await this._protocol._processMessage(message);
statement.requiresFullExecute = false;
// if a define is required, send an additional request to the database
if (statement.requiresDefine && statement.sql) {
statement.requiresFullExecute = true;
await this._protocol._processMessage(message);
statement.requiresFullExecute = false;
statement.requiresDefine = false;
}
// process message results
if (statement.numQueryVars > 0) {
result.resultSet = message.resultSet;
} else {
statement.bufferRowIndex = 0;
let bindVars = thinUtil.getBindVars(statement);
let outBinds = thinUtil.getExecuteOutBinds(bindVars);
if (outBinds) {
result.outBinds = outBinds;
}
if (statement.isPlSql) {
if (options.implicitResultSet) {
result.implicitResults = options.implicitResultSet;
}
}
if (statement.lastRowid) {
result.lastRowid = statement.lastRowid;
delete statement.lastRowid;
}
if (statement.isPlSql) {
if (statement.rowCount) {
result.rowsAffected = statement.rowCount;
}
} else {
result.rowsAffected = statement.rowCount || 0;
}
if (statement.rowCount) {
delete statement.rowCount;
}
this._returnStatement(statement);
}
return result;
}
//---------------------------------------------------------------------------
// executeMany()
//
// Prepares the sql given by the user, calls the OAL8 RPC that executes a SQL
// statement multiple times and returns the results.
//---------------------------------------------------------------------------
async executeMany(sql, numIters, binds, options) {
const statement = await this._prepareAndBind(sql, binds, options);
if (statement.isPlSql && (options.batchErrors || options.dmlRowCounts)) {
errors.throwErr(errors.ERR_EXEC_MODE_ONLY_FOR_DML);
}
// send database request
const message = new messages.ExecuteMessage(this, statement, options);
message.numExecs = numIters;
message.arrayDmlRowCounts = options.dmlRowCounts;
message.batchErrors = options.batchErrors;
if (statement.isPlSql && statement.cursorId === 0) {
message.numExecs = 1;
await this._protocol._processMessage(message);
if (statement.plsqlMultipleExecs) {
for (let i = 0; i < numIters - 1; i++) {
message.offset = i + 1;
await this._protocol._processMessage(message);
}
} else {
message.offset = 1;
message.numExecs = numIters - 1;
}
} else {
await this._protocol._processMessage(message);
}
// process results
const returnObj = {};
statement.bufferRowIndex = 0;
const bindVars = thinUtil.getBindVars(statement);
const outBinds = thinUtil.getExecuteManyOutBinds(bindVars, numIters);
if (outBinds) {
returnObj.outBinds = outBinds;
}
const rowsAffected = !statement.isPlSql ? statement.rowCount : undefined;
if (rowsAffected) {
returnObj.rowsAffected = rowsAffected;
delete statement.rowCount;
}
if (options.dmlRowCounts) {
returnObj.dmlRowCounts = options.dmlRowCounts;
}
if (options.batchErrors) {
returnObj.batchErrors = options.batchErrors;
}
this._returnStatement(statement);
return returnObj;
}
//---------------------------------------------------------------------------
// Get the statement object from the statement cache for the SQL if it exists
// else prepare a new statement object for the SQL. If a statement is already
// in use a copy will be made and returned (and will not be returned to the
// cache). If a statement is being executed for the first time after releasing
// a DRCP session, a copy will also be made (and will not be returned to the
// cache) since it is unknown at this point whether the original session or a
// new session is going to be used.
//---------------------------------------------------------------------------
_getStatement(sql, cacheStatement = false) {
let statement = this.statementCache.get(sql);
if (!statement) {
statement = new Statement();
statement._prepare(sql);
if (cacheStatement && this.statementCache.size < this.statementCacheSize && !this._drcpEstablishSession && !statement.isDdl) {
this.statementCache.set(sql, statement);
statement.returnToCache = true;
this._adjustStatementCache();
}
} else if (statement.inUse || !cacheStatement || this._drcpEstablishSession) {
if (!cacheStatement) {
this.statementCache.delete(sql);
statement.returnToCache = false;
}
if (statement.inUse || this._drcpEstablishSession) {
statement = statement._copy();
}
} else {
this.statementCache.delete(sql);
this.statementCache.set(sql, statement);
}
statement.inUse = true;
return statement;
}
//---------------------------------------------------------------------------
// Calls the ping RPC for Oracle Database
//---------------------------------------------------------------------------
async ping() {
const message = new messages.PingMessage(this);
await this._protocol._processMessage(message);
}
//---------------------------------------------------------------------------
// Calls the Rollback RPC for Oracle Database
//---------------------------------------------------------------------------
async rollback() {
const message = new messages.RollbackMessage(this);
await this._protocol._processMessage(message);
}
//---------------------------------------------------------------------------
// Returns the Oracle Server version
//---------------------------------------------------------------------------
getOracleServerVersion() {
return this.serverVersion;
}
//---------------------------------------------------------------------------
// Returns the Oracle Server version string
//---------------------------------------------------------------------------
getOracleServerVersionString() {
return this.serverVersionString;
}
setCurrentSchema(schema) {
this._currentSchemaModified = true;
this.currentSchema = schema;
}
getCurrentSchema() {
return this.currentSchema;
}
setClientId(clientId) {
this._clientIdentifierModified = true;
this._clientIdentifier = clientId;
}
setDbOp(dbOp) {
this._dbOpModified = true;
this._dbOp = dbOp;
}
setClientInfo(clientInfo) {
this._clientInfoModified = true;
this._clientInfo = clientInfo;
}
setModule(module) {
this._moduleModified = true;
this._module = module;
/*
* setting the module by itself results in an error so always force
* action to be set as well (which eliminates this error)
*/
this._actionModified = true;
}
setAction(action) {
this._actionModified = true;
this._action = action;
}
async changePassword(user, password, newPassword) {
const config = {
user: user,
newPassword: newPassword,
password: password,
changePassword: true
};
const message = new messages.AuthMessage(this, config);
await this._protocol._processMessage(message); // OAUTH
}
async createLob(dbType) {
const lobImpl = new ThinLobImpl();
await lobImpl.create(this, dbType);
return lobImpl;
}
//---------------------------------------------------------------------------
// Returns the statement cache size for the statement cache maintained by
// the connection object
//---------------------------------------------------------------------------
getStmtCacheSize() {
return this.statementCacheSize;
}
setCallTimeout(timeout) {
this._protocol.callTimeout = timeout;
}
getCallTimeout() {
return this._protocol.callTimeout;
}
//---------------------------------------------------------------------------
// Returns getTag. Actual tag returned by db must be a string.
//---------------------------------------------------------------------------
getTag() {
return '';
}
}
module.exports = ThinConnectionImpl;

38
lib/thin/index.js Normal file
View File

@ -0,0 +1,38 @@
// Copyright (c) 2022, 2023, Oracle and/or its affiliates.
//-----------------------------------------------------------------------------
//
// This software is dual-licensed to you under the Universal Permissive License
// (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
// 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
// either license.
//
// If you elect to accept the software under the Apache License, Version 2.0,
// the following applies:
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://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 ThinConnectionImpl = require('./connection.js');
const ThinResultSetImpl = require('./resultSet.js');
const ThinPoolImpl = require('./pool.js');
const ThinLobImpl = require('./lob.js');
const impl = require('../impl');
impl.ConnectionImpl = ThinConnectionImpl;
impl.ResultSetImpl = ThinResultSetImpl;
impl.PoolImpl = ThinPoolImpl;
impl.LobImpl = ThinLobImpl;

188
lib/thin/lob.js Normal file
View File

@ -0,0 +1,188 @@
// Copyright (c) 2022, 2023, Oracle and/or its affiliates.
//-----------------------------------------------------------------------------
//
// This software is dual-licensed to you under the Universal Permissive License
// (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
// 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
// either license.
//
// If you elect to accept the software under the Apache License, Version 2.0,
// the following applies:
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://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 LobImpl = require('../impl/lob.js');
const constants = require('./protocol/constants.js');
const LobOpMessage = require('./protocol/messages/lobOp.js');
const errors = require('../errors.js');
class ThinLobImpl extends LobImpl {
//---------------------------------------------------------------------------
// _getConnImpl()
//
// Common method on all classes that make use of a connection -- used to
// ensure serialization of all use of the connection.
//---------------------------------------------------------------------------
_getConnImpl() {
return this.conn;
}
//---------------------------------------------------------------------------
// _sendMessage()
//
// Sends a LOB operation message to the server and processes the response.
//---------------------------------------------------------------------------
async _sendMessage(options) {
const message = new LobOpMessage(this.conn, options);
await this.conn._protocol._processMessage(message);
if (options.operation === constants.TNS_LOB_OP_READ) {
return (message.data) ? message.data : null;
} else {
return message.amount;
}
}
getChunkSize() {
return this._chunkSize;
}
async _getChunkSizeAsync() {
this.checkConn();
const options = {
operation: constants.TNS_LOB_OP_GET_CHUNK_SIZE,
sourceLobImpl: this,
sendAmount: true
};
this._chunkSize = this._pieceSize = await this._sendMessage(options);
}
getLength() {
return this._length;
}
getPieceSize() {
return this._pieceSize;
}
setPieceSize(value) {
this._pieceSize = value;
}
getType() {
return this.dbType;
}
async getData() {
if (this._length < 0) {
errors.throwErr(errors.ERR_INVALID_LOB);
}
return await this.read(1, this._length);
}
async read(offset, length) {
this.checkConn();
const options = {
operation: constants.TNS_LOB_OP_READ,
sourceLobImpl: this,
sourceOffset: offset,
sendAmount: true,
amount: length || this._pieceSize
};
return await this._sendMessage(options);
}
async write(offset, data) {
this.checkConn();
const options = {
operation: constants.TNS_LOB_OP_WRITE,
sourceLobImpl: this,
sourceOffset: offset,
data: data
};
await this._sendMessage(options);
this._length += data.length;
}
getCsfrm() {
if (this.dbType._csfrm !== constants.TNS_CS_NCHAR) {
if (this._locator[constants.TNS_LOB_LOC_OFFSET_FLAG_3] &
constants.TNS_LOB_LOC_FLAGS_VAR_LENGTH_CHARSET) {
return constants.TNS_CS_NCHAR;
}
}
return this.dbType._csfrm;
}
/**
* Creates a temporary LOB.
*
* @param {object} conn Connection Impl object
* @param {number} dbType indicates BLOB/CLOB DB type
*/
async create(conn, dbType) {
this.dirtyLength = false;
this.conn = conn;
this.dbType = dbType;
this._locator = Buffer.alloc(40);
this._isTempLob = true;
this._length = 0;
const options = {
operation: constants.TNS_LOB_OP_CREATE_TEMP,
sourceLobImpl: this,
amount: constants.TNS_DURATION_SESSION,
destOffset: dbType._oraTypeNum,
sourceOffset: dbType._csfrm,
sendAmount: true
};
await this._sendMessage(options);
await this._getChunkSizeAsync();
}
checkConn() {
if (!this.conn.nscon.connected)
errors.throwErr(errors.ERR_LOB_CLOSED);
}
close() {
this.checkConn();
if (this._isTempLob) {
// Add to freelist which will be sent in piggyback fashion
this.conn._tempLobsToClose.push(this._locator);
this.conn._tempLobsTotalSize += this._locator.length;
}
}
init(conn, locator, dbType, len, chunkSize) {
this.dirtyLength = false;
this.conn = conn;
this._locator = locator;
this._isTempLob = false;
if (this._locator[constants.TNS_LOB_LOC_OFFSET_FLAG_4] & constants.TNS_LOB_LOC_FLAGS_TEMP === constants.TNS_LOB_LOC_FLAGS_TEMP
|| this._locator[constants.TNS_LOB_LOC_OFFSET_FLAG_1] & constants.TNS_LOB_LOC_FLAGS_ABSTRACT === constants.TNS_LOB_LOC_FLAGS_ABSTRACT) {
this._isTempLob = true;
}
this.dbType = dbType;
this._length = len;
this._chunkSize = chunkSize;
this._pieceSize = chunkSize;
}
}
module.exports = ThinLobImpl;

475
lib/thin/pool.js Normal file
View File

@ -0,0 +1,475 @@
// Copyright (c) 2022, 2023, Oracle and/or its affiliates.
//-----------------------------------------------------------------------------
//
// This software is dual-licensed to you under the Universal Permissive License
// (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
// 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
// either license.
//
// If you elect to accept the software under the Apache License, Version 2.0,
// the following applies:
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://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 PoolImpl = require('../impl/pool.js');
const ThinConnectionImpl = require('./connection.js');
const protocolUtil = require('./protocol/utils.js');
const errors = require('../errors.js');
const settings = require('../settings.js');
const util = require('../util.js');
const {getConnectionInfo} = require('./sqlnet/networkSession.js');
const crypto = require('crypto');
const EventEmitter = require('events');
class ThinPoolImpl extends PoolImpl {
_init(params) {
this._availableObjects = [];
this._name = 'node-thin';
this._poolMin = params.poolMin;
this._poolMax = params.poolMax;
this._poolIncrement = params.poolIncrement;
this._poolTimeout = params.poolTimeout;
this._poolPingInterval = params.poolPingInterval;
this._stmtCacheSize = params.stmtCacheSize;
// The user Config filterd from common layer is cached except
// sensitive data as sensitive data is obfuscated in the pool
// and de-obfuscated as necessary.
this._userConfig = params;
this._freeConnectionList = [];
this._usedConnectionList = new Set();
this._password = params.password;
this._walletPassword = params.walletPassword;
this._obfuscatedPassword = [];
this._obfuscatedWalletPassword = [];
this._token = params.token;
this._obfuscatedToken = [];
this._privateKey = params.privateKey;
this._obfuscatedPrivateKey = [];
this._schedulerJob = null;
// password obfuscation
if (this._password !== undefined) {
let obj = protocolUtil.setObfuscatedValue(this._password);
this._password = obj.value;
this._obfuscatedPassword = obj.obfuscatedValue;
this._userConfig.password = null;
}
// wallet password obfuscation
if (this._walletPassword !== undefined) {
let obj = protocolUtil.setObfuscatedValue(this._walletPassword);
this._walletPassword = obj.value;
this._obfuscatedWalletPassword = obj.obfuscatedValue;
this._userConfig.walletPassword = null;
}
// token obfuscation
if (this._token !== undefined) {
let obj = protocolUtil.setObfuscatedValue(this._token);
this._token = obj.value;
this._obfuscatedToken = obj.obfuscatedValue;
this._userConfig.token = null;
}
// privateKey obfuscation
if (this._privateKey !== undefined) {
let obj = protocolUtil.setObfuscatedValue(this._privateKey);
this._privateKey = obj.value;
this._obfuscatedPrivateKey = obj.obfuscatedValue;
this._userConfig.privateKey = null;
}
this._accessTokenFn = params.accessTokenFn;
this._isDRCPEnabled = false;
this.eventEmitter = new EventEmitter();
// listener to remove dead or idle connections
this.eventEmitter.on('_removePoolConnection', async (connImpl) => {
await this._destroy(connImpl);
});
}
//---------------------------------------------------------------------------
// create pool with specified parameters and miminum number of connections as
// specified by poolMin
//---------------------------------------------------------------------------
async create(params) {
this._init(params);
this._userConfig._connInfo =
await getConnectionInfo(params);
this._isDRCPEnabled =
String(this._userConfig._connInfo[0]).toLowerCase() === 'pooled';
// generate connection class when none is provided by user
if (this._isDRCPEnabled && settings.connectionClass === '') {
this._generateConnectionClass();
}
// create minimum connections
await this._growPool(this._poolMin);
}
//---------------------------------------------------------------------------
// set new token and private key in pool
//---------------------------------------------------------------------------
setAccessToken(params) {
if (params.token) {
this._token = params.token;
let objToken = protocolUtil.setObfuscatedValue(this._token);
this._token = objToken.value;
this._obfuscatedToken = objToken.obfuscatedValue;
}
if (params.privateKey) {
this._privateKey = params.privateKey;
let objKey = protocolUtil.setObfuscatedValue(this._privateKey);
this._privateKey = objKey.value;
this._obfuscatedPrivateKey = objKey.obfuscatedValue;
}
}
//---------------------------------------------------------------------------
// get connection from pool
//---------------------------------------------------------------------------
async _connect(connAttrs) {
let accessToken;
const conn = new ThinConnectionImpl();
conn._pool = this;
let clonedAttrs = Object.assign({}, connAttrs);
if (clonedAttrs.password === null) {
clonedAttrs.password = protocolUtil.getDeobfuscatedValue(this._password,
this._obfuscatedPassword);
}
if (clonedAttrs.walletPassword === null) {
clonedAttrs.walletPassword =
protocolUtil.getDeobfuscatedValue(this._walletPassword,
this._obfuscatedWalletPassword);
}
if (clonedAttrs.token === null) {
clonedAttrs.token =
protocolUtil.getDeobfuscatedValue(this._token, this._obfuscatedToken);
if (util.isTokenExpired(clonedAttrs.token)) {
if (typeof this._accessTokenFn === 'function') {
accessToken = await this._accessTokenFn(true);
if (typeof accessToken === 'string') {
clonedAttrs.token = accessToken;
if (util.isTokenExpired(clonedAttrs.token)) {
// OAuth2 token is expired
errors.throwErr(errors.ERR_TOKEN_HAS_EXPIRED);
} else {
// update pool with OAuth2 token
let obj = protocolUtil.setObfuscatedValue(clonedAttrs.token);
this._token = obj.value;
this._obfuscatedToken = obj.obfuscatedValue;
}
} else if (typeof accessToken === 'object') {
clonedAttrs.token = accessToken.token;
clonedAttrs.privateKey = accessToken.privateKey;
if (util.isTokenExpired(clonedAttrs.token)) {
// IAM token is expired
errors.throwErr(errors.ERR_TOKEN_HAS_EXPIRED);
} else {
// update pool with IAM token and private key
let objToken = protocolUtil.setObfuscatedValue(clonedAttrs.token);
this._token = objToken.value;
this._obfuscatedToken = objToken.obfuscatedValue;
let objKey = protocolUtil.setObfuscatedValue(clonedAttrs.privateKey);
this._privateKey = objKey.value;
this._obfuscatedPrivateKey = objKey.obfuscatedValue;
}
}
} else {
errors.throwErr(errors.ERR_TOKEN_HAS_EXPIRED);
}
}
}
if (clonedAttrs.privateKey === null) {
clonedAttrs.privateKey =
protocolUtil.getDeobfuscatedValue(this._privateKey,
this._obfuscatedPrivateKey);
}
await conn.connect(clonedAttrs);
clonedAttrs = null;
return conn;
}
//---------------------------------------------------------------------------
// return available connection if present in pool else
// create new connection and return it
//---------------------------------------------------------------------------
async getConnection() {
if (settings.connectionClass !== '') {
this._userConfig.connectionClass = settings.connectionClass;
}
return await this.acquire();
}
//---------------------------------------------------------------------------
// destroy connection when pool close operation is called
//---------------------------------------------------------------------------
async _destroy(connection) {
if (connection.nscon.ntAdapter.connected) {
connection._dropSess = true;
await connection.close();
}
}
//---------------------------------------------------------------------------
// close pool by destroying available connections
//---------------------------------------------------------------------------
async close(obj) {
// clear scheduled job
if (this._schedulerJob) {
clearTimeout(this._schedulerJob);
this._schedulerJob = null;
}
return await this.destroyAllNow(obj);
}
//---------------------------------------------------------------------------
// returns poolMax from configuration
//---------------------------------------------------------------------------
getPoolMax() {
return this._poolMax;
}
//---------------------------------------------------------------------------
// returns poolMin from configuration
//---------------------------------------------------------------------------
getPoolMin() {
return this._poolMin;
}
//---------------------------------------------------------------------------
// get number of used connection
//---------------------------------------------------------------------------
getConnectionsInUse() {
return this._usedConnectionList.size;
}
//---------------------------------------------------------------------------
// get number of free connection
//---------------------------------------------------------------------------
getConnectionsOpen() {
return this._freeConnectionList.length + this._usedConnectionList.size;
}
//---------------------------------------------------------------------------
// returns poolIncrement from configuration
//---------------------------------------------------------------------------
getPoolIncrement() {
return this._poolIncrement;
}
//---------------------------------------------------------------------------
// returns maximum number of connections allowed per shard in the pool
//---------------------------------------------------------------------------
getPoolMaxPerShard() {
return;
}
//---------------------------------------------------------------------------
// returns the pool ping interval (seconds)
//---------------------------------------------------------------------------
getPoolPingInterval() {
return this._poolPingInterval;
}
//---------------------------------------------------------------------------
// returns the pool timeout
//---------------------------------------------------------------------------
getPoolTimeout() {
return this._poolTimeout;
}
//---------------------------------------------------------------------------
// returns whether the SODA metadata cache is enabled or not
//---------------------------------------------------------------------------
getSodaMetaDataCache() {
return;
}
//---------------------------------------------------------------------------
// returns the statement cache size associate with the pool
//---------------------------------------------------------------------------
getStmtCacheSize() {
return this._stmtCacheSize;
}
//---------------------------------------------------------------------------
// _growPool()
//
// Grows the pool to include the specified number of connections.
//---------------------------------------------------------------------------
async _growPool(numConns) {
while (numConns > 0) {
let conn = await this._connect(this._userConfig);
conn._newSession = true;
conn._dropSess = false;
conn._lastTimeUsed = Date.now();
this._freeConnectionList.push(conn);
numConns--;
}
}
//---------------------------------------------------------------------------
// _setScheduler()
//
// set scheduler to scan and remove idle connections
//---------------------------------------------------------------------------
_setScheduler() {
if (!this._schedulerJob && this._poolTimeout > 0 &&
this._freeConnectionList.length > 0 &&
(this._freeConnectionList.length + this._usedConnectionList.size >
this._poolMin)) {
this._schedulerJob = setTimeout(() => {
this._scanIdleConnection();
}, this._poolTimeout * 1000);
}
}
//---------------------------------------------------------------------------
// scanIdleConnection()
//
// scan connection list and removes idle connections from pool
//---------------------------------------------------------------------------
_scanIdleConnection() {
while ((this._usedConnectionList.size + this._freeConnectionList.length) >
this._poolMin && this._freeConnectionList.length > 0) {
const conn = this._freeConnectionList[this._freeConnectionList.length - 1];
if (Date.now() - conn._lastTimeUsed < this._poolTimeout * 1000) {
break;
}
this.eventEmitter.emit('_removePoolConnection', conn);
this._freeConnectionList.pop();
}
this._schedulerJob = null;
this._setScheduler();
}
//---------------------------------------------------------------------------
// acquire()
//
// acquire a connection from connection pool
//---------------------------------------------------------------------------
async acquire() {
// return first connection from the free list that passes health checks
while (this._freeConnectionList.length > 0) {
const conn = this._freeConnectionList.pop();
// if connection is unhealthy, drop it from the pool
if (!conn.isHealthy()) {
this.eventEmitter.emit('_removePoolConnection', conn);
continue;
}
// perform a ping, if necessary; a ping interval less than 0 disables
// pings; a ping interval of 0 forces a ping for each use of the
// connection and a value greater than 0 will be performed if the
// connection has not been used for that period of time; if the ping is
// unsuccessful, drop the connection from the pool
let requiresPing = false;
if (this._poolPingInterval === 0) {
requiresPing = true;
} else if (this._poolPingInterval > 0) {
const elapsed = Date.now() - conn._lastTimeUsed;
if (elapsed > this._poolPingInterval * 1000)
requiresPing = true;
}
if (requiresPing) {
try {
await conn.ping();
} catch {
this.eventEmitter.emit('_removePoolConnection', conn);
continue;
}
}
// connection has passed health checks, return it immediately
this._usedConnectionList.add(conn);
return conn;
}
// no free connections exist at this point; if less than poolMin
// connections exist, grow the pool to poolMin again; otherwise, increase
// the pool by poolIncrement up to poolMax
if (this._usedConnectionList.size < this._poolMin) {
await this._growPool(this._poolMin - this._usedConnectionList.size);
} else {
const sizeAvailable = this._poolMax - this._usedConnectionList.size;
await this._growPool(Math.min(this._poolIncrement, sizeAvailable));
if (this._poolIncrement > 1 && sizeAvailable > 1) {
this._setScheduler();
}
}
// return a connection from the ones that were just built
const conn = this._freeConnectionList.pop();
this._usedConnectionList.add(conn);
return conn;
}
// release connection to connection pool
release(conn) {
this._usedConnectionList.delete(conn);
if (conn.nscon.connected) {
conn._lastTimeUsed = Date.now();
conn._newSession = false;
this._freeConnectionList.push(conn);
}
this._setScheduler();
}
//---------------------------------------------------------------------------
// destroyAllNow()
//
// called during pool close operation and close any available connection
// available in connection pool
//---------------------------------------------------------------------------
async destroyAllNow(obj) {
let conn;
while (this._freeConnectionList.length !== 0) {
conn = this._freeConnectionList.pop();
await this._destroy(conn);
}
if (obj.forceClose) {
for (const item of this._usedConnectionList) {
await this._destroy(item);
this._usedConnectionList.delete(item);
}
}
if (this._usedConnectionList.size !== 0) {
errors.throwErr(errors.ERR_POOL_HAS_BUSY_CONNECTIONS);
}
this.eventEmitter.removeAllListeners();
}
//---------------------------------------------------------------------------
// _generateConnectionClass()
//
// generate connection class for drcp if none is provided by user
//---------------------------------------------------------------------------
_generateConnectionClass() {
this._userConfig.connectionClass = crypto.randomBytes(16).toString('base64');
this._userConfig.connectionClass = "NJS:" + this._userConfig.connectionClass;
}
}
module.exports = ThinPoolImpl;

984
lib/thin/protocol/buffer.js Normal file
View File

@ -0,0 +1,984 @@
// Copyright (c) 2022, 2023, Oracle and/or its affiliates.
//-----------------------------------------------------------------------------
//
// This software is dual-licensed to you under the Universal Permissive License
// (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
// 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
// either license.
//
// If you elect to accept the software under the Apache License, Version 2.0,
// the following applies:
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://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 constants = require("./constants.js");
const errors = require("../../errors.js");
const types = require("../../types.js");
/**
* Base buffer class used for managing buffered data without unnecessary
* copying.
*/
class BaseBuffer {
//---------------------------------------------------------------------------
// constructor()
//
// The initializer is either an integer specifying the size of the buffer, or
// an existing Buffer, which is used directly.
//---------------------------------------------------------------------------
constructor(initializer) {
if (typeof initializer === 'number') {
this.buf = Buffer.alloc(initializer);
this.size = 0;
this.maxSize = initializer;
} else {
this.buf = initializer;
this.size = this.maxSize = initializer.length;
}
this.pos = 0;
}
//---------------------------------------------------------------------------
// _grow()
//
// Called when the buffer needs to grow. The base function simply raises an
// error.
//---------------------------------------------------------------------------
_grow(numBytes) {
errors.throwErr(errors.ERR_BUFFER_LENGTH_INSUFFICIENT, this.numBytesLeft(),
numBytes);
}
//---------------------------------------------------------------------------
// _readBytesWithLength()
//
// Helper function that processes the number of bytes (if needed) and then
// acquires the specified number of bytes from the buffer. The base function
// simply uses the length as given.
//---------------------------------------------------------------------------
_readBytesWithLength(numBytes) {
return this.readBytes(numBytes);
}
//---------------------------------------------------------------------------
// _readInteger()
//
// Read an integer from the buffer of the specified maximum size and returns
// it. The signed flag indicates whether the value is allowed to be signed or
// not and the skip flag indicates whether the data should simply be skipped.
//---------------------------------------------------------------------------
_readInteger(maxSize, signed, skip) {
let isNegative = false;
let size = this.readUInt8();
if (size === 0) {
return 0;
} else if (size & 0x80) {
if (!signed) {
errors.throwErr(errors.ERR_UNEXPECTED_NEGATIVE_INTEGER);
}
isNegative = true;
size = size & 0x7f;
}
if (size > maxSize) {
errors.throwErr(errors.ERR_INTEGER_TOO_LARGE, size, maxSize);
}
if (skip) {
this.skipBytes(size);
} else {
const buf = this.readBytes(size);
const value = buf.readUIntBE(0, size);
return (isNegative) ? -value : value;
}
}
//---------------------------------------------------------------------------
// numBytesLeft()
//
// Returns the number of bytes that are remaining in the buffer.
//---------------------------------------------------------------------------
numBytesLeft() {
return this.size - this.pos;
}
//---------------------------------------------------------------------------
// parseBinaryDouble()
//
// Parses a binary double from the supplied buffer and returns a Number.
// It is assumed at this point that the size of the buffer is 8 bytes. A copy
// is made of the buffer in order to ensure that the original buffer is not
// modified. If it is and data spans multiple packets, incorrect data may be
// returned!
//---------------------------------------------------------------------------
parseBinaryDouble(buf) {
buf = Buffer.from(buf);
if (buf[0] & 0x80) {
buf[0] &= 0x7f;
} else {
// complement the bits for a negative number
buf[0] ^= 0xff;
buf[1] ^= 0xff;
buf[2] ^= 0xff;
buf[3] ^= 0xff;
buf[4] ^= 0xff;
buf[5] ^= 0xff;
buf[6] ^= 0xff;
buf[7] ^= 0xff;
}
return buf.readDoubleBE();
}
//---------------------------------------------------------------------------
// parseBinaryFloat()
//
// Parses a binary float from the supplied buffer and returns a Number. It
// is assumed at this point that the size of the buffer is 4 bytes. A copy is
// made of the buffer in order to ensure that the original buffer is not
// modified. If it is and data spans multiple packets, incorrect data may be
// returned!
//---------------------------------------------------------------------------
parseBinaryFloat(buf) {
buf = Buffer.from(buf);
if (buf[0] & 0x80) {
buf[0] &= 0x7f;
} else {
// complement the bits for a negative number
buf[0] ^= 0xff;
buf[1] ^= 0xff;
buf[2] ^= 0xff;
buf[3] ^= 0xff;
}
return buf.readFloatBE();
}
//---------------------------------------------------------------------------
// parseOracleDate()
//
// Parses an Oracle date from the supplied buffer and returns a Date. It is
// assumed at this point that the size of the buffer is either 7 bytes (date
// or compressed timestamp), 11 bytes (timestamp) or 13 bytes (timestamp with
// time zone). Time zone information is discarded because Node.js uses UTC
// timestamps and the server returns the data in that format, too. The Date
// type in Node.js doesn't support time zone information.
//---------------------------------------------------------------------------
parseOracleDate(buf, offset) {
let fseconds = 0;
if (buf.length >= 11) {
fseconds = Math.floor(buf.readUInt32BE(7) / 1000);
}
const year = (buf[0] - 100) * 100 + buf[1] - 100;
let dateRet = new Date(Date.UTC(year, buf[2] - 1, buf[3], buf[4] - 1, buf[5] - 1,
buf[6] - 1, fseconds / 1000, fseconds % 1000));
if (offset) {
dateRet = new Date(dateRet.getTime() - offset * 60000);
}
return dateRet;
}
//---------------------------------------------------------------------------
// parseOracleNumber()
//
// Parses an Oracle number from the supplied buffer and returns a Number. It
// is assumed at this point that the buffer only contains the encoded numeric
// data.
//---------------------------------------------------------------------------
parseOracleNumber(buf, desiredType) {
// the first byte is the exponent; positive numbers have the highest
// order bit set, whereas negative numbers have the highest order bit
// cleared and the bits inverted
let exponent = buf[0];
const isPositive = Boolean(exponent & 0x80);
if (!isPositive) {
exponent = (exponent ^ 0xFF);
}
exponent -= 193;
let decimalPointIndex = exponent * 2 + 2;
// a mantissa length of 0 implies a value of 0 (if positive) or a value
// of -1e126 (if negative)
if (buf.length === 1) {
if (isPositive) {
return 0;
}
return -1e126;
}
// check for the trailing 102 byte for negative numbers and, if present,
// reduce the number of mantissa digits
let numBytes = buf.length;
if (!isPositive && buf[buf.length - 1] === 102) {
numBytes -= 1;
}
// process the mantissa bytes which are the remaining bytes; each
// mantissa byte is a base-100 digit
let base100Digit;
const digits = [];
for (let i = 1; i < numBytes; i++) {
// positive numbers have 1 added to them; negative numbers are
// subtracted from the value 101
if (isPositive) {
base100Digit = buf[i] - 1;
} else {
base100Digit = 101 - buf[i];
}
// process the first digit; leading zeroes are ignored
let digit = Math.floor(base100Digit / 10);
if (digit === 0 && i === 1) {
decimalPointIndex -= 1;
} else if (digit === 10) {
digits.push("1");
digits.push("0");
decimalPointIndex += 1;
} else if (digit !== 0 || i > 1) {
digits.push(digit.toString());
}
// process the second digit; trailing zeroes are ignored
digit = base100Digit % 10;
if (digit !== 0 || i < numBytes - 1) {
digits.push(digit.toString());
}
}
// create string of digits for transformation to JS value
const chars = [];
// if negative, include the sign
if (!isPositive) {
chars.push("-");
}
// if the decimal point index is 0 or less, add the decimal point and
// any leading zeroes that are needed
if (decimalPointIndex <= 0) {
chars.push(".");
if (decimalPointIndex < 0)
chars.push("0".repeat(-decimalPointIndex));
}
// add each of the digits
for (let i = 0; i < digits.length; i++) {
if (i > 0 && i === decimalPointIndex) {
chars.push(".");
}
chars.push(digits[i]);
}
// if the decimal point index exceeds the number of digits, add any
// trailing zeroes that are needed
if (decimalPointIndex > digits.length) {
for (let i = digits.length; i < decimalPointIndex; i++) {
chars.push("0");
}
}
// convert result to a Number
const text = chars.join("");
if (desiredType === types.DB_TYPE_VARCHAR) {
return text;
}
return parseFloat(text);
}
//---------------------------------------------------------------------------
// readBinaryDouble()
//
// Reads a binary double value from the buffer and returns a Number or a
// String, depending on the desired type.
//---------------------------------------------------------------------------
readBinaryDouble(desiredType) {
const buf = this.readBytesWithLength();
if (!buf) {
return null;
}
const val = this.parseBinaryDouble(buf);
if (desiredType === types.DB_TYPE_VARCHAR) {
return val.toString();
}
return val;
}
//---------------------------------------------------------------------------
// readBinaryFloat()
//
// Reads a binary float value from the buffer and returns a Number or a
// String, depending on the desired type.
//---------------------------------------------------------------------------
readBinaryFloat(desiredType) {
const buf = this.readBytesWithLength();
if (!buf) {
return null;
}
const val = this.parseBinaryFloat(buf);
if (desiredType === types.DB_TYPE_VARCHAR) {
return val.toString();
}
return val;
}
//---------------------------------------------------------------------------
// readBool()
//
// Reads a boolean value from the buffer and returns a Boolean.
//---------------------------------------------------------------------------
readBool() {
const buf = this.readBytesWithLength();
if (!buf) {
return null;
}
return (buf[buf.length - 1] === 1);
}
//---------------------------------------------------------------------------
// readBytes()
//
// Returns a Buffer containing the specified number of bytes. If an
// insufficient number of bytes are available an error is thrown.
//---------------------------------------------------------------------------
readBytes(numBytes) {
const numBytesLeft = this.numBytesLeft();
if (numBytes > numBytesLeft) {
errors.throwErr(errors.ERR_UNEXPECTED_END_OF_DATA, numBytes,
numBytesLeft);
}
const buf = this.buf.subarray(this.pos, this.pos + numBytes);
this.pos += numBytes;
return buf;
}
//---------------------------------------------------------------------------
// readBytesWithLength()
//
// Reads the length from the buffer and then returns a Buffer containing the
// specified number of bytes. If the length is 0 or the special null length
// indicator value, null is returned instead.
//---------------------------------------------------------------------------
readBytesWithLength() {
const numBytes = this.readUInt8();
if (numBytes === 0 || numBytes === constants.TNS_NULL_LENGTH_INDICATOR)
return null;
return this._readBytesWithLength(numBytes);
}
//---------------------------------------------------------------------------
// readInt8()
//
// Reads a signed 8-bit integer from the buffer.
//---------------------------------------------------------------------------
readInt8() {
const buf = this.readBytes(1);
return buf.readInt8();
}
//---------------------------------------------------------------------------
// readOracleDate()
//
// Reads an Oracle date from the buffer and returns a Date or a String,
// depending on the desired type.
//---------------------------------------------------------------------------
readOracleDate(desiredType, offset) {
const buf = this.readBytesWithLength();
if (!buf) {
return null;
}
const val = this.parseOracleDate(buf, offset);
if (desiredType === types.DB_TYPE_VARCHAR) {
return val.toString();
}
return val;
}
//---------------------------------------------------------------------------
// readOracleNumber()
//
// Reads an Oracle number from the buffer and returns a Number or a String,
// depending on the desired type.
//---------------------------------------------------------------------------
readOracleNumber(desiredType) {
const buf = this.readBytesWithLength();
if (!buf) {
return null;
}
return this.parseOracleNumber(buf, desiredType);
}
//---------------------------------------------------------------------------
// readSB2()
//
// Reads a signed, variable length integer of up to 2 bytes in length.
//---------------------------------------------------------------------------
readSB2() {
return this._readInteger(2, true, false);
}
//---------------------------------------------------------------------------
// readSB4()
//
// Reads a signed, variable length integer of up to 4 bytes in length.
//---------------------------------------------------------------------------
readSB4() {
return this._readInteger(4, true, false);
}
//---------------------------------------------------------------------------
// readSB8()
//
// Reads a signed, variable length integer of up to 8 bytes in length.
//---------------------------------------------------------------------------
readSB8() {
return this._readInteger(8, true, false);
}
//---------------------------------------------------------------------------
// readStr()
//
// Reads a string from the buffer in the specified character set form.
//---------------------------------------------------------------------------
readStr(csfrm) {
const buf = this.readBytesWithLength();
if (!buf) {
return null;
}
if (csfrm === constants.TNS_CS_IMPLICIT)
return buf.toString();
// need a copy of the buffer since swap16() changes the buffer in place and
// it is possible that the buffer may need to be rescanned (for the case
// where insufficient packets are available during the initial scan)
return Buffer.from(buf).swap16().toString('utf16le');
}
//---------------------------------------------------------------------------
// readUB2()
//
// Reads an unsigned, variable length integer of up to 2 bytes in length.
//---------------------------------------------------------------------------
readUB2() {
return this._readInteger(2, false, false);
}
//---------------------------------------------------------------------------
// readUB4()
//
// Reads an unsigned, variable length integer of up to 4 bytes in length.
//---------------------------------------------------------------------------
readUB4() {
return this._readInteger(4, false, false);
}
//---------------------------------------------------------------------------
// readUB8()
//
// Reads an unsigned, variable length integer of up to 8 bytes in length.
//---------------------------------------------------------------------------
readUB8() {
return this._readInteger(8, false, false);
}
//---------------------------------------------------------------------------
// readUInt8()
//
// Reads an unsigned 8-bit integer from the buffer.
//---------------------------------------------------------------------------
readUInt8() {
const buf = this.readBytes(1);
return buf[0];
}
//---------------------------------------------------------------------------
// readUInt16BE()
//
// Reads an unsigned 16-bit integer from the buffer in big endian order.
//---------------------------------------------------------------------------
readUInt16BE() {
const buf = this.readBytes(2);
return buf.readUInt16BE();
}
//---------------------------------------------------------------------------
// readUInt16LE()
//
// Reads an unsigned 16-bit integer from the buffer in little endian order.
//---------------------------------------------------------------------------
readUInt16LE() {
const buf = this.readBytes(2);
return buf.readUInt16LE();
}
//---------------------------------------------------------------------------
// readUInt32BE()
//
// Reads an unsigned 32-bit integer from the buffer in big endian order.
//---------------------------------------------------------------------------
readUInt32BE() {
const buf = this.readBytes(4);
return buf.readUInt32BE();
}
//---------------------------------------------------------------------------
// reserveBytes()
//
// Reserves the specified number of bytes in the buffer. If not enough bytes
// remain in the buffer, the buffer is grown.
//---------------------------------------------------------------------------
reserveBytes(numBytes) {
if (numBytes > this.numBytesLeft())
this._grow(this.pos + numBytes);
const buf = this.buf.subarray(this.pos, this.pos + numBytes);
this.pos += numBytes;
return buf;
}
//---------------------------------------------------------------------------
// skipBytes()
//
// Skips the specified number of bytes in the buffer.
//---------------------------------------------------------------------------
skipBytes(numBytes) {
if (numBytes > this.numBytesLeft())
errors.throwErr(errors.ERR_UNEXPECTED_END_OF_DATA);
this.pos += numBytes;
}
//---------------------------------------------------------------------------
// skipSB4()
//
// Skips a signed, variable length integer of up to 4 bytes in length.
//---------------------------------------------------------------------------
skipSB4() {
return this._readInteger(4, true, true);
}
//---------------------------------------------------------------------------
// skipUB1()
//
// Skips a single byte integer in the buffer.
//---------------------------------------------------------------------------
skipUB1() {
this.skipBytes(1);
}
//---------------------------------------------------------------------------
// skipUB2()
//
// Skips an unsigned, variable length integer of up to 2 bytes in length.
//---------------------------------------------------------------------------
skipUB2() {
return this._readInteger(2, false, true);
}
//---------------------------------------------------------------------------
// skipUB4()
//
// Skips an unsigned, variable length integer of up to 4 bytes in length.
//---------------------------------------------------------------------------
skipUB4() {
return this._readInteger(4, false, true);
}
//---------------------------------------------------------------------------
// skipUB8()
//
// Skips an unsigned, variable length integer of up to 8 bytes in length.
//---------------------------------------------------------------------------
skipUB8() {
return this._readInteger(8, false, true);
}
//---------------------------------------------------------------------------
// writeBinaryDouble()
//
// Writes the number in binary double format to the buffer.
//---------------------------------------------------------------------------
writeBinaryDouble(n) {
this.writeUInt8(8);
const buf = this.reserveBytes(8);
buf.writeDoubleBE(n);
if ((buf[0] & 0x80) === 0) {
buf[0] |= 0x80;
} else {
// We complement the bits for a negative number
buf[0] ^= 0xff;
buf[1] ^= 0xff;
buf[2] ^= 0xff;
buf[3] ^= 0xff;
buf[4] ^= 0xff;
buf[5] ^= 0xff;
buf[6] ^= 0xff;
buf[7] ^= 0xff;
}
}
//---------------------------------------------------------------------------
// writeBinaryFloat()
//
// Writes the number in binary float format to the buffer.
//---------------------------------------------------------------------------
writeBinaryFloat(n) {
this.writeUInt8(4);
const buf = this.reserveBytes(4);
buf.writeFloatBE(n);
if ((buf[0] & 0x80) === 0) {
buf[0] |= 0x80;
} else {
// We complement the bits for a negative number
buf[0] ^= 0xff;
buf[1] ^= 0xff;
buf[2] ^= 0xff;
buf[3] ^= 0xff;
}
}
//---------------------------------------------------------------------------
// writeBytes()
//
// Writes the bytes in the supplied buffer to the buffer.
//---------------------------------------------------------------------------
writeBytes(value) {
let start = 0;
let valueLen = value.length;
while (valueLen > 0) {
const bytesLeft = this.numBytesLeft();
if (bytesLeft === 0) {
this._grow(this.pos + valueLen);
}
const bytesToWrite = Math.min(bytesLeft, valueLen);
value.copy(this.buf, this.pos, start, start + bytesToWrite);
this.pos += bytesToWrite;
start += bytesToWrite;
valueLen -= bytesToWrite;
}
}
//---------------------------------------------------------------------------
// writeBytesWithLength()
//
// Writes the bytes in the supplied buffer to the buffer, but first writes
// the length. If the length exceeds a fixed value, the value is written in
// chunks instead.
//---------------------------------------------------------------------------
writeBytesWithLength(value) {
let numBytes = value.length;
if (numBytes <= constants.TNS_MAX_SHORT_LENGTH) {
this.writeUInt8(numBytes);
this.writeBytes(value);
} else {
let start = 0;
this.writeUInt8(constants.TNS_LONG_LENGTH_INDICATOR);
while (numBytes > 0) {
const chunkLen = Math.min(numBytes, constants.BUFFER_CHUNK_SIZE);
this.writeUB4(chunkLen);
this.writeBytes(value.subarray(start, start + chunkLen));
numBytes -= chunkLen;
start += chunkLen;
}
this.writeUB4(0);
}
}
//---------------------------------------------------------------------------
// writeOracleDate()
//
// Writes the date to the buffer. The length specifies the amount of
// information the server is expecting for the particular date type.
//---------------------------------------------------------------------------
writeOracleDate(date, length, writeLength = true) {
let fsec;
if (length > 7) {
fsec = date.getUTCMilliseconds() * 1000 * 1000;
if (fsec === 0 && length <= 11)
length = 7;
}
if (writeLength) {
this.writeUInt8(length);
}
const ptr = this.reserveBytes(length);
const year = date.getUTCFullYear();
ptr[0] = Math.floor(year / 100) + 100;
ptr[1] = year % 100 + 100;
ptr[2] = date.getUTCMonth() + 1;
ptr[3] = date.getUTCDate();
ptr[4] = date.getUTCHours() + 1;
ptr[5] = date.getUTCMinutes() + 1;
ptr[6] = date.getUTCSeconds() + 1;
if (length > 7) {
ptr.writeInt32BE(fsec, 7);
if (length > 11) {
ptr[11] = constants.TZ_HOUR_OFFSET;
ptr[12] = constants.TZ_MINUTE_OFFSET;
}
}
}
//---------------------------------------------------------------------------
// writeOracleNumber()
//
// Writes the number (in string form) in Oracle Number format to the buffer.
//---------------------------------------------------------------------------
writeOracleNumber(value) {
// determine if number is negative
let isNegative = false;
if (value[0] === '-') {
isNegative = true;
value = value.substring(1);
}
// parse the exponent, if one is present
let exponent = 0;
const exponentPos = value.indexOf('e');
if (exponentPos > 0) {
exponent = Number(value.substring(exponentPos + 1));
value = value.substring(0, exponentPos);
}
// adjust the exponent and the value if there is a decimal point
const decimalPos = value.indexOf('.');
if (decimalPos > 0) {
exponent -= (value.length - decimalPos - 1);
value = value.substring(0, decimalPos) + value.substring(decimalPos + 1);
}
// strip any leading zeroes
if (value[0] === '0') {
value = value.replace(/^0+/, "");
}
// strip any trailing zeroes
if (value.length > 0 && value[value.length - 1] === '0') {
const trimmedValue = value.replace(/0+$/, "");
exponent += (value.length - trimmedValue.length);
value = trimmedValue;
}
// throw exception if number cannot be represented as an Oracle Number
if (value.length > constants.NUMBER_MAX_DIGITS || exponent > 126 ||
exponent < -129) {
errors.throwErr(errors.ERR_ORACLE_NUMBER_NO_REPR);
}
// if the exponent is odd, append a zero
if ((exponent > 0 && exponent % 2 === 1) ||
(exponent < 0 && exponent % 2 === -1)) {
exponent--;
value += "0";
}
// add a leading zero if the number of digits is odd
if (value.length % 2 === 1) {
value = "0" + value;
}
// write the encoded data to the wire
const appendSentinel =
(isNegative && value.length < constants.NUMBER_MAX_DIGITS);
const numPairs = value.length / 2;
let exponentOnWire = ((exponent + value.length) / 2) + 192;
if (isNegative) {
exponentOnWire = (exponentOnWire ^ 0xFF);
} else if (value.length === 0 && exponent === 0) {
exponentOnWire = 128;
}
const buf = this.reserveBytes(numPairs + 2 + appendSentinel);
buf[0] = numPairs + 1 + appendSentinel;
buf[1] = exponentOnWire;
for (let i = 0, pos = 2; i < value.length; i += 2, pos++) {
let base100Digit = Number(value.substring(i, i + 2));
if (isNegative) {
buf[pos] = 101 - base100Digit;
} else {
buf[pos] = base100Digit + 1;
}
}
if (appendSentinel) {
buf[buf.length - 1] = 102;
}
}
//---------------------------------------------------------------------------
// writeQLocator()
//
// Writes a QLocator. QLocators are always 40 bytes in length.
//---------------------------------------------------------------------------
writeQLocator(numBytes) {
this.writeUB4(40); // QLocator length
this.writeUInt8(40); // repeated length
this.writeUInt16BE(38); // internal length
this.writeUInt16BE(constants.TNS_LOB_QLOCATOR_VERSION);
this.writeUInt8(constants.TNS_LOB_LOC_FLAGS_VALUE_BASED |
constants.TNS_LOB_LOC_FLAGS_BLOB | constants.TNS_LOB_LOC_FLAGS_ABSTRACT);
this.writeUInt8(constants.TNS_LOB_LOC_FLAGS_INIT);
this.writeUInt16BE(0); // additional flags
this.writeUInt16BE(1); // byt1
this.writeUInt64BE(numBytes);
this.writeUInt16BE(0); // unused
this.writeUInt16BE(0); // csid
this.writeUInt16BE(0); // unused
this.writeUInt64BE(0); // unused
this.writeUInt64BE(0); // unused
}
//---------------------------------------------------------------------------
// writeStr()
//
// Writes the string to the buffer.
//---------------------------------------------------------------------------
writeStr(s) {
this.writeBytes(Buffer.from(s));
}
//---------------------------------------------------------------------------
// writeUB4()
//
// Writes an unsigned integer (up to 4 bytes in length) in variable length
// format to the buffer.
//---------------------------------------------------------------------------
writeUB4(value) {
if (value === 0) {
this.writeUInt8(0);
} else if (value <= 0xff) {
this.writeUInt8(1);
this.writeUInt8(value);
} else if (value <= 0xffff) {
this.writeUInt8(2);
this.writeUInt16BE(value);
} else {
this.writeUInt8(4);
this.writeUInt32BE(value);
}
}
//---------------------------------------------------------------------------
// writeUB8()
//
// Writes an unsigned integer (up to 8 bytes in length) in variable length
// format to the buffer.
//---------------------------------------------------------------------------
writeUB8(value) {
if (value === 0) {
this.writeUInt8(0);
} else if (value <= 0xff) {
this.writeUInt8(1);
this.writeUInt8(value);
} else if (value <= 0xffff) {
this.writeUInt8(2);
this.writeUInt16BE(value);
} else if (value <= 0xffffffff) {
this.writeUInt8(4);
this.writeUInt32BE(value);
} else {
this.writeUInt8(8);
this.writeUInt64BE(value);
}
}
//---------------------------------------------------------------------------
// writeUInt8()
//
// Writes an unsigned 8-bit integer to the buffer.
//---------------------------------------------------------------------------
writeUInt8(n) {
const buf = this.reserveBytes(1);
buf[0] = n;
}
//---------------------------------------------------------------------------
// writeUInt16BE()
//
// Writes an unsigned 16-bit integer to the buffer in big endian order.
//---------------------------------------------------------------------------
writeUInt16BE(n) {
const buf = this.reserveBytes(2);
buf.writeUInt16BE(n);
}
//---------------------------------------------------------------------------
// writeUInt32BE()
//
// Writes an unsigned 32-bit integer to the buffer in big endian order.
//---------------------------------------------------------------------------
writeUInt32BE(n) {
const buf = this.reserveBytes(4);
buf.writeUInt32BE(n);
}
//---------------------------------------------------------------------------
// writeUInt64BE()
//
// Writes an unsigned 64-bit integer to the buffer in big endian order. Since
// Node.js doesn't support anything above 32-bits without using BigInt, the
// higher order bits are simply written as 0.
//---------------------------------------------------------------------------
writeUInt64BE(n) {
const buf = this.reserveBytes(8);
buf.writeUInt32BE(0);
buf.writeUInt32BE(n);
}
//---------------------------------------------------------------------------
// writeUInt16LE()
//
// Writes an unsigned 16-bit integer to the buffer in little endian order.
//---------------------------------------------------------------------------
writeUInt16LE(n) {
const buf = this.reserveBytes(2);
buf.writeUInt16LE(n);
}
}
class GrowableBuffer extends BaseBuffer {
//---------------------------------------------------------------------------
// constructor()
//
// Initializes the buffer with an initial fixed chunk size.
//---------------------------------------------------------------------------
constructor() {
super(constants.BUFFER_CHUNK_SIZE);
this.size = this.maxSize;
}
//---------------------------------------------------------------------------
// _grow()
//
// Called when the buffer needs to grow. Ensures that sufficient space is
// allocated to include the requested number of bytes, rounded to the nearest
// chunk size.
//---------------------------------------------------------------------------
_grow(numBytes) {
const remainder = numBytes % constants.BUFFER_CHUNK_SIZE;
if (remainder > 0) {
numBytes += (constants.BUFFER_CHUNK_SIZE - remainder);
}
const buf = Buffer.alloc(numBytes);
this.buf.copy(buf);
this.buf = buf;
this.maxSize = this.size = numBytes;
}
}
module.exports = {
BaseBuffer,
GrowableBuffer
};

View File

@ -0,0 +1,116 @@
// Copyright (c) 2022, 2023, Oracle and/or its affiliates.
//-----------------------------------------------------------------------------
//
// This software is dual-licensed to you under the Universal Permissive License
// (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
// 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
// either license.
//
// If you elect to accept the software under the Apache License, Version 2.0,
// the following applies:
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://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 Buffer = require("buffer").Buffer;
const constants = require("./constants.js");
const errors = require('../../errors');
/**
* Negotiates Compiletime and Runtime capabilities
*
*/
class Capabilities {
constructor(protocolVersion) {
this.protocolVersion = protocolVersion;
this.ttcFieldVersion = constants.TNS_CCAP_FIELD_VERSION_MAX;
this.supports12cLogon = true;
this.supportsOob = false;
this.nCharsetId = constants.TNS_CHARSET_UTF16;
this.compileCaps = Buffer.alloc(constants.TNS_CCAP_MAX);
this.runtimeCaps = Buffer.alloc(constants.TNS_RCAP_MAX);
this.initCompileCaps();
this.initRuntimeCaps();
}
adjustForServerCompileCaps(serverCaps) {
if (serverCaps[constants.TNS_CCAP_FIELD_VERSION] < this.ttcFieldVersion) {
this.ttcFieldVersion = serverCaps[constants.TNS_CCAP_FIELD_VERSION];
this.compileCaps[constants.TNS_CCAP_FIELD_VERSION] =
this.ttcFieldVersion;
}
}
adjustForServerRuntimeCaps() {
// nothing to do currently
}
initCompileCaps() {
this.compileCaps[constants.TNS_CCAP_SQL_VERSION] =
constants.TNS_CCAP_SQL_VERSION_MAX;
this.compileCaps[constants.TNS_CCAP_LOGON_TYPES] =
constants.TNS_CCAP_O5LOGON | constants.TNS_CCAP_O5LOGON_NP |
constants.TNS_CCAP_O7LOGON | constants.TNS_CCAP_O8LOGON_LONG_IDENTIFIER |
constants.TNS_CCAP_O9LOGON_LONG_PASSWORD;
this.compileCaps[constants.TNS_CCAP_FIELD_VERSION] = this.ttcFieldVersion;
this.compileCaps[constants.TNS_CCAP_SERVER_DEFINE_CONV] = 1;
this.compileCaps[constants.TNS_CCAP_TTC1] =
constants.TNS_CCAP_FAST_BVEC | constants.TNS_CCAP_END_OF_CALL_STATUS |
constants.TNS_CCAP_IND_RCD;
this.compileCaps[constants.TNS_CCAP_OCI1] =
constants.TNS_CCAP_FAST_SESSION_PROPAGATE |
constants.TNS_CCAP_APP_CTX_PIGGYBACK;
this.compileCaps[constants.TNS_CCAP_TDS_VERSION] =
constants.TNS_CCAP_TDS_VERSION_MAX;
this.compileCaps[constants.TNS_CCAP_RPC_VERSION] =
constants.TNS_CCAP_RPC_VERSION_MAX;
this.compileCaps[constants.TNS_CCAP_RPC_SIG] =
constants.TNS_CCAP_RPC_SIG_VALUE;
this.compileCaps[constants.TNS_CCAP_DBF_VERSION] =
constants.TNS_CCAP_DBF_VERSION_MAX;
this.compileCaps[constants.TNS_CCAP_LOB] =
constants.TNS_CCAP_LOB_UB8_SIZE | constants.TNS_CCAP_LOB_ENCS | constants.TNS_CCAP_LOB_PREFETCH;
this.compileCaps[constants.TNS_CCAP_UB2_DTY] = 1;
this.compileCaps[constants.TNS_CCAP_LOB2] =
constants.TNS_CCAP_LOB2_QUASI | constants.TNS_CCAP_LOB2_2GB_PREFETCH;
this.compileCaps[constants.TNS_CCAP_TTC3] =
constants.TNS_CCAP_IMPLICIT_RESULTS | constants.TNS_CCAP_BIG_CHUNK_CLR |
constants.TNS_CCAP_KEEP_OUT_ORDER;
this.compileCaps[constants.TNS_CCAP_TTC2] = constants.TNS_CCAP_ZLNP;
this.compileCaps[constants.TNS_CCAP_OCI2] = constants.TNS_CCAP_DRCP;
this.compileCaps[constants.TNS_CCAP_CLIENT_FN] =
constants.TNS_CCAP_CLIENT_FN_MAX;
this.compileCaps[constants.TNS_CCAP_TTC4] =
constants.TNS_CCAP_INBAND_NOTIFICATION;
}
initRuntimeCaps() {
this.runtimeCaps[constants.TNS_RCAP_COMPAT] = constants.TNS_RCAP_COMPAT_81;
this.runtimeCaps[constants.TNS_RCAP_TTC] =
constants.TNS_RCAP_TTC_ZERO_COPY | constants.TNS_RCAP_TTC_32K;
}
checkNCharsetId() {
if (this.nCharsetId !== constants.TNS_CHARSET_UTF16) {
errors.throwErr(errors.ERR_NCHAR_CS_NOT_SUPPORTED, this.nCharsetId);
}
}
}
module.exports = Capabilities;

View File

@ -0,0 +1,730 @@
// Copyright (c) 2022, 2023, Oracle and/or its affiliates.
//-----------------------------------------------------------------------------
//
// This software is dual-licensed to you under the Universal Permissive License
// (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
// 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
// either license.
//
// If you elect to accept the software under the Apache License, Version 2.0,
// the following applies:
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://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 constants = require('../../constants.js');
module.exports = {
// constants from upper level exposed here in order to avoid having multiple
// files containing constants
BIND_IN: constants.BIND_IN,
CLIENT_VERSION:
constants.VERSION_MAJOR << 24 |
constants.VERSION_MINOR << 20 |
constants.VERSION_PATCH << 12,
DRIVER_NAME: constants.DEFAULT_DRIVER_NAME + ' thn',
SYSASM: constants.SYSASM,
SYSBKP: constants.SYSBKP,
SYSDBA: constants.SYSDBA,
SYSDG: constants.SYSDG,
SYSKM: constants.SYSKM,
SYSOPER: constants.SYSOPER,
SYSRAC: constants.SYSRAC,
// authentication modes
AUTH_MODE_DEFAULT: 0,
AUTH_MODE_PRELIM : 0x00000008,
AUTH_MODE_SYSASM : 0x00008000,
AUTH_MODE_SYSBKP : 0x00020000,
AUTH_MODE_SYSDBA : 0x00000002,
AUTH_MODE_SYSDGD : 0x00040000,
AUTH_MODE_SYSKMT : 0x00080000,
AUTH_MODE_SYSOPER: 0x00000004,
AUTH_MODE_SYSRAC : 0x00100000,
// TTC authentication modes
TNS_AUTH_MODE_LOGON: 0x00000001,
TNS_AUTH_MODE_CHANGE_PASSWORD: 0x00000002,
TNS_AUTH_MODE_SYSDBA: 0x00000020,
TNS_AUTH_MODE_SYSOPER: 0x00000040,
TNS_AUTH_MODE_PRELIM: 0x00000080,
TNS_AUTH_MODE_WITH_PASSWORD: 0x00000100,
TNS_AUTH_MODE_SYSASM: 0x00400000,
TNS_AUTH_MODE_SYSBKP: 0x01000000,
TNS_AUTH_MODE_SYSDGD: 0x02000000,
TNS_AUTH_MODE_SYSKMT: 0x04000000,
TNS_AUTH_MODE_SYSRAC: 0x08000000,
TNS_AUTH_MODE_IAM_TOKEN: 0x20000000,
// packet types
TNS_PACKET_TYPE_CONNECT: 1,
TNS_PACKET_TYPE_ACCEPT: 2,
TNS_PACKET_TYPE_REFUSE: 4,
TNS_PACKET_TYPE_REDIRECT: 5,
TNS_PACKET_TYPE_DATA: 6,
TNS_PACKET_TYPE_RESEND: 11,
TNS_PACKET_TYPE_MARKER: 12,
TNS_PACKET_TYPE_CONTROL: 14,
// marker types
TNS_MARKER_TYPE_BREAK: 1,
TNS_MARKER_TYPE_RESET: 2,
// charset forms
TNS_CS_IMPLICIT: 1,
TNS_CS_NCHAR: 2,
// data types
TNS_DATA_TYPE_DEFAULT: 0,
TNS_DATA_TYPE_VARCHAR: 1,
TNS_DATA_TYPE_NUMBER: 2,
TNS_DATA_TYPE_BINARY_INTEGER: 3,
TNS_DATA_TYPE_FLOAT: 4,
TNS_DATA_TYPE_STR: 5,
TNS_DATA_TYPE_VNU: 6,
TNS_DATA_TYPE_PDN: 7,
TNS_DATA_TYPE_LONG: 8,
TNS_DATA_TYPE_VCS: 9,
TNS_DATA_TYPE_TIDDEF: 10,
TNS_DATA_TYPE_ROWID: 11,
TNS_DATA_TYPE_DATE: 12,
TNS_DATA_TYPE_VBI: 15,
TNS_DATA_TYPE_RAW: 23,
TNS_DATA_TYPE_LONG_RAW: 24,
TNS_DATA_TYPE_UB2: 25,
TNS_DATA_TYPE_UB4: 26,
TNS_DATA_TYPE_SB1: 27,
TNS_DATA_TYPE_SB2: 28,
TNS_DATA_TYPE_SB4: 29,
TNS_DATA_TYPE_SWORD: 30,
TNS_DATA_TYPE_UWORD: 31,
TNS_DATA_TYPE_PTRB: 32,
TNS_DATA_TYPE_PTRW: 33,
TNS_DATA_TYPE_OER8: 34 + 256,
TNS_DATA_TYPE_FUN: 35 + 256,
TNS_DATA_TYPE_AUA: 36 + 256,
TNS_DATA_TYPE_RXH7: 37 + 256,
TNS_DATA_TYPE_NA6: 38 + 256,
TNS_DATA_TYPE_OAC: 39,
TNS_DATA_TYPE_AMS: 40,
TNS_DATA_TYPE_BRN: 41,
TNS_DATA_TYPE_BRP: 42 + 256,
TNS_DATA_TYPE_BRV: 43 + 256,
TNS_DATA_TYPE_KVA: 44 + 256,
TNS_DATA_TYPE_CLS: 45 + 256,
TNS_DATA_TYPE_CUI: 46 + 256,
TNS_DATA_TYPE_DFN: 47 + 256,
TNS_DATA_TYPE_DQR: 48 + 256,
TNS_DATA_TYPE_DSC: 49 + 256,
TNS_DATA_TYPE_EXE: 50 + 256,
TNS_DATA_TYPE_FCH: 51 + 256,
TNS_DATA_TYPE_GBV: 52 + 256,
TNS_DATA_TYPE_GEM: 53 + 256,
TNS_DATA_TYPE_GIV: 54 + 256,
TNS_DATA_TYPE_OKG: 55 + 256,
TNS_DATA_TYPE_HMI: 56 + 256,
TNS_DATA_TYPE_INO: 57 + 256,
TNS_DATA_TYPE_LNF: 59 + 256,
TNS_DATA_TYPE_ONT: 60 + 256,
TNS_DATA_TYPE_OPE: 61 + 256,
TNS_DATA_TYPE_OSQ: 62 + 256,
TNS_DATA_TYPE_SFE: 63 + 256,
TNS_DATA_TYPE_SPF: 64 + 256,
TNS_DATA_TYPE_VSN: 65 + 256,
TNS_DATA_TYPE_UD7: 66 + 256,
TNS_DATA_TYPE_DSA: 67 + 256,
TNS_DATA_TYPE_UIN: 68,
TNS_DATA_TYPE_PIN: 71 + 256,
TNS_DATA_TYPE_PFN: 72 + 256,
TNS_DATA_TYPE_PPT: 73 + 256,
TNS_DATA_TYPE_STO: 75 + 256,
TNS_DATA_TYPE_ARC: 77 + 256,
TNS_DATA_TYPE_MRS: 78 + 256,
TNS_DATA_TYPE_MRT: 79 + 256,
TNS_DATA_TYPE_MRG: 80 + 256,
TNS_DATA_TYPE_MRR: 81 + 256,
TNS_DATA_TYPE_MRC: 82 + 256,
TNS_DATA_TYPE_VER: 83 + 256,
TNS_DATA_TYPE_LON2: 84 + 256,
TNS_DATA_TYPE_INO2: 85 + 256,
TNS_DATA_TYPE_ALL: 86 + 256,
TNS_DATA_TYPE_UDB: 87 + 256,
TNS_DATA_TYPE_AQI: 88 + 256,
TNS_DATA_TYPE_ULB: 89 + 256,
TNS_DATA_TYPE_ULD: 90 + 256,
TNS_DATA_TYPE_SLS: 91,
TNS_DATA_TYPE_SID: 92 + 256,
TNS_DATA_TYPE_NA7: 93 + 256,
TNS_DATA_TYPE_LVC: 94,
TNS_DATA_TYPE_LVB: 95,
TNS_DATA_TYPE_CHAR: 96,
TNS_DATA_TYPE_AVC: 97,
TNS_DATA_TYPE_AL7: 98 + 256,
TNS_DATA_TYPE_K2RPC: 99 + 256,
TNS_DATA_TYPE_BINARY_FLOAT: 100,
TNS_DATA_TYPE_BINARY_DOUBLE: 101,
TNS_DATA_TYPE_CURSOR: 102,
TNS_DATA_TYPE_RDD: 104,
TNS_DATA_TYPE_XDP: 103 + 256,
TNS_DATA_TYPE_OSL: 106,
TNS_DATA_TYPE_OKO8: 107 + 256,
TNS_DATA_TYPE_EXT_NAMED: 108,
TNS_DATA_TYPE_INT_NAMED: 109,
TNS_DATA_TYPE_EXT_REF: 110,
TNS_DATA_TYPE_INT_REF: 111,
TNS_DATA_TYPE_CLOB: 112,
TNS_DATA_TYPE_BLOB: 113,
TNS_DATA_TYPE_BFILE: 114,
TNS_DATA_TYPE_CFILE: 115,
TNS_DATA_TYPE_RSET: 116,
TNS_DATA_TYPE_CWD: 117,
TNS_DATA_TYPE_JSON: 119,
TNS_DATA_TYPE_NEW_OAC: 120,
TNS_DATA_TYPE_UD12: 124 + 256,
TNS_DATA_TYPE_AL8: 125 + 256,
TNS_DATA_TYPE_LFOP: 126 + 256,
TNS_DATA_TYPE_FCRT: 127 + 256,
TNS_DATA_TYPE_DNY: 128 + 256,
TNS_DATA_TYPE_OPR: 129 + 256,
TNS_DATA_TYPE_PLS: 130 + 256,
TNS_DATA_TYPE_XID: 131 + 256,
TNS_DATA_TYPE_TXN: 132 + 256,
TNS_DATA_TYPE_DCB: 133 + 256,
TNS_DATA_TYPE_CCA: 134 + 256,
TNS_DATA_TYPE_WRN: 135 + 256,
TNS_DATA_TYPE_TLH: 137 + 256,
TNS_DATA_TYPE_TOH: 138 + 256,
TNS_DATA_TYPE_FOI: 139 + 256,
TNS_DATA_TYPE_SID2: 140 + 256,
TNS_DATA_TYPE_TCH: 141 + 256,
TNS_DATA_TYPE_PII: 142 + 256,
TNS_DATA_TYPE_PFI: 143 + 256,
TNS_DATA_TYPE_PPU: 144 + 256,
TNS_DATA_TYPE_PTE: 145 + 256,
TNS_DATA_TYPE_CLV: 146,
TNS_DATA_TYPE_RXH8: 148 + 256,
TNS_DATA_TYPE_N12: 149 + 256,
TNS_DATA_TYPE_AUTH: 150 + 256,
TNS_DATA_TYPE_KVAL: 151 + 256,
TNS_DATA_TYPE_DTR: 152,
TNS_DATA_TYPE_DUN: 153,
TNS_DATA_TYPE_DOP: 154,
TNS_DATA_TYPE_VST: 155,
TNS_DATA_TYPE_ODT: 156,
TNS_DATA_TYPE_FGI: 157 + 256,
TNS_DATA_TYPE_DSY: 158 + 256,
TNS_DATA_TYPE_DSYR8: 159 + 256,
TNS_DATA_TYPE_DSYH8: 160 + 256,
TNS_DATA_TYPE_DSYL: 161 + 256,
TNS_DATA_TYPE_DSYT8: 162 + 256,
TNS_DATA_TYPE_DSYV8: 163 + 256,
TNS_DATA_TYPE_DSYP: 164 + 256,
TNS_DATA_TYPE_DSYF: 165 + 256,
TNS_DATA_TYPE_DSYK: 166 + 256,
TNS_DATA_TYPE_DSYY: 167 + 256,
TNS_DATA_TYPE_DSYQ: 168 + 256,
TNS_DATA_TYPE_DSYC: 169 + 256,
TNS_DATA_TYPE_DSYA: 170 + 256,
TNS_DATA_TYPE_OT8: 171 + 256,
TNS_DATA_TYPE_DOL: 172,
TNS_DATA_TYPE_DSYTY: 173 + 256,
TNS_DATA_TYPE_AQE: 174 + 256,
TNS_DATA_TYPE_KV: 175 + 256,
TNS_DATA_TYPE_AQD: 176 + 256,
TNS_DATA_TYPE_AQ8: 177 + 256,
TNS_DATA_TYPE_TIME: 178,
TNS_DATA_TYPE_TIME_TZ: 179,
TNS_DATA_TYPE_TIMESTAMP: 180,
TNS_DATA_TYPE_TIMESTAMP_TZ: 181,
TNS_DATA_TYPE_INTERVAL_YM: 182,
TNS_DATA_TYPE_INTERVAL_DS: 183,
TNS_DATA_TYPE_EDATE: 184,
TNS_DATA_TYPE_ETIME: 185,
TNS_DATA_TYPE_ETTZ: 186,
TNS_DATA_TYPE_ESTAMP: 187,
TNS_DATA_TYPE_ESTZ: 188,
TNS_DATA_TYPE_EIYM: 189,
TNS_DATA_TYPE_EIDS: 190,
TNS_DATA_TYPE_RFS: 193 + 256,
TNS_DATA_TYPE_RXH10: 194 + 256,
TNS_DATA_TYPE_DCLOB: 195,
TNS_DATA_TYPE_DBLOB: 196,
TNS_DATA_TYPE_DBFILE: 197,
TNS_DATA_TYPE_DJSON: 198,
TNS_DATA_TYPE_KPN: 198 + 256,
TNS_DATA_TYPE_KPDNR: 199 + 256,
TNS_DATA_TYPE_DSYD: 200 + 256,
TNS_DATA_TYPE_DSYS: 201 + 256,
TNS_DATA_TYPE_DSYR: 202 + 256,
TNS_DATA_TYPE_DSYH: 203 + 256,
TNS_DATA_TYPE_DSYT: 204 + 256,
TNS_DATA_TYPE_DSYV: 205 + 256,
TNS_DATA_TYPE_AQM: 206 + 256,
TNS_DATA_TYPE_OER11: 207 + 256,
TNS_DATA_TYPE_UROWID: 208,
TNS_DATA_TYPE_AQL: 210 + 256,
TNS_DATA_TYPE_OTC: 211 + 256,
TNS_DATA_TYPE_KFNO: 212 + 256,
TNS_DATA_TYPE_KFNP: 213 + 256,
TNS_DATA_TYPE_KGT8: 214 + 256,
TNS_DATA_TYPE_RASB4: 215 + 256,
TNS_DATA_TYPE_RAUB2: 216 + 256,
TNS_DATA_TYPE_RAUB1: 217 + 256,
TNS_DATA_TYPE_RATXT: 218 + 256,
TNS_DATA_TYPE_RSSB4: 219 + 256,
TNS_DATA_TYPE_RSUB2: 220 + 256,
TNS_DATA_TYPE_RSUB1: 221 + 256,
TNS_DATA_TYPE_RSTXT: 222 + 256,
TNS_DATA_TYPE_RIDL: 223 + 256,
TNS_DATA_TYPE_GLRDD: 224 + 256,
TNS_DATA_TYPE_GLRDG: 225 + 256,
TNS_DATA_TYPE_GLRDC: 226 + 256,
TNS_DATA_TYPE_OKO: 227 + 256,
TNS_DATA_TYPE_DPP: 228 + 256,
TNS_DATA_TYPE_DPLS: 229 + 256,
TNS_DATA_TYPE_DPMOP: 230 + 256,
TNS_DATA_TYPE_TIMESTAMP_LTZ: 231,
TNS_DATA_TYPE_ESITZ: 232,
TNS_DATA_TYPE_UB8: 233,
TNS_DATA_TYPE_STAT: 234 + 256,
TNS_DATA_TYPE_RFX: 235 + 256,
TNS_DATA_TYPE_FAL: 236 + 256,
TNS_DATA_TYPE_CKV: 237 + 256,
TNS_DATA_TYPE_DRCX: 238 + 256,
TNS_DATA_TYPE_KGH: 239 + 256,
TNS_DATA_TYPE_AQO: 240 + 256,
TNS_DATA_TYPE_PNTY: 241,
TNS_DATA_TYPE_OKGT: 242 + 256,
TNS_DATA_TYPE_KPFC: 243 + 256,
TNS_DATA_TYPE_FE2: 244 + 256,
TNS_DATA_TYPE_SPFP: 245 + 256,
TNS_DATA_TYPE_DPULS: 246 + 256,
TNS_DATA_TYPE_BOOLEAN: 252,
TNS_DATA_TYPE_AQA: 253 + 256,
TNS_DATA_TYPE_KPBF: 254 + 256,
TNS_DATA_TYPE_TSM: 513,
TNS_DATA_TYPE_MSS: 514,
TNS_DATA_TYPE_KPC: 516,
TNS_DATA_TYPE_CRS: 517,
TNS_DATA_TYPE_KKS: 518,
TNS_DATA_TYPE_KSP: 519,
TNS_DATA_TYPE_KSPTOP: 520,
TNS_DATA_TYPE_KSPVAL: 521,
TNS_DATA_TYPE_PSS: 522,
TNS_DATA_TYPE_NLS: 523,
TNS_DATA_TYPE_ALS: 524,
TNS_DATA_TYPE_KSDEVTVAL: 525,
TNS_DATA_TYPE_KSDEVTTOP: 526,
TNS_DATA_TYPE_KPSPP: 527,
TNS_DATA_TYPE_KOL: 528,
TNS_DATA_TYPE_LST: 529,
TNS_DATA_TYPE_ACX: 530,
TNS_DATA_TYPE_SCS: 531,
TNS_DATA_TYPE_RXH: 532,
TNS_DATA_TYPE_KPDNS: 533,
TNS_DATA_TYPE_KPDCN: 534,
TNS_DATA_TYPE_KPNNS: 535,
TNS_DATA_TYPE_KPNCN: 536,
TNS_DATA_TYPE_KPS: 537,
TNS_DATA_TYPE_APINF: 538,
TNS_DATA_TYPE_TEN: 539,
TNS_DATA_TYPE_XSSCS: 540,
TNS_DATA_TYPE_XSSSO: 541,
TNS_DATA_TYPE_XSSAO: 542,
TNS_DATA_TYPE_KSRPC: 543,
TNS_DATA_TYPE_KVL: 560,
TNS_DATA_TYPE_SESSGET: 563,
TNS_DATA_TYPE_SESSREL: 564,
TNS_DATA_TYPE_XSSDEF: 565,
TNS_DATA_TYPE_PDQCINV: 572,
TNS_DATA_TYPE_PDQIDC: 573,
TNS_DATA_TYPE_KPDQCSTA: 574,
TNS_DATA_TYPE_KPRS: 575,
TNS_DATA_TYPE_KPDQIDC: 576,
TNS_DATA_TYPE_RTSTRM: 578,
TNS_DATA_TYPE_SESSRET: 579,
TNS_DATA_TYPE_SCN6: 580,
TNS_DATA_TYPE_KECPA: 581,
TNS_DATA_TYPE_KECPP: 582,
TNS_DATA_TYPE_SXA: 583,
TNS_DATA_TYPE_KVARR: 584,
TNS_DATA_TYPE_KPNGN: 585,
TNS_DATA_TYPE_XSNSOP: 590,
TNS_DATA_TYPE_XSATTR: 591,
TNS_DATA_TYPE_XSNS: 592,
TNS_DATA_TYPE_TXT: 593,
TNS_DATA_TYPE_XSSESSNS: 594,
TNS_DATA_TYPE_XSATTOP: 595,
TNS_DATA_TYPE_XSCREOP: 596,
TNS_DATA_TYPE_XSDETOP: 597,
TNS_DATA_TYPE_XSDESOP: 598,
TNS_DATA_TYPE_XSSETSP: 599,
TNS_DATA_TYPE_XSSIDP: 600,
TNS_DATA_TYPE_XSPRIN: 601,
TNS_DATA_TYPE_XSKVL: 602,
TNS_DATA_TYPE_XSSSDEF2: 603,
TNS_DATA_TYPE_XSNSOP2: 604,
TNS_DATA_TYPE_XSNS2: 605,
TNS_DATA_TYPE_IMPLRES: 611,
TNS_DATA_TYPE_OER: 612,
TNS_DATA_TYPE_UB1ARRAY: 613,
TNS_DATA_TYPE_SESSSTATE: 614,
TNS_DATA_TYPE_AC_REPLAY: 615,
TNS_DATA_TYPE_AC_CONT: 616,
TNS_DATA_TYPE_KPDNREQ: 622,
TNS_DATA_TYPE_KPDNRNF: 623,
TNS_DATA_TYPE_KPNGNC: 624,
TNS_DATA_TYPE_KPNRI: 625,
TNS_DATA_TYPE_AQENQ: 626,
TNS_DATA_TYPE_AQDEQ: 627,
TNS_DATA_TYPE_AQJMS: 628,
TNS_DATA_TYPE_KPDNRPAY: 629,
TNS_DATA_TYPE_KPDNRACK: 630,
TNS_DATA_TYPE_KPDNRMP: 631,
TNS_DATA_TYPE_KPDNRDQ: 632,
TNS_DATA_TYPE_CHUNKINFO: 636,
TNS_DATA_TYPE_SCN: 637,
TNS_DATA_TYPE_SCN8: 638,
TNS_DATA_TYPE_UDS: 639,
TNS_DATA_TYPE_TNP: 640,
// data type representations
TNS_TYPE_REP_NATIVE: 0,
TNS_TYPE_REP_UNIVERSAL: 1,
TNS_TYPE_REP_ORACLE: 10,
// message types
TNS_MSG_TYPE_PROTOCOL: 1,
TNS_MSG_TYPE_DATA_TYPES: 2,
TNS_MSG_TYPE_FUNCTION: 3,
TNS_MSG_TYPE_ERROR: 4,
TNS_MSG_TYPE_ROW_HEADER: 6,
TNS_MSG_TYPE_ROW_DATA: 7,
TNS_MSG_TYPE_PARAMETER: 8,
TNS_MSG_TYPE_STATUS: 9,
TNS_MSG_TYPE_IO_VECTOR: 11,
TNS_MSG_TYPE_LOB_DATA: 14,
TNS_MSG_TYPE_WARNING: 15,
TNS_MSG_TYPE_DESCRIBE_INFO: 16,
TNS_MSG_TYPE_PIGGYBACK: 17,
TNS_MSG_TYPE_FLUSH_OUT_BINDS: 19,
TNS_MSG_TYPE_BIT_VECTOR: 21,
TNS_MSG_TYPE_SERVER_SIDE_PIGGYBACK: 23,
TNS_MSG_TYPE_IMPLICIT_RESULTSET: 27,
TNS_MSG_TYPE_ONEWAY_FN: 26,
// parameter keyword numbers,
TNS_KEYWORD_AL8KW_TIMEZONE: 163,
TNS_KEYWORD_NUM_CURRENT_SCHEMA: 168,
TNS_KEYWORD_NUM_EDITION: 172,
// bind flags
TNS_BIND_USE_INDICATORS: 0x0001,
TNS_BIND_USE_LENGTH: 0x0002,
TNS_BIND_ARRAY: 0x0040,
// bind directions
TNS_BIND_DIR_OUTPUT: 16,
TNS_BIND_DIR_INPUT: 32,
TNS_BIND_DIR_INPUT_OUTPUT: 48,
// execute options
TNS_EXEC_OPTION_PARSE: 0x01,
TNS_EXEC_OPTION_BIND: 0x08,
TNS_EXEC_OPTION_DEFINE: 0x10,
TNS_EXEC_OPTION_EXECUTE: 0x20,
TNS_EXEC_OPTION_FETCH: 0x40,
TNS_EXEC_OPTION_COMMIT: 0x100,
TNS_EXEC_OPTION_COMMIT_REEXECUTE: 0x1,
TNS_EXEC_OPTION_PLSQL_BIND: 0x400,
TNS_EXEC_OPTION_DML_ROWCOUNTS: 0x4000,
TNS_EXEC_OPTION_NOT_PLSQL: 0x8000,
TNS_EXEC_OPTION_IMPLICIT_RESULTSET: 0x8000,
TNS_EXEC_OPTION_DESCRIBE: 0x20000,
TNS_EXEC_OPTION_NO_COMPRESSED_FETCH: 0x40000,
TNS_EXEC_OPTION_BATCH_ERRORS: 0x80000,
// server side piggyback op codes
TNS_SERVER_PIGGYBACK_QUERY_CACHE_INVALIDATION: 1,
TNS_SERVER_PIGGYBACK_OS_PID_MTS: 2,
TNS_SERVER_PIGGYBACK_TRACE_EVENT: 3,
TNS_SERVER_PIGGYBACK_SESS_RET: 4,
TNS_SERVER_PIGGYBACK_SYNC: 5,
TNS_SERVER_PIGGYBACK_LTXID: 7,
TNS_SERVER_PIGGYBACK_AC_REPLAY_CONTEXT: 8,
TNS_SERVER_PIGGYBACK_EXT_SYNC: 9,
// session return constants
TNS_SESSGET_SESSION_CHANGED: 4,
// timezone constants
TNS_LDIREGIDFLAG: 120,
TNS_LDIREGIDSET: 181,
TNS_LDIMAXTIMEFIELD: 60,
// LOB operations
TNS_LOB_OP_GET_LENGTH: 0x0001,
TNS_LOB_OP_READ: 0x0002,
TNS_LOB_OP_TRIM: 0x0020,
TNS_LOB_OP_WRITE: 0x0040,
TNS_LOB_OP_GET_CHUNK_SIZE: 0x4000,
TNS_LOB_OP_CREATE_TEMP: 0x0110,
TNS_LOB_OP_FREE_TEMP: 0x0111,
TNS_LOB_OP_OPEN: 0x8000,
TNS_LOB_OP_CLOSE: 0x10000,
TNS_LOB_OP_IS_OPEN: 0x11000,
TNS_LOB_OP_ARRAY: 0x80000,
// LOB locator constants
TNS_LOB_LOC_OFFSET_FLAG_1: 4,
TNS_LOB_LOC_OFFSET_FLAG_3: 6,
TNS_LOB_LOC_OFFSET_FLAG_4: 7,
TNS_LOB_QLOCATOR_VERSION: 4,
// LOB locator flags (byte 1)
TNS_LOB_LOC_FLAGS_BLOB: 0x01,
TNS_LOB_LOC_FLAGS_VALUE_BASED: 0x20,
TNS_LOB_LOC_FLAGS_ABSTRACT: 0x40,
// LOB locator flags (byte 2)
TNS_LOB_LOC_FLAGS_INIT: 0x08,
// LOB locator flags (byte 4)
TNS_LOB_LOC_FLAGS_TEMP: 0x01,
TNS_LOB_LOC_FLAGS_VAR_LENGTH_CHARSET: 0x80,
// other LOB constants
TNS_LOB_OPEN_READ_WRITE: 2,
TNS_LOB_PREFETCH_FLAG: 0x2000000,
// base JSON constants
TNS_JSON_MAX_LENGTH: 32 * 1024 * 1024,
TNS_JSON_MAGIC_BYTE_1: 0xff,
TNS_JSON_MAGIC_BYTE_2: 0x4a, // 'J'
TNS_JSON_MAGIC_BYTE_3: 0x5a, // 'Z'
TNS_JSON_VERSION: 1,
TNS_JSON_FLAG_HASH_ID_UINT8: 0x0100,
TNS_JSON_FLAG_HASH_ID_UINT16: 0x0200,
TNS_JSON_FLAG_NUM_FNAMES_UINT16: 0x0400,
TNS_JSON_FLAG_FNAMES_SEG_UINT32: 0x0800,
TNS_JSON_FLAG_TINY_NODES_STAT: 0x2000,
TNS_JSON_FLAG_TREE_SEG_UINT32: 0x1000,
TNS_JSON_FLAG_REL_OFFSET_MODE: 0x01,
TNS_JSON_FLAG_INLINE_LEAF: 0x02,
TNS_JSON_FLAG_LEN_IN_PCODE: 0x04,
TNS_JSON_FLAG_NUM_FNAMES_UINT32: 0x08,
TNS_JSON_FLAG_IS_SCALAR: 0x10,
// JSON data types
TNS_JSON_TYPE_NULL: 0x30,
TNS_JSON_TYPE_TRUE: 0x31,
TNS_JSON_TYPE_FALSE: 0x32,
TNS_JSON_TYPE_STRING_LENGTH_UINT8: 0x33,
TNS_JSON_TYPE_NUMBER_LENGTH_UINT8: 0x34,
TNS_JSON_TYPE_BINARY_DOUBLE: 0x36,
TNS_JSON_TYPE_STRING_LENGTH_UINT16: 0x37,
TNS_JSON_TYPE_STRING_LENGTH_UINT32: 0x38,
TNS_JSON_TYPE_TIMESTAMP: 0x39,
TNS_JSON_TYPE_BINARY_LENGTH_UINT16: 0x3a,
TNS_JSON_TYPE_BINARY_LENGTH_UINT32: 0x3b,
TNS_JSON_TYPE_DATE: 0x3c,
TNS_JSON_TYPE_INTERVAL_YM: 0x3d,
TNS_JSON_TYPE_INTERVAL_DS: 0x3e,
TNS_JSON_TYPE_TIMESTAMP_TZ: 0x7c,
TNS_JSON_TYPE_TIMESTAMP7: 0x7d,
TNS_JSON_TYPE_BINARY_FLOAT: 0x7f,
TNS_JSON_TYPE_OBJECT: 0x84,
TNS_JSON_TYPE_ARRAY: 0xc0,
// end-to-end metrics
TNS_END_TO_END_ACTION: 0x0010,
TNS_END_TO_END_CLIENT_IDENTIFIER: 0x0001,
TNS_END_TO_END_CLIENT_INFO: 0x0100,
TNS_END_TO_END_DBOP: 0x0200,
TNS_END_TO_END_MODULE: 0x0008,
// versions
TNS_VERSION_DESIRED: 316,
TNS_VERSION_MINIMUM: 300,
TNS_VERSION_MIN_LARGE_SDU: 315,
// other connection constants
TNS_SERVICE_OPTIONS: 0xc01,
TNS_PROTOCOL_CHARACTERISTICS: 0x4f98,
TNS_CONNECT_FLAGS: 0x8080,
TNS_CAN_RECV_ATTENTION: 0x0400,
TNS_CHECK_OOB: 0x01,
// TTC functions
TNS_FUNC_AUTH_PHASE_ONE: 118,
TNS_FUNC_AUTH_PHASE_TWO: 115,
TNS_FUNC_CLOSE_CURSORS: 105,
TNS_FUNC_COMMIT: 14,
TNS_FUNC_EXECUTE: 94,
TNS_FUNC_FETCH: 5,
TNS_FUNC_LOB_OP: 96,
TNS_FUNC_LOGOFF: 9,
TNS_FUNC_PING: 147,
TNS_FUNC_ROLLBACK: 15,
TNS_FUNC_SET_END_TO_END_ATTR: 135,
TNS_FUNC_REEXECUTE: 4,
TNS_FUNC_REEXECUTE_AND_FETCH: 78,
TNS_FUNC_SET_SCHEMA: 152,
TNS_FUNC_SESSION_GET: 162,
TNS_FUNC_SESSION_RELEASE: 163,
TNS_FUNC_SESSION_STATE: 176, // piggyback fn
TNS_FUNC_CANCEL_ALL: 120, // piggyback fn
// character sets and encodings
TNS_CHARSET_UTF8: 873,
TNS_CHARSET_UTF16: 2000,
TNS_ENCODING_UTF8: "UTF-8",
TNS_ENCODING_UTF16: "UTF-16LE",
TNS_ENCODING_MULTI_BYTE: 0x01,
TNS_ENCODING_CONV_LENGTH: 0x02,
// compile time capability indices
TNS_CCAP_SQL_VERSION: 0,
TNS_CCAP_LOGON_TYPES: 4,
TNS_CCAP_FIELD_VERSION: 7,
TNS_CCAP_SERVER_DEFINE_CONV: 8,
TNS_CCAP_TTC1: 15,
TNS_CCAP_OCI1: 16,
TNS_CCAP_TDS_VERSION: 17,
TNS_CCAP_RPC_VERSION: 18,
TNS_CCAP_RPC_SIG: 19,
TNS_CCAP_DBF_VERSION: 21,
TNS_CCAP_LOB: 23,
TNS_CCAP_TTC2: 26,
TNS_CCAP_UB2_DTY: 27,
TNS_CCAP_OCI2: 31,
TNS_CCAP_CLIENT_FN: 34,
TNS_CCAP_TTC3: 37,
TNS_CCAP_TTC4: 40,
TNS_CCAP_LOB2: 42,
TNS_CCAP_MAX: 45,
// compile time capability values
TNS_CCAP_SQL_VERSION_MAX: 6,
TNS_CCAP_FIELD_VERSION_11_2: 6,
TNS_CCAP_FIELD_VERSION_12_1: 7,
TNS_CCAP_FIELD_VERSION_12_2: 8,
TNS_CCAP_FIELD_VERSION_12_2_EXT1: 9,
TNS_CCAP_FIELD_VERSION_18_1: 10,
TNS_CCAP_FIELD_VERSION_18_1_EXT_1: 11,
TNS_CCAP_FIELD_VERSION_19_1: 12,
TNS_CCAP_FIELD_VERSION_19_1_EXT_1: 13,
TNS_CCAP_FIELD_VERSION_20_1: 14,
TNS_CCAP_FIELD_VERSION_20_1_EXT_1: 15,
TNS_CCAP_FIELD_VERSION_21_1: 16,
TNS_CCAP_FIELD_VERSION_23_1: 17,
TNS_CCAP_FIELD_VERSION_23_1_EXT_1: 18,
TNS_CCAP_FIELD_VERSION_MAX: 18,
TNS_CCAP_O5LOGON: 8,
TNS_CCAP_O5LOGON_NP: 2,
TNS_CCAP_O7LOGON: 32,
TNS_CCAP_O8LOGON_LONG_IDENTIFIER: 64,
TNS_CCAP_O9LOGON_LONG_PASSWORD: 0x80,
TNS_CCAP_END_OF_CALL_STATUS: 0x01,
TNS_CCAP_IND_RCD: 0x08,
TNS_CCAP_FAST_BVEC: 0x20,
TNS_CCAP_FAST_SESSION_PROPAGATE: 0x10,
TNS_CCAP_APP_CTX_PIGGYBACK: 0x80,
TNS_CCAP_TDS_VERSION_MAX: 3,
TNS_CCAP_RPC_VERSION_MAX: 7,
TNS_CCAP_RPC_SIG_VALUE: 3,
TNS_CCAP_DBF_VERSION_MAX: 1,
TNS_CCAP_IMPLICIT_RESULTS: 0x10,
TNS_CCAP_BIG_CHUNK_CLR: 0x20,
TNS_CCAP_KEEP_OUT_ORDER: 0x80,
TNS_CCAP_LOB_UB8_SIZE: 0x01,
TNS_CCAP_LOB_ENCS: 0x02,
TNS_CCAP_LOB_PREFETCH: 0x40,
TNS_CCAP_DRCP: 0x10,
TNS_CCAP_ZLNP: 0x04,
TNS_CCAP_INBAND_NOTIFICATION: 0x04,
TNS_CCAP_CLIENT_FN_MAX: 12,
TNS_CCAP_LOB2_QUASI: 0x01,
TNS_CCAP_LOB2_2GB_PREFETCH: 0x04,
// runtime capability indices
TNS_RCAP_COMPAT: 0,
TNS_RCAP_TTC: 6,
TNS_RCAP_MAX: 7,
// runtime capability values
TNS_RCAP_COMPAT_81: 2,
TNS_RCAP_TTC_ZERO_COPY: 0x01,
TNS_RCAP_TTC_32K: 0x04,
/** Verifier types. */
/** SHA1 (salted). */
TNS_VERIFIER_TYPE_11G_1: 0xb152,
TNS_VERIFIER_TYPE_11G_2: 0x1b25,
/** MultiRound SHA-512. */
TNS_VERIFIER_TYPE_12C: 0x4815,
// other constants
TNS_MAX_SHORT_LENGTH: 252,
TNS_ESCAPE_CHAR: 253,
TNS_LONG_LENGTH_INDICATOR: 254,
TNS_NULL_LENGTH_INDICATOR: 255,
TNS_MAX_ROWID_LENGTH: 18,
TNS_DURATION_MID: 0x80000000,
TNS_DURATION_OFFSET: 60,
TNS_DURATION_SESSION: 10,
TNS_MIN_LONG_LENGTH: 0x8000,
TNS_MAX_LONG_LENGTH: 0x7fffffff,
TNS_SDU: 8192,
TNS_TDU: 65535,
TNS_TXN_IN_PROGRESS: 0x00000002,
TNS_MAX_CONNECT_DATA: 230,
TNS_CHUNK_SIZE: 32767,
TNS_MAX_UROWID_LENGTH: 3950,
TNS_HAS_REGION_ID: 0x80,
// timezone offsets
TZ_HOUR_OFFSET: 20,
TZ_MINUTE_OFFSET: 60,
// Preferred Num Types
NUM_TYPE_FLOAT: 0,
NUM_TYPE_INT: 1,
NUM_TYPE_DECIMAL: 2,
NUM_TYPE_STR: 3,
// drcp release mode
DRCP_DEAUTHENTICATE: 0x00000002,
// errors
TNS_ERR_VAR_NOT_IN_SELECT_LIST: 1007,
TNS_ERR_INBAND_MESSAGE: 12573,
TNS_ERR_INVALID_SERVICE_NAME: 12514,
TNS_ERR_INVALID_SID: 12505,
TNS_ERR_NO_DATA_FOUND: 1403,
TNS_ERR_SESSION_SHUTDOWN: 12572,
// other constants
PACKET_HEADER_SIZE: 8,
NUMBER_AS_TEXT_CHARS: 172,
NUMBER_MAX_DIGITS: 40,
BUFFER_CHUNK_SIZE: 65536,
CHUNKED_BYTES_CHUNK_SIZE: 65536,
TNS_BASE64_ALPHABET_ARRAY: Buffer.from('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/')
};

View File

@ -0,0 +1,185 @@
// Copyright (c) 2022, Oracle and/or its affiliates.
//-----------------------------------------------------------------------------
//
// This software is dual-licensed to you under the Universal Permissive License
// (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
// 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
// either license.
//
// If you elect to accept the software under the Apache License, Version 2.0,
// the following applies:
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://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 Buffer = require('buffer').Buffer;
const crypto = require('crypto');
let algorithm = 'aes-256-cbc';
const _appendBuffer = Buffer.from([0x00, 0x01]);
/**
* A single Instance which handles all Encrypt, Decrypt,
* hash related to password verifiers.
*/
class EncryptDecrypt {
// Key length is dependent on the algorithm. In this case for aes192, it is
// 24 bytes (192 bits).
_decrypt(key, val) {
const iv = Buffer.alloc(16, 0); // Initialization vector, same is used in server
const decipher = crypto.createDecipheriv(algorithm, key, iv);
decipher.setAutoPadding(false);
let decrypted = decipher.update(val);
decrypted = Buffer.concat([decrypted, decipher.final()]);
return decrypted;
}
_encrypt(key, val, padding) {
let block_size = 16;
const iv = Buffer.alloc(block_size, 0);
let n = block_size - (val.length % block_size);
const nv = Buffer.alloc(n, n);
if (n > 0) {
if (padding) {
val += Buffer.alloc(n);
} else {
val = Buffer.concat([val, nv]);
}
}
const cipher = crypto.createCipheriv(algorithm, key, iv);
let encrypted = cipher.update(val);
encrypted = Buffer.concat([encrypted, cipher.final()]);
if (!padding) {
encrypted = encrypted.slice(0, val.length);
}
val.fill(0);
return encrypted;
}
// Encrypt password and newPassword using comboKey
_setEncryptedPasswordBuffers(passwordBytes, newPasswordBytes, comboKey, authObj) {
let salt = Buffer.alloc(16);
crypto.randomFillSync(salt, 0, 16);
let temp = Buffer.concat([salt, passwordBytes]);
authObj.encodedPassword = this._encrypt(comboKey, temp);
temp.fill(0);
authObj.encodedPassword = authObj.encodedPassword.slice().toString('hex').toUpperCase();
if (newPasswordBytes) {
let newPasswordWithSalt = Buffer.concat([salt, newPasswordBytes]);
authObj.encodedNewPassword = this._encrypt(comboKey, newPasswordWithSalt);
newPasswordWithSalt.fill(0);
authObj.encodedNewPassword = authObj.encodedNewPassword.slice().toString('hex').toUpperCase();
}
// reset Buffers
passwordBytes.fill(0);
if (newPasswordBytes) {
newPasswordBytes.fill(0);
}
}
/**
* updates authObject with required data.
*
* @param {object} sessionData The key/value pairs returned from OSESS key rpc
* @param {string} password Current Password of user
* @param {string} newPassword New password to be updated
* @param {boolean} verifier11G Verifier type 11g or not(12c)
*/
updateVerifierData(sessionData, password, newPassword, verifier11G, authObj) {
let keyLen = 32;
let hashAlg = 'sha512';
let verifierData = Buffer.from(sessionData['AUTH_VFR_DATA'], 'hex');
let encodedServerKey = Buffer.from(sessionData['AUTH_SESSKEY'], 'hex');
let iterations = Number(sessionData['AUTH_PBKDF2_VGEN_COUNT']);
let passwordBytes = Buffer.from(password, 'utf8');
let passwordHash;
let passwordKey;
if (verifier11G) {
algorithm = 'aes-192-cbc';
keyLen = 24;
hashAlg = 'sha1';
let h = crypto.createHash(hashAlg);
h.update(passwordBytes);
h.update(verifierData);
let ph = h.digest();
passwordHash = Buffer.alloc(ph.length + 4);
ph.copy(passwordHash, 0, 0, ph.length);
} else {
algorithm = 'aes-256-cbc';
let temp = Buffer.from('AUTH_PBKDF2_SPEEDY_KEY', 'utf8');
let salt = Buffer.concat([verifierData, temp]);
passwordKey = crypto.pbkdf2Sync(passwordBytes, salt, iterations, 64, 'sha512');
let h = crypto.createHash(hashAlg);
h.update(passwordKey);
h.update(verifierData);
passwordHash = h.digest().slice(0, keyLen);
}
let newPasswordBytes;
if (newPassword) {
newPasswordBytes = Buffer.from(newPassword, 'utf8');
}
let sessionKeyParta = this._decrypt(passwordHash, encodedServerKey);
let sessionKeyPartb = Buffer.alloc(32);
crypto.randomFillSync(sessionKeyPartb, 0, 32);
let encodedClientKey = this._encrypt(passwordHash, sessionKeyPartb);
authObj.sessionKey = encodedClientKey.slice().toString('hex').toUpperCase().slice(0, 64);
iterations = Number(sessionData['AUTH_PBKDF2_SDER_COUNT']);
let mixingSalt = Buffer.from(sessionData['AUTH_PBKDF2_CSK_SALT'], 'hex');
let partABKey = Buffer.concat([sessionKeyPartb.slice(0, keyLen), sessionKeyParta.slice(0, keyLen)]);
let partABKeyStr = partABKey.toString('hex').toUpperCase();
let partABKeyBuffer = Buffer.from(partABKeyStr, 'utf8');
authObj.comboKey = crypto.pbkdf2Sync(partABKeyBuffer, mixingSalt, iterations, keyLen, 'sha512');
let salt = Buffer.alloc(16);
if (!verifier11G) {
crypto.randomFillSync(salt, 0, 16);
let temp = Buffer.concat([salt, passwordKey]);
authObj.speedyKey = this._encrypt(authObj.comboKey, temp);
authObj.speedyKey = authObj.speedyKey.slice(0, 80).toString('hex').toUpperCase();
}
this._setEncryptedPasswordBuffers(passwordBytes, newPasswordBytes, authObj.comboKey, authObj);
}
getEncryptedJSWPData(sessionKey, jdwpData) {
let buf = this._encrypt(sessionKey, jdwpData, true);
// Add a "01" at the end of the hex encrypted data to indicate the
// use of AES encryption
buf = buf.slice().toString('hex').toUpperCase();
buf = Buffer.concat([buf, _appendBuffer]);
return buf;
}
updatePasswordsWithComboKey(password, newPassword, comboKey, authObj) {
let passwordBytes = Buffer.from(password, 'utf8');
let newPasswordBytes;
if (newPassword) {
newPasswordBytes = Buffer.from(newPassword, 'utf8');
}
this._setEncryptedPasswordBuffers(passwordBytes, newPasswordBytes, comboKey, authObj);
}
}
let encryptDecryptInst = new EncryptDecrypt();
module.exports = encryptDecryptInst;

View File

@ -0,0 +1,341 @@
// Copyright (c) 2022, 2023, Oracle and/or its affiliates.
//-----------------------------------------------------------------------------
//
// This software is dual-licensed to you under the Universal Permissive License
// (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
// 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
// either license.
//
// If you elect to accept the software under the Apache License, Version 2.0,
// the following applies:
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://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 constants = require("../constants.js");
const errors = require("../../../errors.js");
const os = require("os");
const process = require("process");
const ED = require("../encryptDecrypt.js");
const Message = require("./base.js");
const util = require("../../util.js");
const crypto = require('crypto');
/**
* Executes OSESSKEY and OAUTH RPC functions
*
* @class AuthMessage
* @extends {Message}
*/
class AuthMessage extends Message {
/**
* Represents the data required for OAUTH and OSESSKEY rpc.
*
* @param {object} conn Connection object
* @param {object} config Dynamic Configuration like change password config after connection is established
*/
constructor(conn, config) {
super(conn);
this.functionCode = constants.TNS_FUNC_AUTH_PHASE_ONE;
this.messageType = constants.TNS_MSG_TYPE_FUNCTION;
this.sessionData = {};
this.conn = conn;
this.sessionKey = "";
this.encodedPassword = "";
this.changePassword = false;
Object.defineProperty(this, 'password', {
enumerable: false,
value: config.password,
});
this.username = config.user;
if (this.username === undefined) {
this.username = "";
} else {
// trim leading and trailing spaces
this.username = this.username.trim();
}
this.schemaUser = '';
this.proxyUser = '';
this.proxyStatus = -1;
if (this.username.length !== 0) {
this.proxyStatusObj = util.checkProxyUserValidity(this.username);
if (this.proxyStatusObj.status === 0) {
this.proxyStatus = 0;
this.proxyUser = this.proxyStatusObj.proxyUser;
this.schemaUser = this.proxyStatusObj.schemaUser;
this.username = this.proxyUser;
}
}
this.newPassword = config.newPassword;
if (config.changePassword) {
// ChangePassword issued after login would use the same comboKey
// used in initial Login. We issue only OAUTH.
this.changePassword = true;
this.functionCode = constants.TNS_FUNC_AUTH_PHASE_TWO;
}
if (this.username) {
this.userByteLen = Buffer.byteLength(this.username); // Get utf8 encoded number of bytes
} else {
this.userByteLen = 0;
}
this.token = config.token;
if (this.token)
this.functionCode = constants.TNS_FUNC_AUTH_PHASE_TWO;
this.privateKey = config.privateKey;
if (this.privateKey) {
this.privateKey = '-----BEGIN PRIVATE KEY-----\n' + this.privateKey;
this.privateKey = this.privateKey + '\n' + '-----END PRIVATE KEY-----';
}
this.serviceName = this.conn.serviceName;
this.remoteAddress = this.conn.remoteAddress;
this.setAuthMode();
}
setAuthMode() {
if (!this.newPassword) {
this.authMode = constants.TNS_AUTH_MODE_LOGON;
}
if (this.conn.privilege & constants.SYSDBA) {
this.authMode |= constants.TNS_AUTH_MODE_SYSDBA;
}
if (this.conn.privilege & constants.SYSOPER) {
this.authMode |= constants.TNS_AUTH_MODE_SYSOPER;
}
if (this.conn.privilege & constants.SYSASM) {
this.authMode |= constants.TNS_AUTH_MODE_SYSASM;
}
if (this.conn.privilege & constants.SYSBKP) {
this.authMode |= constants.TNS_AUTH_MODE_SYSBKP;
}
if (this.conn.privilege & constants.SYSDG) {
this.authMode |= constants.TNS_AUTH_MODE_SYSDGD;
}
if (this.conn.privilege & constants.SYSKM) {
this.authMode |= constants.TNS_AUTH_MODE_SYSKMT;
}
if (this.conn.privilege & constants.SYSRAC) {
this.authMode |= constants.TNS_AUTH_MODE_SYSRAC;
}
if (this.privateKey) {
this.authMode |= constants.TNS_AUTH_MODE_IAM_TOKEN;
}
if (this.newPassword) {
this.authMode |= constants.TNS_AUTH_MODE_CHANGE_PASSWORD;
}
if (!this.token) {
this.authMode |= constants.TNS_AUTH_MODE_WITH_PASSWORD;
}
}
getAlterTimezoneStatement() {
let tzHour, tzMinutes, timezoneMinutes, sign, tzRepr;
let date = new Date();
timezoneMinutes = date.getTimezoneOffset();
tzHour = Math.trunc(timezoneMinutes / 60);
tzMinutes = Math.abs((timezoneMinutes - tzHour * 60) % 60);
this.conn.tzOffset = -tzHour * 60 + tzMinutes;
if (tzHour < 0) {
sign = '+'; // getTimezoneOffset() = localtime - timeUTC
tzHour = -tzHour;
} else {
sign = '-';
}
tzHour = tzHour.toLocaleString('en-US', {minimumIntegerDigits: 2});
tzRepr = `${sign}${tzHour}:${tzMinutes}`;
return `ALTER SESSION SET TIME_ZONE ='${tzRepr}'\x00`;
}
encode(buf) {
let verifier11G = false;
this.writeFunctionHeader(buf);
if (this.userByteLen > 0) {
buf.writeUInt8(1);
} else {
buf.writeUInt8(0);
}
buf.writeUB4(this.userByteLen);
buf.writeUB4(this.authMode);
if (this.functionCode === constants.TNS_FUNC_AUTH_PHASE_ONE) {
buf.writeUInt8(1);
buf.writeUB4(5);
buf.writeUInt8(0);
buf.writeUInt8(1);
if (this.userByteLen > 0) {
buf.writeBytesWithLength(Buffer.from(this.username));
}
buf.writeKeyValue("AUTH_TERMINAL", "unknown");
buf.writeKeyValue("AUTH_PROGRAM_NM", process.argv0);
buf.writeKeyValue("AUTH_MACHINE", os.hostname());
buf.writeKeyValue("AUTH_PID", process.pid.toString());
buf.writeKeyValue("AUTH_SID", os.userInfo().username);
} else {
let numPairs = 0;
if (this.changePassword) {
ED.updatePasswordsWithComboKey(this.password, this.newPassword, this.conn.comboKey, this);
numPairs = 2;
} else {
numPairs = 4;
if (this.token) {
numPairs += 1;
} else {
numPairs += 2;
if (this.verifierType === constants.TNS_VERIFIER_TYPE_11G_1 ||
this.verifierType === constants.TNS_VERIFIER_TYPE_11G_2) {
verifier11G = true;
} else if (this.verifierType !== constants.TNS_VERIFIER_TYPE_12C) {
errors.throwErr(errors.ERR_UNSUPPORTED_VERIFIER_TYPE,
this.verifierType.toString(16));
} else {
numPairs += 1;
}
ED.updateVerifierData(this.sessionData, this.password, this.newPassword, verifier11G, this);
// The comboKey is cached inside the conn which is used
// for changePassword issued on the connection
this.conn.comboKey = this.comboKey;
if (this.newPassword) {
numPairs += 1;
}
}
if (this.privateKey) {
numPairs += 2;
}
if (this.conn.connClass) {
numPairs += 1;
}
if (this.conn.purity) {
numPairs += 1;
}
if (this.conn.jdwpData) {
this.encryptedJDWPData = ED.getEncryptedJSWPData(this.sessionKey, this.conn.jdwpData);
numPairs += 1;
}
if (this.schemaUser.length !== 0) {
numPairs += 1;
}
}
buf.writeUInt8(1);
buf.writeUB4(numPairs);
buf.writeUInt8(1);
buf.writeUInt8(1);
if (this.userByteLen > 0)
buf.writeBytesWithLength(Buffer.from(this.username));
if (this.token) {
buf.writeKeyValue("AUTH_TOKEN", this.token);
} else {
if (!this.changePassword) {
buf.writeKeyValue("AUTH_SESSKEY", this.sessionKey, 1);
if (!verifier11G) {
buf.writeKeyValue("AUTH_PBKDF2_SPEEDY_KEY", this.speedyKey);
}
buf.writeKeyValue("SESSION_CLIENT_CHARSET", "873");
buf.writeKeyValue("SESSION_CLIENT_DRIVER_NAME", constants.DRIVER_NAME);
buf.writeKeyValue("SESSION_CLIENT_VERSION",
constants.CLIENT_VERSION.toString());
buf.writeKeyValue("AUTH_ALTER_SESSION", this.getAlterTimezoneStatement(), 1);
}
buf.writeKeyValue("AUTH_PASSWORD", this.encodedPassword);
if (this.proxyStatus === 0) {
buf.writeKeyValue("PROXY_CLIENT_NAME", this.schemaUser);
}
if (this.encodedNewPassword) {
buf.writeKeyValue("AUTH_NEWPASSWORD", this.encodedNewPassword);
}
}
if (this.conn.connClass) {
buf.writeKeyValue("AUTH_KPPL_CONN_CLASS", this.conn.connClass);
}
if (this.conn.purity) {
buf.writeKeyValue("AUTH_KPPL_PURITY", '' + this.conn.purity);
}
if (this.privateKey) {
const currentDate = new Date();
const currentDateFormatted = currentDate.toGMTString();
let header = "date: " + currentDateFormatted + "\n" +
"(request-target): " + this.serviceName + "\n" +
"host: " + this.remoteAddress;
let signature = crypto.createSign('RSA-SHA256')
.update(header)
.sign(this.privateKey, 'base64');
buf.writeKeyValue("AUTH_HEADER", header);
buf.writeKeyValue("AUTH_SIGNATURE", signature);
}
if (this.conn.jdwpData) {
buf.writeKeyValue("AUTH_ORA_DEBUG_JDWP", this.encryptedJDWPData);
}
}
}
processReturnParameter(buf) {
let numParams = buf.readUB2();
for (let i = 0; i < numParams;i++) {
buf.skipUB4();
let key = buf.readStr(constants.TNS_CS_IMPLICIT);
let value = "";
let numBytes = buf.readUB4();
if (numBytes > 0) {
value = buf.readStr(constants.TNS_CS_IMPLICIT);
}
let flag = buf.readUB4();
if (key === "AUTH_VFR_DATA") {
this.verifierType = flag;
}
this.sessionData[key] = value;
}
if (this.functionCode === constants.TNS_FUNC_AUTH_PHASE_ONE) {
this.functionCode = constants.TNS_FUNC_AUTH_PHASE_TWO;
} else {
let versionNum;
let releaseNum;
let updateNum;
let portReleaseNum;
let portUpdateNum;
this.conn.sessionID = this.sessionData['AUTH_SESSION_ID'];
this.conn.serialNum = this.sessionData['AUTH_SERIAL_NUM'];
let fullVersionNum = Number(this.sessionData['AUTH_VERSION_NO']);
versionNum = (fullVersionNum >> 24) & 0xFF;
if (buf.caps.ttcFieldVersion >= constants.TNS_CCAP_FIELD_VERSION_18_1_EXT_1) {
releaseNum = (fullVersionNum >> 16) & 0xFF;
updateNum = (fullVersionNum >> 12) & 0x0F;
portReleaseNum = (fullVersionNum >> 4) & 0xFF;
portUpdateNum = fullVersionNum & 0x0F;
} else {
releaseNum = (fullVersionNum >> 20) & 0x0F;
updateNum = (fullVersionNum >> 12) & 0xFF;
portReleaseNum = (fullVersionNum >> 8) & 0x0F;
portUpdateNum = fullVersionNum & 0xFF;
}
this.conn.serverVersionString = versionNum + '.' + releaseNum + '.' + updateNum + '.' + portReleaseNum + '.' + portUpdateNum;
this.conn.serverVersion = versionNum * 100000000 + releaseNum * 1000000 + updateNum * 10000 + portReleaseNum * 100 + portUpdateNum * 1;
}
}
}
module.exports = AuthMessage;

View File

@ -0,0 +1,475 @@
// Copyright (c) 2022, 2023, Oracle and/or its affiliates.
//-----------------------------------------------------------------------------
//
// This software is dual-licensed to you under the Universal Permissive License
// (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
// 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
// either license.
//
// If you elect to accept the software under the Apache License, Version 2.0,
// the following applies:
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://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 constants = require("../constants.js");
const errors = require("../../../errors.js");
class OracleErrorInfo {
constructor() {
this.num = 0;
this.cursorId = 0;
this.pos = 0;
this.rowCount = 0;
this.message = "";
this.rowID = null;
this.batchErrors;
}
}
class Error {
constructor(num, message = "", context = "", isRecoverable = false, isWarning = false, code = 0, offset = 0) {
this.num = num;
this.message = message;
this.context = context;
this.isRecoverable = isRecoverable;
this.isWarning = isWarning;
this.code = code;
this.offset = offset;
}
}
/**
*
* Base class for all the RPC messages to support encode/decode functions
*/
class Message {
constructor(connection) {
this.errorInfo = new OracleErrorInfo();
this.connection = connection;
this.messageType = constants.TNS_MSG_TYPE_FUNCTION;
this.functionCode = 0;
this.callStatus = 0;
this.flushOutBinds = false;
this.endToEndSeqNum = 0;
this.errorOccurred = false;
this.isWarning = false;
this.flushOutBinds = false;
this.processedError = false;
}
preProcess() { }
async postProcess() { }
writeFunctionHeader(buf) {
buf.writeUInt8(this.messageType);
buf.writeUInt8(this.functionCode);
buf.writeSeqNum();
if (buf.caps.ttcFieldVersion >= constants.TNS_CCAP_FIELD_VERSION_23_1_EXT_1) {
buf.writeUB8(0); // token number
}
}
processErrorInfo(buf) {
this.callStatus = buf.readUB4(); // end of call status
buf.skipUB2(); // end to end seq number
buf.skipUB4(); // current row number
buf.skipUB2(); // error number
buf.skipUB2(); // array elem error
buf.skipUB2(); // array elem error
this.errorInfo.cursorId = buf.readUB2(); // cursor id
this.errorInfo.pos = buf.readUB2(); // error position
buf.skipUB1(); // sql type
buf.skipUB1(); // fatal ?
buf.skipUB2(); // flags
buf.skipUB2(); // user cursor options
buf.skipUB1(); // UPI parameter
buf.skipUB1(); // warning flag
this.errorInfo.rowID = buf.readRowID(); // rowid
buf.skipUB4(); // OS error
buf.skipUB1(); // statement error
buf.skipUB1(); // call number
buf.skipUB2(); // padding
buf.skipUB4(); // success iters
let numBytes = buf.readUB4(); // oerrdd (logical rowid)
if (numBytes > 0) {
buf.skipBytesChunked();
}
// batch error codes
let numEntries = buf.readUB2(); // batch error codes array
if (numEntries > 0) {
this.errorInfo.batchErrors = [];
let firstByte = buf.readUInt8();
for (let i = 0; i < numEntries; i++) {
if (firstByte === constants.TNS_LONG_LENGTH_INDICATOR) {
buf.skipUB4(); // chunk length ignored
}
let errorCode = buf.readUB2();
this.errorInfo.batchErrors.push(new Error(errorCode));
}
if (firstByte === constants.TNS_LONG_LENGTH_INDICATOR) {
buf.skipBytes(1); // ignore end marker
}
}
// batch error offset
numEntries = buf.readUB2(); // batch error row offset array
if (numEntries > 0) {
let firstByte = buf.readUInt8();
for (let i = 0; i < numEntries; i++) {
if (firstByte === constants.TNS_LONG_LENGTH_INDICATOR) {
buf.skipUB4(); // chunk length ignored
}
this.errorInfo.batchErrors[i].offset = buf.readUB4();
}
if (firstByte === constants.TNS_LONG_LENGTH_INDICATOR) {
buf.skipBytes(1); // ignore end marker
}
}
// batch error messages
numEntries = buf.readUB2(); // batch error messages array
if (numEntries > 0) {
buf.skipBytes(1); // ignore packed size
for (let i = 0; i < numEntries; i++) {
buf.skipUB2(); // skip chunk length
this.errorInfo.batchErrors[i].message = buf.readStr(constants.TNS_CS_IMPLICIT);
buf.skipBytes(2); // ignore end marker
}
}
this.errorInfo.num = buf.readUB4(); // error number (extended)
this.errorInfo.rowCount = buf.readUB8(); // row number (extended)
if (this.errorInfo.num !== 0) {
this.errorOccurred = true;
this.errorInfo.message = buf.readStr(constants.TNS_CS_IMPLICIT);
/*
* Remove ending newline from ORA error message
*/
this.errorInfo.message = this.errorInfo.message.replace(/\n+$/, "");
}
this.errorInfo.isWarning = false;
this.processedError = true;
}
processReturnParameter() { }
processWarningInfo(buf) {
this.errorInfo.num = buf.readUB2(); // error number
let numBytes = buf.readUB2(); // length of error message
buf.skipUB2(); // flags
if (this.errorInfo.num != 0 && numBytes > 0) {
this.errorInfo.message = buf.readStr(constants.TNS_CS_IMPLICIT);
}
this.errorInfo.isWarning = true;
}
hasMoreData(buf) {
return buf.numBytesLeft() > 0 && !this.flushOutBinds;
}
decode(buf) {
this.process(buf);
}
process(buf) {
this.flushOutBinds = false;
this.processedError = false;
do {
this.savePoint(buf);
const messageType = buf.readUInt8();
this.processMessage(buf, messageType);
} while (this.hasMoreData(buf));
}
savePoint(buf) {
buf.savePoint();
}
processMessage(buf, messageType) {
if (messageType === constants.TNS_MSG_TYPE_ERROR) {
this.processErrorInfo(buf);
} else if (messageType === constants.TNS_MSG_TYPE_WARNING) {
this.processWarningInfo(buf);
} else if (messageType === constants.TNS_MSG_TYPE_STATUS) {
this.callStatus = buf.readUB4();
this.endToEndSeqNum = buf.readUB2();
} else if (messageType === constants.TNS_MSG_TYPE_PARAMETER) {
this.processReturnParameter(buf);
} else if (messageType === constants.TNS_MSG_TYPE_SERVER_SIDE_PIGGYBACK) {
this.processServerSidePiggyBack(buf);
} else {
errors.throwErr(errors.ERR_UNEXPECTED_MESSAGE_TYPE, messageType);
}
}
processServerSidePiggyBack(buf) {
const opcode = buf.readUInt8();
if (opcode === constants.TNS_SERVER_PIGGYBACK_LTXID) {
const num_bytes = buf.readUB4();
if (num_bytes > 0) {
buf.skipBytes(num_bytes);
}
} else if ((opcode === constants.TNS_SERVER_PIGGYBACK_QUERY_CACHE_INVALIDATION)
|| (opcode === constants.TNS_SERVER_PIGGYBACK_TRACE_EVENT)) {
// pass
} else if (opcode === constants.TNS_SERVER_PIGGYBACK_OS_PID_MTS) {
const nb = buf.readUB2();
buf.skipBytes(nb + 1);
} else if (opcode === constants.TNS_SERVER_PIGGYBACK_SYNC) {
buf.skipUB2(); // skip number of DTYs
buf.skipUB1(); // skip length of DTYs
const num_elements = buf.readUB2();
buf.skipBytes(1); // skip length
for (let i = 0; i < num_elements; i++) {
let temp16 = buf.readUB2();
if (temp16 > 0) { // skip key
buf.skipBytes(temp16 + 1);
}
temp16 = buf.readUB2();
if (temp16 > 0) { // skip value
buf.skipBytes(temp16 + 1);
}
buf.skipUB2(); // skip flags
buf.skipUB4(); // skip overall flags
}
} else if (opcode === constants.TNS_SERVER_PIGGYBACK_EXT_SYNC) {
buf.skipUB2();
buf.skipUB1();
} else if (opcode === constants.TNS_SERVER_PIGGYBACK_AC_REPLAY_CONTEXT) {
buf.skipUB2(); // skip number of DTYs
buf.skipUB1(1); // skip length of DTYs
buf.skipUB4(); // skip flags
buf.skipUB4(); // skip error code
buf.skipUB1(); // skip queue
const num_bytes = buf.readUB4(); // skip replay context
if (num_bytes > 0) {
buf.skipBytes(num_bytes);
}
} else if (opcode === constants.TNS_SERVER_PIGGYBACK_SESS_RET) {
buf.skipUB2();
buf.skipUB1();
const num_elements = buf.readUB2();
if (num_elements > 0) {
buf.skipUB1();
for (let i = 0; i < num_elements; ++i) {
let temp16 = buf.readUB2();
if (temp16 > 0) { // skip key
buf.skipBytes(temp16 + 1);
}
temp16 = buf.readUB2();
if (temp16 > 0) { // skip value
buf.skipBytes(temp16 + 1);
}
buf.skipUB2(); // skip flags
}
}
const flags = buf.readUB4(); // session flags
if (flags & constants.TNS_SESSGET_SESSION_CHANGED) {
if (this.connection._drcpEstablishSession) {
this.connection.resetStatmentCache();
}
}
this.connection._drcpEstablishSession = false;
buf.skipUB4(); // session id
buf.skipUB2(); // serial number
} else {
errors.throwErr(errors.ERR_UNKOWN_SERVER_SIDE_PIGGYBACK, opcode);
}
}
writePiggybacks(buf) {
if (this.connection._currentSchemaModified) {
this._writeCurrentSchemaPiggyback(buf);
}
if (this.connection._cursorsToClose.size > 0 && !this.connection._drcpEstablishSession) {
this.writeCloseCursorsPiggyBack(buf);
}
if (
this.connection._actionModified ||
this.connection._clientIdentifierModified ||
this.connection._dbopModified ||
this.connection._clientInfoModified ||
this.connection._moduleModified
) {
this._writeEndToEndPiggybacks(buf);
}
if (this.connection._tempLobsTotalSize > 0) {
this.writeCloseTempLobsPiggyback(buf);
}
}
writePiggybackHeader(buf, functionCode) {
buf.writeUInt8(constants.TNS_MSG_TYPE_PIGGYBACK);
buf.writeUInt8(functionCode);
buf.writeSeqNum();
if (buf.caps.ttcFieldVersion >= constants.TNS_CCAP_FIELD_VERSION_23_1_EXT_1) {
buf.writeUB8(0); // token number
}
}
writeCloseCursorsPiggyBack(buf) {
this.writePiggybackHeader(buf, constants.TNS_FUNC_CLOSE_CURSORS);
buf.writeUInt8(1);
buf.writeUB4(this.connection._cursorsToClose.size);
for (const cursorNum of this.connection._cursorsToClose.keys()) {
buf.writeUB4(cursorNum);
}
this.connection._cursorsToClose.clear();
}
writeCloseTempLobsPiggyback(buf) {
let lobsToClose = this.connection._tempLobsToClose;
let opCode = constants.TNS_LOB_OP_FREE_TEMP | constants.TNS_LOB_OP_ARRAY;
this.writePiggybackHeader(buf, constants.TNS_FUNC_LOB_OP);
buf.writeUInt8(1); // pointer
buf.writeUB4(this.connection._tempLobsTotalSize);
buf.writeUInt8(0); // dest LOB locator
buf.writeUB4(0);
buf.writeUB4(0); // source LOB locator
buf.writeUB4(0);
buf.writeUInt8(0); // source LOB offset
buf.writeUInt8(0); // dest LOB offset
buf.writeUInt8(0); // charset
buf.writeUB4(opCode);
buf.writeUInt8(0); // scn
buf.writeUB4(0); // LOB scn
buf.writeUB8(0); // LOB scnl
buf.writeUB8(0);
buf.writeUInt8(0);
// array LOB fields
buf.writeUInt8(0);
buf.writeUB4(0);
buf.writeUInt8(0);
buf.writeUB4(0);
buf.writeUInt8(0);
buf.writeUB4(0);
for (const val of lobsToClose) {
buf.writeBytes(val);
}
// Reset Values
this.connection._tempLobsToClose = [];
this.connection._tempLobsTotalSize = 0;
}
_writeCurrentSchemaPiggyback(buf) {
this.writePiggybackHeader(buf, constants.TNS_FUNC_SET_SCHEMA);
buf.writeUInt8(1);
const bytes = Buffer.byteLength(this.connection.currentSchema);
buf.writeUB4(bytes);
buf.writeBytesWithLength(Buffer.from(this.connection.currentSchema));
}
_writeEndToEndPiggybacks(buf) {
let flags = 0;
// determine which flags to send
if (this.connection._actionModified) {
flags |= constants.TNS_END_TO_END_ACTION;
}
if (this.connection._clientIdentifierModified) {
flags |= constants.TNS_END_TO_END_CLIENT_IDENTIFIER;
}
if (this.connection._clientInfoModified) {
flags |= constants.TNS_END_TO_END_CLIENT_INFO;
}
if (this.connection._moduleModified) {
flags |= constants.TNS_END_TO_END_MODULE;
}
if (this.connection._dbOpModified) {
flags |= constants.TNS_END_TO_END_DBOP;
}
// write initial packet data
this.writePiggybackHeader(buf, constants.TNS_FUNC_SET_END_TO_END_ATTR);
buf.writeUInt8(0); // pointer (cidnam)
buf.writeUInt8(0); // pointer (cidser)
buf.writeUB4(flags);
let clientIdentifierBytes = this.writeEndEndTraceValue(buf, this.connection._clientIdentifier, this.connection._clientIdentifierModified);
let moduleBytes = this.writeEndEndTraceValue(buf, this.connection._module, this.connection._moduleModified);
let actionBytes = this.writeEndEndTraceValue(buf, this.connection._action, this.connection._actionModified);
// write unsupported bits
buf.writeUInt8(0); // pointer (cideci)
buf.writeUB4(0); // length (cideci)
buf.writeUInt8(0); // cidcct
buf.writeUB4(0); // cidecs
let clientInfoBytes = this.writeEndEndTraceValue(buf, this.connection._clientInfo, this.connection._clientInfoModified);
// write unsupported bits
buf.writeUInt8(0); // pointer (cideci)
buf.writeUB4(0); // length (cideci)
buf.writeUInt8(0); // cidcct
buf.writeUB4(0); // cidecs
let dbOpBytes = this.writeEndEndTraceValue(buf, this.connection._dbOp, this.connection._dbOpModified);
// write strings
if (this.connection._clientIdentifierModified && this.connection._clientIdentifier) {
buf.writeBytesWithLength(clientIdentifierBytes);
}
if (this.connection._moduleModified && this.connection._module) {
buf.writeBytesWithLength(moduleBytes);
}
if (this.connection._actionModified && this.connection._action) {
buf.writeBytesWithLength(actionBytes);
}
if (this.connection._clientInfoModified && this.connection._clientInfo) {
buf.writeBytesWithLength(clientInfoBytes);
}
if (this.connection._dbOpModified && this.connection._dbOp) {
buf.writeBytesWithLength(dbOpBytes);
}
// reset flags and values
this.connection._actionModified = false;
this.connection._action = "";
this.connection._clientIdentifierModified = false;
this.connection._clientIdentifier = "";
this.connection._clientInfoModified = false;
this.connection._clientInfo = "";
this.connection._dbOpModified = false;
this.connection._dbOp = "";
this.connection._moduleModified = false;
this.connection._module = "";
}
writeEndEndTraceValue(buf, value, modified) {
// write client identifier header info
let writtenBytes;
if (modified) {
buf.writeUInt8(1); // pointer (client identifier)
if (value) {
writtenBytes = Buffer.from(value);
buf.writeUB4(writtenBytes.length);
} else {
buf.writeUB4(0);
}
} else {
buf.writeUInt8(0); // pointer (client identifier)
buf.writeUB4(0); // length of client identifier
}
return writtenBytes;
}
}
module.exports = Message;

View File

@ -0,0 +1,56 @@
// Copyright (c) 2022, 2023, Oracle and/or its affiliates.
//-----------------------------------------------------------------------------
//
// This software is dual-licensed to you under the Universal Permissive License
// (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
// 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
// either license.
//
// If you elect to accept the software under the Apache License, Version 2.0,
// the following applies:
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://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 Message = require("./base.js");
const constants = require("../constants.js");
/**
* Executes Commit RPC
*
* @class CommitMessage
* @extends {Message}
*/
class CommitMessage extends Message {
constructor(connImpl) {
super(connImpl);
this.functionCode = constants.TNS_FUNC_COMMIT;
}
//-------------------------------------------------------------------------
// encode()
//
// Write the RPC to perform commit operation in the database
//-------------------------------------------------------------------------
encode(pkt) {
this.writeFunctionHeader(pkt);
}
}
module.exports = CommitMessage;

View File

@ -0,0 +1,382 @@
// Copyright (c) 2022, 2023, Oracle and/or its affiliates.
//-----------------------------------------------------------------------------
//
// This software is dual-licensed to you under the Universal Permissive License
// (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
// 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
// either license.
//
// If you elect to accept the software under the Apache License, Version 2.0,
// the following applies:
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://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 constants = require("../constants.js");
const Message = require("./base.js");
/**
* Does Datatype Negotiation
*
* @class DataTypeMessage
* @extends {Message}
*
*/
class DataTypeMessage extends Message {
decode() { }
encode(buf) {
buf.writeUInt8(constants.TNS_MSG_TYPE_DATA_TYPES);
buf.writeUInt16LE(constants.TNS_CHARSET_UTF8);
buf.writeUInt16LE(constants.TNS_CHARSET_UTF8);
buf.writeUInt8(constants.TNS_ENCODING_MULTI_BYTE |
constants.TNS_ENCODING_CONV_LENGTH);
buf.writeBytesWithLength(buf.caps.compileCaps);
buf.writeBytesWithLength(buf.caps.runtimeCaps);
for (let val of dataTypes) {
buf.writeUInt16BE(val[0]);
buf.writeUInt16BE(val[1]);
buf.writeUInt16BE(val[2]);
buf.writeUInt16BE(0);
}
buf.writeUInt16BE(0);
}
}
const dataTypes = [
[constants.TNS_DATA_TYPE_VARCHAR, constants.TNS_DATA_TYPE_VARCHAR, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_NUMBER, constants.TNS_DATA_TYPE_NUMBER, constants.TNS_TYPE_REP_ORACLE],
[constants.TNS_DATA_TYPE_LONG, constants.TNS_DATA_TYPE_LONG, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DATE, constants.TNS_DATA_TYPE_DATE, constants.TNS_TYPE_REP_ORACLE],
[constants.TNS_DATA_TYPE_RAW, constants.TNS_DATA_TYPE_RAW, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_LONG_RAW, constants.TNS_DATA_TYPE_LONG_RAW, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_UB2, constants.TNS_DATA_TYPE_UB2, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_UB4, constants.TNS_DATA_TYPE_UB4, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_SB1, constants.TNS_DATA_TYPE_SB1, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_SB2, constants.TNS_DATA_TYPE_SB2, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_SB4, constants.TNS_DATA_TYPE_SB4, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_SWORD, constants.TNS_DATA_TYPE_SWORD, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_UWORD, constants.TNS_DATA_TYPE_UWORD, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_PTRB, constants.TNS_DATA_TYPE_PTRB, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_PTRW, constants.TNS_DATA_TYPE_PTRW, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_TIDDEF, constants.TNS_DATA_TYPE_TIDDEF, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_ROWID, constants.TNS_DATA_TYPE_ROWID, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_AMS, constants.TNS_DATA_TYPE_AMS, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_BRN, constants.TNS_DATA_TYPE_BRN, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_CWD, constants.TNS_DATA_TYPE_CWD, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_NEW_OAC, constants.TNS_DATA_TYPE_NEW_OAC, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_OER8, constants.TNS_DATA_TYPE_OER8, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_FUN, constants.TNS_DATA_TYPE_FUN, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_AUA, constants.TNS_DATA_TYPE_AUA, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_RXH7, constants.TNS_DATA_TYPE_RXH7, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_NA6, constants.TNS_DATA_TYPE_NA6, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_BRP, constants.TNS_DATA_TYPE_BRP, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_BRV, constants.TNS_DATA_TYPE_BRV, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KVA, constants.TNS_DATA_TYPE_KVA, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_CLS, constants.TNS_DATA_TYPE_CLS, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_CUI, constants.TNS_DATA_TYPE_CUI, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DFN, constants.TNS_DATA_TYPE_DFN, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DQR, constants.TNS_DATA_TYPE_DQR, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DSC, constants.TNS_DATA_TYPE_DSC, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_EXE, constants.TNS_DATA_TYPE_EXE, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_FCH, constants.TNS_DATA_TYPE_FCH, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_GBV, constants.TNS_DATA_TYPE_GBV, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_GEM, constants.TNS_DATA_TYPE_GEM, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_GIV, constants.TNS_DATA_TYPE_GIV, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_OKG, constants.TNS_DATA_TYPE_OKG, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_HMI, constants.TNS_DATA_TYPE_HMI, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_INO, constants.TNS_DATA_TYPE_INO, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_LNF, constants.TNS_DATA_TYPE_LNF, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_ONT, constants.TNS_DATA_TYPE_ONT, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_OPE, constants.TNS_DATA_TYPE_OPE, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_OSQ, constants.TNS_DATA_TYPE_OSQ, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_SFE, constants.TNS_DATA_TYPE_SFE, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_SPF, constants.TNS_DATA_TYPE_SPF, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_VSN, constants.TNS_DATA_TYPE_VSN, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_UD7, constants.TNS_DATA_TYPE_UD7, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DSA, constants.TNS_DATA_TYPE_DSA, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_PIN, constants.TNS_DATA_TYPE_PIN, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_PFN, constants.TNS_DATA_TYPE_PFN, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_PPT, constants.TNS_DATA_TYPE_PPT, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_STO, constants.TNS_DATA_TYPE_STO, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_ARC, constants.TNS_DATA_TYPE_ARC, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_MRS, constants.TNS_DATA_TYPE_MRS, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_MRT, constants.TNS_DATA_TYPE_MRT, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_MRG, constants.TNS_DATA_TYPE_MRG, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_MRR, constants.TNS_DATA_TYPE_MRR, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_MRC, constants.TNS_DATA_TYPE_MRC, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_VER, constants.TNS_DATA_TYPE_VER, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_LON2, constants.TNS_DATA_TYPE_LON2, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_INO2, constants.TNS_DATA_TYPE_INO2, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_ALL, constants.TNS_DATA_TYPE_ALL, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_UDB, constants.TNS_DATA_TYPE_UDB, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_AQI, constants.TNS_DATA_TYPE_AQI, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_ULB, constants.TNS_DATA_TYPE_ULB, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_ULD, constants.TNS_DATA_TYPE_ULD, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_SID, constants.TNS_DATA_TYPE_SID, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_NA7, constants.TNS_DATA_TYPE_NA7, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_AL7, constants.TNS_DATA_TYPE_AL7, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_K2RPC, constants.TNS_DATA_TYPE_K2RPC, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_XDP, constants.TNS_DATA_TYPE_XDP, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_OKO8, constants.TNS_DATA_TYPE_OKO8, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_UD12, constants.TNS_DATA_TYPE_UD12, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_AL8, constants.TNS_DATA_TYPE_AL8, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_LFOP, constants.TNS_DATA_TYPE_LFOP, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_FCRT, constants.TNS_DATA_TYPE_FCRT, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DNY, constants.TNS_DATA_TYPE_DNY, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_OPR, constants.TNS_DATA_TYPE_OPR, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_PLS, constants.TNS_DATA_TYPE_PLS, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_XID, constants.TNS_DATA_TYPE_XID, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_TXN, constants.TNS_DATA_TYPE_TXN, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DCB, constants.TNS_DATA_TYPE_DCB, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_CCA, constants.TNS_DATA_TYPE_CCA, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_WRN, constants.TNS_DATA_TYPE_WRN, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_TLH, constants.TNS_DATA_TYPE_TLH, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_TOH, constants.TNS_DATA_TYPE_TOH, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_FOI, constants.TNS_DATA_TYPE_FOI, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_SID2, constants.TNS_DATA_TYPE_SID2, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_TCH, constants.TNS_DATA_TYPE_TCH, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_PII, constants.TNS_DATA_TYPE_PII, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_PFI, constants.TNS_DATA_TYPE_PFI, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_PPU, constants.TNS_DATA_TYPE_PPU, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_PTE, constants.TNS_DATA_TYPE_PTE, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_RXH8, constants.TNS_DATA_TYPE_RXH8, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_N12, constants.TNS_DATA_TYPE_N12, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_AUTH, constants.TNS_DATA_TYPE_AUTH, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KVAL, constants.TNS_DATA_TYPE_KVAL, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_FGI, constants.TNS_DATA_TYPE_FGI, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DSY, constants.TNS_DATA_TYPE_DSY, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DSYR8, constants.TNS_DATA_TYPE_DSYR8, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DSYH8, constants.TNS_DATA_TYPE_DSYH8, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DSYL, constants.TNS_DATA_TYPE_DSYL, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DSYT8, constants.TNS_DATA_TYPE_DSYT8, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DSYV8, constants.TNS_DATA_TYPE_DSYV8, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DSYP, constants.TNS_DATA_TYPE_DSYP, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DSYF, constants.TNS_DATA_TYPE_DSYF, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DSYK, constants.TNS_DATA_TYPE_DSYK, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DSYY, constants.TNS_DATA_TYPE_DSYY, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DSYQ, constants.TNS_DATA_TYPE_DSYQ, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DSYC, constants.TNS_DATA_TYPE_DSYC, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DSYA, constants.TNS_DATA_TYPE_DSYA, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_OT8, constants.TNS_DATA_TYPE_OT8, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DSYTY, constants.TNS_DATA_TYPE_DSYTY, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_AQE, constants.TNS_DATA_TYPE_AQE, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KV, constants.TNS_DATA_TYPE_KV, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_AQD, constants.TNS_DATA_TYPE_AQD, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_AQ8, constants.TNS_DATA_TYPE_AQ8, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_RFS, constants.TNS_DATA_TYPE_RFS, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_RXH10, constants.TNS_DATA_TYPE_RXH10, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KPN, constants.TNS_DATA_TYPE_KPN, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KPDNR, constants.TNS_DATA_TYPE_KPDNR, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DSYD, constants.TNS_DATA_TYPE_DSYD, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DSYS, constants.TNS_DATA_TYPE_DSYS, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DSYR, constants.TNS_DATA_TYPE_DSYR, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DSYH, constants.TNS_DATA_TYPE_DSYH, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DSYT, constants.TNS_DATA_TYPE_DSYT, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DSYV, constants.TNS_DATA_TYPE_DSYV, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_AQM, constants.TNS_DATA_TYPE_AQM, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_OER11, constants.TNS_DATA_TYPE_OER11, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_AQL, constants.TNS_DATA_TYPE_AQL, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_OTC, constants.TNS_DATA_TYPE_OTC, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KFNO, constants.TNS_DATA_TYPE_KFNO, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KFNP, constants.TNS_DATA_TYPE_KFNP, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KGT8, constants.TNS_DATA_TYPE_KGT8, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_RASB4, constants.TNS_DATA_TYPE_RASB4, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_RAUB2, constants.TNS_DATA_TYPE_RAUB2, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_RAUB1, constants.TNS_DATA_TYPE_RAUB1, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_RATXT, constants.TNS_DATA_TYPE_RATXT, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_RSSB4, constants.TNS_DATA_TYPE_RSSB4, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_RSUB2, constants.TNS_DATA_TYPE_RSUB2, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_RSUB1, constants.TNS_DATA_TYPE_RSUB1, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_RSTXT, constants.TNS_DATA_TYPE_RSTXT, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_RIDL, constants.TNS_DATA_TYPE_RIDL, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_GLRDD, constants.TNS_DATA_TYPE_GLRDD, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_GLRDG, constants.TNS_DATA_TYPE_GLRDG, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_GLRDC, constants.TNS_DATA_TYPE_GLRDC, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_OKO, constants.TNS_DATA_TYPE_OKO, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DPP, constants.TNS_DATA_TYPE_DPP, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DPLS, constants.TNS_DATA_TYPE_DPLS, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DPMOP, constants.TNS_DATA_TYPE_DPMOP, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_STAT, constants.TNS_DATA_TYPE_STAT, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_RFX, constants.TNS_DATA_TYPE_RFX, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_FAL, constants.TNS_DATA_TYPE_FAL, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_CKV, constants.TNS_DATA_TYPE_CKV, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DRCX, constants.TNS_DATA_TYPE_DRCX, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KGH, constants.TNS_DATA_TYPE_KGH, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_AQO, constants.TNS_DATA_TYPE_AQO, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_OKGT, constants.TNS_DATA_TYPE_OKGT, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KPFC, constants.TNS_DATA_TYPE_KPFC, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_FE2, constants.TNS_DATA_TYPE_FE2, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_SPFP, constants.TNS_DATA_TYPE_SPFP, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DPULS, constants.TNS_DATA_TYPE_DPULS, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_AQA, constants.TNS_DATA_TYPE_AQA, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KPBF, constants.TNS_DATA_TYPE_KPBF, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_TSM, constants.TNS_DATA_TYPE_TSM, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_MSS, constants.TNS_DATA_TYPE_MSS, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KPC, constants.TNS_DATA_TYPE_KPC, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_CRS, constants.TNS_DATA_TYPE_CRS, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KKS, constants.TNS_DATA_TYPE_KKS, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KSP, constants.TNS_DATA_TYPE_KSP, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KSPTOP, constants.TNS_DATA_TYPE_KSPTOP, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KSPVAL, constants.TNS_DATA_TYPE_KSPVAL, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_PSS, constants.TNS_DATA_TYPE_PSS, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_NLS, constants.TNS_DATA_TYPE_NLS, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_ALS, constants.TNS_DATA_TYPE_ALS, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KSDEVTVAL, constants.TNS_DATA_TYPE_KSDEVTVAL, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KSDEVTTOP, constants.TNS_DATA_TYPE_KSDEVTTOP, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KPSPP, constants.TNS_DATA_TYPE_KPSPP, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KOL, constants.TNS_DATA_TYPE_KOL, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_LST, constants.TNS_DATA_TYPE_LST, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_ACX, constants.TNS_DATA_TYPE_ACX, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_SCS, constants.TNS_DATA_TYPE_SCS, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_RXH, constants.TNS_DATA_TYPE_RXH, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KPDNS, constants.TNS_DATA_TYPE_KPDNS, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KPDCN, constants.TNS_DATA_TYPE_KPDCN, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KPNNS, constants.TNS_DATA_TYPE_KPNNS, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KPNCN, constants.TNS_DATA_TYPE_KPNCN, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KPS, constants.TNS_DATA_TYPE_KPS, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_APINF, constants.TNS_DATA_TYPE_APINF, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_TEN, constants.TNS_DATA_TYPE_TEN, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_XSSCS, constants.TNS_DATA_TYPE_XSSCS, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_XSSSO, constants.TNS_DATA_TYPE_XSSSO, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_XSSAO, constants.TNS_DATA_TYPE_XSSAO, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KSRPC, constants.TNS_DATA_TYPE_KSRPC, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KVL, constants.TNS_DATA_TYPE_KVL, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_XSSDEF, constants.TNS_DATA_TYPE_XSSDEF, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_PDQCINV, constants.TNS_DATA_TYPE_PDQCINV, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_PDQIDC, constants.TNS_DATA_TYPE_PDQIDC, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KPDQCSTA, constants.TNS_DATA_TYPE_KPDQCSTA, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KPRS, constants.TNS_DATA_TYPE_KPRS, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KPDQIDC, constants.TNS_DATA_TYPE_KPDQIDC, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_RTSTRM, constants.TNS_DATA_TYPE_RTSTRM, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_SESSGET, constants.TNS_DATA_TYPE_SESSGET, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_SESSREL, constants.TNS_DATA_TYPE_SESSREL, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_SESSRET, constants.TNS_DATA_TYPE_SESSRET, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_SCN6, constants.TNS_DATA_TYPE_SCN6, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KECPA, constants.TNS_DATA_TYPE_KECPA, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KECPP, constants.TNS_DATA_TYPE_KECPP, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_SXA, constants.TNS_DATA_TYPE_SXA, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KVARR, constants.TNS_DATA_TYPE_KVARR, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KPNGN, constants.TNS_DATA_TYPE_KPNGN, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_BINARY_INTEGER, constants.TNS_DATA_TYPE_NUMBER, constants.TNS_TYPE_REP_ORACLE],
[constants.TNS_DATA_TYPE_FLOAT, constants.TNS_DATA_TYPE_NUMBER, constants.TNS_TYPE_REP_ORACLE],
[constants.TNS_DATA_TYPE_STR, constants.TNS_DATA_TYPE_VARCHAR, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_VNU, constants.TNS_DATA_TYPE_NUMBER, constants.TNS_TYPE_REP_ORACLE],
[constants.TNS_DATA_TYPE_PDN, constants.TNS_DATA_TYPE_NUMBER, constants.TNS_TYPE_REP_ORACLE],
[constants.TNS_DATA_TYPE_VCS, constants.TNS_DATA_TYPE_VARCHAR, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_VBI, constants.TNS_DATA_TYPE_VARCHAR, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_OAC, constants.TNS_DATA_TYPE_NEW_OAC, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_UIN, constants.TNS_DATA_TYPE_NUMBER, constants.TNS_TYPE_REP_ORACLE],
[constants.TNS_DATA_TYPE_SLS, constants.TNS_DATA_TYPE_NUMBER, constants.TNS_TYPE_REP_ORACLE],
[constants.TNS_DATA_TYPE_LVC, constants.TNS_DATA_TYPE_VARCHAR, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_LVB, constants.TNS_DATA_TYPE_RAW, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_CHAR, constants.TNS_DATA_TYPE_CHAR, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_AVC, constants.TNS_DATA_TYPE_CHAR, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_BINARY_FLOAT, constants.TNS_DATA_TYPE_BINARY_FLOAT,
constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_BINARY_DOUBLE, constants.TNS_DATA_TYPE_BINARY_DOUBLE,
constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_CURSOR, constants.TNS_DATA_TYPE_CURSOR, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_RDD, constants.TNS_DATA_TYPE_ROWID, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_OSL, constants.TNS_DATA_TYPE_OSL, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_EXT_NAMED, constants.TNS_DATA_TYPE_INT_NAMED, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_INT_NAMED, constants.TNS_DATA_TYPE_INT_NAMED, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_EXT_REF, constants.TNS_DATA_TYPE_INT_REF, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_INT_REF, constants.TNS_DATA_TYPE_INT_REF, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_CLOB, constants.TNS_DATA_TYPE_CLOB, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_BLOB, constants.TNS_DATA_TYPE_BLOB, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_BFILE, constants.TNS_DATA_TYPE_BFILE, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_CFILE, constants.TNS_DATA_TYPE_CFILE, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_RSET, constants.TNS_DATA_TYPE_CURSOR, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_JSON, constants.TNS_DATA_TYPE_JSON, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DJSON, constants.TNS_DATA_TYPE_DJSON, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_CLV, constants.TNS_DATA_TYPE_CLV, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DTR, constants.TNS_DATA_TYPE_NUMBER, constants.TNS_TYPE_REP_ORACLE],
[constants.TNS_DATA_TYPE_DUN, constants.TNS_DATA_TYPE_NUMBER, constants.TNS_TYPE_REP_ORACLE],
[constants.TNS_DATA_TYPE_DOP, constants.TNS_DATA_TYPE_NUMBER, constants.TNS_TYPE_REP_ORACLE],
[constants.TNS_DATA_TYPE_VST, constants.TNS_DATA_TYPE_VARCHAR, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_ODT, constants.TNS_DATA_TYPE_DATE, constants.TNS_TYPE_REP_ORACLE],
[constants.TNS_DATA_TYPE_DOL, constants.TNS_DATA_TYPE_NUMBER, constants.TNS_TYPE_REP_ORACLE],
[constants.TNS_DATA_TYPE_TIME, constants.TNS_DATA_TYPE_TIME, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_TIME_TZ, constants.TNS_DATA_TYPE_TIME_TZ, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_TIMESTAMP, constants.TNS_DATA_TYPE_TIMESTAMP, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_TIMESTAMP_TZ, constants.TNS_DATA_TYPE_TIMESTAMP_TZ,
constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_INTERVAL_YM, constants.TNS_DATA_TYPE_INTERVAL_YM,
constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_INTERVAL_DS, constants.TNS_DATA_TYPE_INTERVAL_DS,
constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_EDATE, constants.TNS_DATA_TYPE_DATE, constants.TNS_TYPE_REP_ORACLE],
[constants.TNS_DATA_TYPE_ETIME, constants.TNS_DATA_TYPE_ETIME, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_ETTZ, constants.TNS_DATA_TYPE_ETTZ, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_ESTAMP, constants.TNS_DATA_TYPE_ESTAMP, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_ESTZ, constants.TNS_DATA_TYPE_ESTZ, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_EIYM, constants.TNS_DATA_TYPE_EIYM, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_EIDS, constants.TNS_DATA_TYPE_EIDS, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DCLOB, constants.TNS_DATA_TYPE_CLOB, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DBLOB, constants.TNS_DATA_TYPE_BLOB, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_DBFILE, constants.TNS_DATA_TYPE_BFILE, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_UROWID, constants.TNS_DATA_TYPE_UROWID, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_TIMESTAMP_LTZ, constants.TNS_DATA_TYPE_TIMESTAMP_LTZ,
constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_ESITZ, constants.TNS_DATA_TYPE_TIMESTAMP_LTZ, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_UB8, constants.TNS_DATA_TYPE_UB8, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_PNTY, constants.TNS_DATA_TYPE_INT_NAMED, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_BOOLEAN, constants.TNS_DATA_TYPE_BOOLEAN, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_XSNSOP, constants.TNS_DATA_TYPE_XSNSOP, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_XSATTR, constants.TNS_DATA_TYPE_XSATTR, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_XSNS, constants.TNS_DATA_TYPE_XSNS, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_UB1ARRAY, constants.TNS_DATA_TYPE_UB1ARRAY, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_SESSSTATE, constants.TNS_DATA_TYPE_SESSSTATE, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_AC_REPLAY, constants.TNS_DATA_TYPE_AC_REPLAY, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_AC_CONT, constants.TNS_DATA_TYPE_AC_CONT, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_IMPLRES, constants.TNS_DATA_TYPE_IMPLRES, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_OER, constants.TNS_DATA_TYPE_OER, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_TXT, constants.TNS_DATA_TYPE_TXT, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_XSSESSNS, constants.TNS_DATA_TYPE_XSSESSNS, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_XSATTOP, constants.TNS_DATA_TYPE_XSATTOP, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_XSCREOP, constants.TNS_DATA_TYPE_XSCREOP, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_XSDETOP, constants.TNS_DATA_TYPE_XSDETOP, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_XSDESOP, constants.TNS_DATA_TYPE_XSDESOP, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_XSSETSP, constants.TNS_DATA_TYPE_XSSETSP, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_XSSIDP, constants.TNS_DATA_TYPE_XSSIDP, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_XSPRIN, constants.TNS_DATA_TYPE_XSPRIN, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_XSKVL, constants.TNS_DATA_TYPE_XSKVL, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_XSSSDEF2, constants.TNS_DATA_TYPE_XSSSDEF2, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_XSNSOP2, constants.TNS_DATA_TYPE_XSNSOP2, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_XSNS2, constants.TNS_DATA_TYPE_XSNS2, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KPDNREQ, constants.TNS_DATA_TYPE_KPDNREQ, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KPDNRNF, constants.TNS_DATA_TYPE_KPDNRNF, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KPNGNC, constants.TNS_DATA_TYPE_KPNGNC, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KPNRI, constants.TNS_DATA_TYPE_KPNRI, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_AQENQ, constants.TNS_DATA_TYPE_AQENQ, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_AQDEQ, constants.TNS_DATA_TYPE_AQDEQ, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_AQJMS, constants.TNS_DATA_TYPE_AQJMS, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KPDNRPAY, constants.TNS_DATA_TYPE_KPDNRPAY, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KPDNRACK, constants.TNS_DATA_TYPE_KPDNRACK, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KPDNRMP, constants.TNS_DATA_TYPE_KPDNRMP, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_KPDNRDQ, constants.TNS_DATA_TYPE_KPDNRDQ, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_SCN, constants.TNS_DATA_TYPE_SCN, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_SCN8, constants.TNS_DATA_TYPE_SCN8, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_CHUNKINFO, constants.TNS_DATA_TYPE_CHUNKINFO, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_UDS, constants.TNS_DATA_TYPE_UDS, constants.TNS_TYPE_REP_UNIVERSAL],
[constants.TNS_DATA_TYPE_TNP, constants.TNS_DATA_TYPE_TNP, constants.TNS_TYPE_REP_UNIVERSAL]
];
module.exports = DataTypeMessage;

View File

@ -0,0 +1,314 @@
// Copyright (c) 2022, 2023, Oracle and/or its affiliates.
//-----------------------------------------------------------------------------
//
// This software is dual-licensed to you under the Universal Permissive License
// (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
// 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
// either license.
//
// If you elect to accept the software under the Apache License, Version 2.0,
// the following applies:
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://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 MessageWithData = require("./withData.js");
const constants = require("../constants.js");
const errors = require("../../../errors.js");
/**
*
* Executes OALL8 RPC function
*
* @class ExecuteMessage
* @extends {MessageWithData}
*/
class ExecuteMessage extends MessageWithData {
/**
*
* @param {object} statement
* @param {object} options
*/
constructor(connection, statement, options, resultSet) {
super(connection, statement, options);
if (!resultSet && statement.isQuery) {
resultSet = connection._createResultSet(options, statement);
}
this.resultSet = resultSet;
this.functionCode = constants.TNS_FUNC_EXECUTE;
this.bindParams = undefined;
this.currentRow = 0;
}
//-------------------------------------------------------------------------
// writeReExecuteMessage()
//
// Write the message for a full execute.
//-------------------------------------------------------------------------
writeExecuteMessage(buf) {
let options = 0x0;
let dmlOptions = 0;
let numParams = 0;
let numIters = 1;
// Configuring the options field thats send to the server
let stmt = this.statement;
let params = stmt.bindInfoList;
if (!stmt.requiresDefine && !this.parseOnly && params) {
numParams = params.length;
}
if (stmt.requiresDefine) {
options |= constants.TNS_EXEC_OPTION_DEFINE;
} else if (!this.parseOnly && stmt.sql) {
dmlOptions = constants.TNS_EXEC_OPTION_IMPLICIT_RESULTSET;
options |= constants.TNS_EXEC_OPTION_EXECUTE;
}
if (stmt.cursorId == 0 || stmt.isDdl) {
options |= constants.TNS_EXEC_OPTION_PARSE;
}
if (stmt.isQuery) {
if (this.parseOnly) {
options |= constants.TNS_EXEC_OPTION_DESCRIBE;
} else {
if (this.options.prefetchRows > 0) {
options |= constants.TNS_EXEC_OPTION_FETCH;
}
if (stmt.cursorId === 0 || stmt.requiresDefine) {
numIters = this.options.prefetchRows;
} else {
numIters = this.options.fetchArraySize;
}
}
}
if (!stmt.isPlSql && !this.parseOnly) {
options |= constants.TNS_EXEC_OPTION_NOT_PLSQL;
} else if (stmt.isPlSql && numParams > 0) {
options |= constants.TNS_EXEC_OPTION_PLSQL_BIND;
}
if (numParams > 0) {
options |= constants.TNS_EXEC_OPTION_BIND;
}
if (this.batchErrors) {
options |= constants.TNS_EXEC_OPTION_BATCH_ERRORS;
}
if (this.arrayDmlRowCounts) {
dmlOptions = constants.TNS_EXEC_OPTION_DML_ROWCOUNTS;
}
if (this.options.autoCommit) {
options |= constants.TNS_EXEC_OPTION_COMMIT;
}
this.writePiggybacks(buf);
this.writeFunctionHeader(buf);
buf.writeUB4(options); // execute options
buf.writeUB4(stmt.cursorId); // cursor id
if (stmt.cursorId === 0 || stmt.isDdl) {
buf.writeUInt8(1); // pointer (cursor id)
buf.writeUB4(stmt.sqlLength);
} else {
buf.writeUInt8(0); // pointer (cursor id)
buf.writeUB4(0);
}
buf.writeUInt8(1); // pointer (vector)
buf.writeUB4(13); // al8i4 array length
buf.writeUInt8(0); // pointer (al8o4)
buf.writeUInt8(0); // pointer (al8o4l)
buf.writeUInt8(0); // prefetc buffer size
buf.writeUB4(numIters); // prefetch num rows
buf.writeUB4(constants.TNS_MAX_LONG_LENGTH); // maximum long size
if (numParams === 0) {
buf.writeUInt8(0); // pointer (binds)
buf.writeUB4(0); // number of binds
} else {
buf.writeUInt8(1); // pointer (binds)
buf.writeUB4(numParams); // number of binds
}
buf.writeUInt8(0); // pointer (al8pp)
buf.writeUInt8(0); // pointer (al8txn)
buf.writeUInt8(0); // pointer (al8txl)
buf.writeUInt8(0); // pointer (al8kv)
buf.writeUInt8(0); // pointer (al8kvl)
if (stmt.requiresDefine) {
buf.writeUInt8(1); // pointer (al8doac)
buf.writeUB4(this.statement.queryVars.length); // number of defines
} else {
buf.writeUInt8(0);
buf.writeUB4(0);
}
buf.writeUB4(0); // registration id
buf.writeUInt8(0); // pointer (al8objlist)
buf.writeUInt8(1); // pointer (al8objlen)
buf.writeUInt8(0); // pointer (al8blv)
buf.writeUB4(0); // al8blv
buf.writeUInt8(0); // pointer (al8dnam)
buf.writeUB4(0); // al8dnaml
buf.writeUB4(0); // al8regid_msb
if (this.arrayDmlRowCounts) {
buf.writeUInt8(1); // pointer (al8pidmlrc)
buf.writeUB4(this.numExecs); // al8pidmlrcbl
buf.writeUInt8(1); // pointer (al8pidmlrcl)
} else {
buf.writeUInt8(0); // pointer (al8pidmlrc)
buf.writeUB4(0); // al8pidmlrcbl
buf.writeUInt8(0); // pointer (al8pidmlrcl)
}
if (buf.caps.ttcFieldVersion >= constants.TNS_CCAP_FIELD_VERSION_12_2) {
buf.writeUInt8(0); // pointer (al8sqlsig)
buf.writeUB4(0); // SQL signature length
buf.writeUInt8(0); // pointer (SQL ID)
buf.writeUB4(0); // allocated size of SQL ID
buf.writeUInt8(0); // pointer (length of SQL ID)
if (buf.caps.ttcFieldVersion >= constants.TNS_CCAP_FIELD_VERSION_12_2_EXT1) {
buf.writeUInt8(0); // pointer (chunk ids)
buf.writeUB4(0); // number of chunk ids
}
}
if (stmt.cursorId === 0 || stmt.isDdl) {
if (stmt.sql) {
buf.writeBytesWithLength(stmt.sqlBytes);
buf.writeUB4(1); // al8i4[0] parse
} else {
errors.throwErr(errors.ERR_INVALID_REF_CURSOR);
}
} else {
buf.writeUB4(0); // al8i4[0] parse
}
if (stmt.isQuery) {
if (stmt.cursorId === 0) {
buf.writeUB4(0); // al8i4[1] execution count
} else {
buf.writeUB4(numIters);
}
} else {
buf.writeUB4(this.numExecs); // al8i4[1] execution count
}
buf.writeUB4(0); // al8i4[2]
buf.writeUB4(0); // al8i4[3]
buf.writeUB4(0); // al8i4[4]
buf.writeUB4(0); // al8i4[5] SCN (part 1)
buf.writeUB4(0); // al8i4[6] SCN (part 2)
buf.writeUB4((stmt.isQuery) ? 1 : 0); // al8i4[7] is query
buf.writeUB4(0); // al8i4[8]
buf.writeUB4(dmlOptions); // al8i4[9] DML row counts/implicit
buf.writeUB4(0); // al8i4[10]
buf.writeUB4(0); // al8i4[11]
buf.writeUB4(0); // al8i4[12]
/*
* write column metadata and bind params
*/
if (stmt.requiresDefine) {
this.writeColumnMetadata(buf, this.statement.queryVars);
} else if (numParams > 0) {
const returningOnly = this.processBindParams(buf, params);
if (!returningOnly)
return params;
}
}
//-------------------------------------------------------------------------
// writeReExecuteMessage()
//
// Write the message header for a re-execute and return the bind parameters.
//-------------------------------------------------------------------------
writeReExecuteMessage(buf) {
let stmt = this.statement;
let params = stmt.bindInfoList;
let execFlag1 = 0, execFlag2 = 0, numIters;
if (params !== undefined) {
if (!stmt.isQuery) {
this.outVariables = [];
params.forEach(info => {
if (info.bindDir !== constants.TNS_BIND_DIR_INPUT) {
this.outVariables.push(info.bindVar);
}
});
}
let tmpparams = [];
params.forEach(info => {
if (info.bindDir !== constants.TNS_BIND_DIR_OUTPUT && !info.isReturnBind) {
tmpparams.push(info);
}
});
params = tmpparams;
}
if (this.functionCode === constants.TNS_FUNC_REEXECUTE_AND_FETCH) {
execFlag1 |= constants.TNS_EXEC_OPTION_EXECUTE;
numIters = this.options.prefetchRows;
} else {
if (this.options.autoCommit) {
execFlag2 |= constants.TNS_EXEC_OPTION_COMMIT_REEXECUTE;
}
numIters = this.numExecs;
}
this.writePiggybacks(buf);
this.writeFunctionHeader(buf);
buf.writeUB4(stmt.cursorId);
buf.writeUB4(numIters);
buf.writeUB4(execFlag1);
buf.writeUB4(execFlag2);
return params;
}
//-------------------------------------------------------------------------
// encode()
//
// Write the execute message to the buffer. Two types of execute messages
// are possible: one for a full execute and the second, simpler message,
// for when an existing cursor is being re-executed.
//-------------------------------------------------------------------------
encode(buf) {
// no rows have yet been sent so the header information needs to be sent
if (this.currentRow === 0) {
let stmt = this.statement;
if (stmt.cursorId !== 0 && !stmt.requiresFullExecute && !stmt.requiresDefine && !stmt.isDdl) {
if (stmt.isQuery && !stmt.requiresDefine && this.options.prefetchRows > 0) {
this.functionCode = constants.TNS_FUNC_REEXECUTE_AND_FETCH;
} else {
this.functionCode = constants.TNS_FUNC_REEXECUTE;
}
this.bindParams = this.writeReExecuteMessage(buf);
} else {
this.functionCode = constants.TNS_FUNC_EXECUTE;
this.bindParams = this.writeExecuteMessage(buf);
}
}
// if any bind parameters need to be sent, do that
// after each row is sent, check to see whether a pause should be performed
if (this.bindParams && this.bindParams.length > 0) {
const adapter = buf.nsi.ntAdapter;
while (this.currentRow < this.numExecs) {
buf.writeUInt8(constants.TNS_MSG_TYPE_ROW_DATA);
this.writeBindParamsRow(buf, this.bindParams, this.currentRow);
this.currentRow++;
if (this.currentRow < this.numExecs && adapter.shouldPauseWrite())
return true;
}
}
// reset state in case message is resent
this.currentRow = 0;
this.bindParams = undefined;
}
}
module.exports = ExecuteMessage;

View File

@ -0,0 +1,60 @@
// Copyright (c) 2022, 2023, Oracle and/or its affiliates.
//-----------------------------------------------------------------------------
//
// This software is dual-licensed to you under the Universal Permissive License
// (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
// 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
// either license.
//
// If you elect to accept the software under the Apache License, Version 2.0,
// the following applies:
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://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 constants = require("../constants.js");
const MessageWithData = require("./withData.js");
/**
* Executes OFETCH RPC
*
* @class FetchMessage
* @extends {MessageWithData}
*/
class FetchMessage extends MessageWithData {
constructor(connection, statement, options, resultSet) {
super(connection, statement, options);
this.resultSet = resultSet;
this.functionCode = constants.TNS_FUNC_FETCH;
}
//-------------------------------------------------------------------------
// encode()
//
// Write the cursor ID and the number of rows to be fetched in the
// Fetch Message RPC
//-------------------------------------------------------------------------
encode(buf) {
this.writeFunctionHeader(buf);
buf.writeUB4(this.statement.cursorId);
buf.writeUB4(this.options.fetchArraySize);
}
}
module.exports = FetchMessage;

View File

@ -0,0 +1,53 @@
// Copyright (c) 2023, Oracle and/or its affiliates.
//-----------------------------------------------------------------------------
//
// This software is dual-licensed to you under the Universal Permissive License
// (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
// 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
// either license.
//
// If you elect to accept the software under the Apache License, Version 2.0,
// the following applies:
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://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 AuthMessage = require('./auth.js');
const CommitMessage = require('./commit.js');
const DataTypeMessage = require('./dataType.js');
const ExecuteMessage = require('./execute.js');
const FetchMessage = require('./fetch.js');
const LobOpMessage = require('./lobOp.js');
const LogOffMessage = require('./logOff.js');
const PingMessage = require('./ping.js');
const ProtocolMessage = require('./protocol.js');
const RollbackMessage = require('./rollback.js');
const SessionReleaseMessage = require('./sessionRelease.js');
module.exports = {
AuthMessage,
CommitMessage,
DataTypeMessage,
ExecuteMessage,
FetchMessage,
LobOpMessage,
LogOffMessage,
PingMessage,
ProtocolMessage,
RollbackMessage,
SessionReleaseMessage
};

View File

@ -0,0 +1,200 @@
// Copyright (c) 2022, 2023, Oracle and/or its affiliates.
//-----------------------------------------------------------------------------
//
// This software is dual-licensed to you under the Universal Permissive License
// (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
// 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
// either license.
//
// If you elect to accept the software under the Apache License, Version 2.0,
// the following applies:
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://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 Message = require('./base.js');
const constants = require('../constants.js');
/**
* Abstracts all LOB operations.
*
* @class LobOpMessage
* @extends {Message}
*/
class LobOpMessage extends Message {
constructor(connImpl, options) {
super(connImpl);
/*
* source LOB locator. Reading data from it.
*/
this.sourceLobImpl = options.sourceLobImpl || null;
this.operation = options.operation;
/*
* Destination LOB locator. For copy, append operations,...
*/
this.destLobImpl = options.destLobImpl || null;
/*
* Offset from where sourceLob operation to start
*/
this.sourceOffset = options.sourceOffset || 0;
/*
* Offset from where destLob operation to start
*/
this.destOffset = options.destOffset || 0;
this.boolFlag = false;
if (options.data) { // data available For Writes
this.data = options.data;
}
this.functionCode = constants.TNS_FUNC_LOB_OP;
this.sendAmount = options.sendAmount;
this.amount = options.amount || 0; // LOB length
}
encode(buf) {
this.writeFunctionHeader(buf);
if (this.sourceLobImpl === null) {
buf.writeUInt8(0);
buf.writeUB4(0);
} else {
buf.writeUInt8(1);
buf.writeUB4(this.sourceLobImpl._locator.length);
}
if (this.destLobImpl === null) {
buf.writeUInt8(0);
buf.writeUB4(0);
} else {
buf.writeUInt8(1);
buf.writeUB4(this.destLobImpl._locator.length);
}
buf.writeUB4(0);
buf.writeUB4(0);
if (this.operation === constants.TNS_LOB_OP_CREATE_TEMP) {
buf.writeUInt8(1);
} else {
buf.writeUInt8(0);
}
buf.writeUInt8(0);
if (this.operation === constants.TNS_LOB_OP_CREATE_TEMP
|| this.operation === constants.TNS_LOB_OP_IS_OPEN) {
buf.writeUInt8(1);
} else {
buf.writeUInt8(0);
}
buf.writeUB4(this.operation);
buf.writeUInt8(0);
buf.writeUInt8(0);
buf.writeUB8(this.sourceOffset);
buf.writeUB8(this.destOffset);
if (this.sendAmount) {
buf.writeUInt8(1);
} else {
buf.writeUInt8(0);
}
for (let i = 0; i < 3; i++) {
buf.writeUInt16BE(0);
}
if (this.sourceLobImpl) {
buf.writeBytes(this.sourceLobImpl._locator);
}
if (this.destLobImpl) {
buf.writeBytes(this.destLobImpl._locator);
}
if (this.operation === constants.TNS_LOB_OP_CREATE_TEMP) {
if (this.sourceLobImpl.dbType._csfrm === constants.TNS_CS_NCHAR) {
buf.caps.checkNCharsetId();
buf.writeUB4(constants.TNS_CHARSET_UTF16);
} else {
buf.writeUB4(constants.TNS_CHARSET_UTF8);
}
}
if (this.data) {
let data;
buf.writeUInt8(constants.TNS_MSG_TYPE_LOB_DATA);
if (this.sourceLobImpl.dbType._oraTypeNum === constants.TNS_DATA_TYPE_BLOB) {
data = this.data;
} else if (this.sourceLobImpl.getCsfrm() === constants.TNS_CS_NCHAR) {
data = this.data;
// TODO: avoid conversion back to string, if possible
// this is since bind data is converted to buffer automatically, but if
// it exceeds 32K for PL/SQL it must be written as a temporary LOB
if (Buffer.isBuffer(this.data)) {
data = data.toString();
}
data = Buffer.from(data, constants.TNS_ENCODING_UTF16).swap16();
} else {
data = Buffer.from(this.data);
}
buf.writeBytesWithLength(data);
}
if (this.sendAmount) {
buf.writeUB8(this.amount);
}
}
processMessage(buf, messageType) {
if (messageType === constants.TNS_MSG_TYPE_LOB_DATA) {
const oraTypeNum = this.sourceLobImpl.dbType._oraTypeNum;
let data = buf.readBytesWithLength();
if (data !== null) {
if (oraTypeNum === constants.TNS_DATA_TYPE_BLOB) {
data = Buffer.from(data);
} else if (this.sourceLobImpl.getCsfrm() === constants.TNS_CS_NCHAR) {
data = Buffer.from(data).swap16().toString('utf16le');
} else {
data = data.toString();
}
}
this.data = data;
} else {
super.processMessage(buf, messageType);
}
}
processReturnParameter(buf) {
let lobArray;
let locator;
let temp16;
let numBytes;
if (this.sourceLobImpl !== null) {
numBytes = this.sourceLobImpl._locator.length;
lobArray = buf.readBytes(numBytes);
locator = lobArray.slice(0, numBytes);
locator.copy(this.sourceLobImpl._locator);
}
if (this.destLobImpl !== null) {
numBytes = this.destLobImpl._locator.length;
lobArray = buf.readBytes(numBytes);
locator = lobArray.slice(0, numBytes);
locator.copy(this.destLobImpl._locator);
}
if (this.operation === constants.TNS_LOB_OP_CREATE_TEMP) {
buf.skipUB2();
}
if (this.sendAmount) {
this.amount = buf.readSB8();
}
if (this.operation === constants.TNS_LOB_OP_CREATE_TEMP
|| this.operation === constants.TNS_LOB_OP_IS_OPEN) {
temp16 = buf.readUB2();
this.boolFlag = temp16 > 0;
}
}
}
module.exports = LobOpMessage;

View File

@ -0,0 +1,53 @@
// Copyright (c) 2022, 2023, Oracle and/or its affiliates.
//-----------------------------------------------------------------------------
//
// This software is dual-licensed to you under the Universal Permissive License
// (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
// 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
// either license.
//
// If you elect to accept the software under the Apache License, Version 2.0,
// the following applies:
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://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 Message = require("./base.js");
const constants = require("../constants.js");
/**
* Executes Logoff RPC
*
* @class LogOffMessage
* @extends {Message}
*
*/
class LogOffMessage extends Message {
constructor(connImpl) {
super(connImpl);
this.functionCode = constants.TNS_FUNC_LOGOFF;
}
encode(buf) {
this.writePiggybacks(buf);
this.writeFunctionHeader(buf);
}
}
module.exports = LogOffMessage;

Some files were not shown because too many files have changed in this diff Show More