Documentation and Test updates for the latest changes and feature additions

This commit is contained in:
Sharad Chandran R 2024-03-11 16:56:28 +05:30
parent 6b029fea52
commit 9ac20938a8
10 changed files with 162 additions and 64 deletions

View File

@ -672,11 +672,12 @@ Connection Methods
**Promise**::
promise = execute(String sql [, Object bindParams [, Object options]]);
promise = execute(Object sql [, Object options]);
Executes a single SQL or PL/SQL statement. See :ref:`SQL
Execution <sqlexecution>` for examples. Also see
:meth:`connection.queryStream()` for an alternative way of executing
queries.
Executes a single SQL statement, PL/SQL statement, or the SQL statement
in the object that was returned by the ``sql`` function of the third-party
`sql-template-tag <https://www.npmjs.com/package/sql-template-tag#
oracledb>`__ module. See :ref:`SQL Execution <sqlexecution>` for examples.
The statement to be executed may contain :ref:`IN binds <inbind>`,
:ref:`OUT or IN OUT <outbind>` bind values or variables, which are bound
@ -699,10 +700,18 @@ Connection Methods
- Data Type
- Description
* - ``sql``
- String
- String or Object
- .. _executesqlparam:
The SQL statement that is executed. The statement may contain bind parameters.
This function parameter can either be a string or an object.
If the parameter is a string, then it is the SQL statement that is executed. The statement may contain bind parameters.
If the parameter is an object, then it is the object that is returned from the ``sql`` function of the third-party `sql-template-tag <https://www.npmjs.com/package/sql-template-tag#oracledb>`__ module. This object exposes the SQL statement and values properties to retrieve the SQL string and bind values. See :ref:`example <executeobj>`. If the object returned by the ``sql`` function contains a SQL statement with a ``RETURNING INTO`` clause, then :meth:`connection.execute()` will not work and an error will be thrown.
.. versionchanged:: 6.4
The ability to accept an object (returned from the ``sql`` function of the third-party ``sql-template-tag`` module) as an input parameter was added to :meth:`connection.execute()`.
* - ``bindParams``
- Object or Array
- .. _executebindParams:

View File

@ -168,6 +168,14 @@ it is to convert that DbObject to and from a JavaScript object.
Returns an array of element values as a JavaScript array in key order.
.. method:: dbObject.toMap()
Returns a map object for the collection types indexed by PLS_INTEGER where
the collections indexes are the keys and the elements are its values. See
:ref:`indexbyplsinteger` for example.
.. versionadded:: 6.4
.. method:: dbObject.trim(count)
Trims the specified number of elements from the end of the collection.

View File

@ -21,12 +21,12 @@ Common Changes
which returns a map object.
See `Issue #1627 <https://github.com/oracle/node-oracledb/issues/1627>`__.
#) Accept an object as an input parameter for :meth:`connection.execute()`
as per GitHub user request.
#) Added support to accept an object as an input parameter in the
:meth:`connection.execute()` method. This object is returned from the
third-party `sql-template-tag <https://www.npmjs.com/package/sql-template-
tag#oracledb>`__ module and exposes statement and values properties to
retrieve SQL string and bind values.
See `Issue #1629 <https://github.com/oracle/node-oracledb/issues/1629>`__.
This object is returned from the 3rd party ``sql-template-tag`` module and
exposes statement and values properties to retrieve sql string
and bind values.
#) Added new extended :ref:`metadata <execmetadata>` information attribute
``isOson`` for a fetched column.

View File

@ -421,6 +421,66 @@ Parameters <executebindParams>` for more information about binding.
See `plsqlarray.js <https://github.com/oracle/node-oracledb/tree/
main/examples/plsqlarray.js>`__ for a runnable example.
.. _indexbyplsinteger:
Associative Array Indexed By PLS_INTEGER
++++++++++++++++++++++++++++++++++++++++
The following example defines an associative array indexed by PLS_INTEGER and
a function that returns an associative array of that type.
.. code-block:: sql
DROP TABLE mytable;
CREATE TABLE mytable (id NUMBER, numcol NUMBER);
CREATE OR REPLACE PACKAGE mypkg IS
TYPE numtype IS TABLE OF NUMBER INDEX BY PLS_INTEGER;
FUNCTION F1 RETURN numtype;
END;
/
CREATE OR REPLACE PACKAGE BODY mypkg AS
FUNCTION F1 RETURN numtype IS
R numtype;
BEGIN
R(2):=22;
R(5):=55;
RETURN R;
END;
END;
/
To return a map object for collection types indexed by PLS_INTEGER to
get the keys along with values, you can use the :meth:`dbObject.toMap()`
method:
.. code-block:: javascript
const connection = await oracledb.getConnection({
user : "hr",
password : mypw, // contains the hr schema password
connectString : "localhost/FREEPDB1"
});
const result = await connection.execute(
`BEGIN
:ret := mypkg.f1;
END;`,
{
ret: {
dir: oracledb.BIND_OUT,
type: `mypkg.numtype`
}
});
const res = result.outBinds.ret;
console.log(res.toMap());
This will print::
Map(2) { 2 => 22, 5 => 55 }
.. _plsqlvarray:
PL/SQL Collection VARRAY Types

View File

@ -92,6 +92,28 @@ cases:
In both cases, use a :ref:`ResultSet <resultsethandling>` or :ref:`Query
Stream <streamingresults>` instead of a direct fetch.
.. _executeobj:
If you are using the ``sql`` function of the third-party `sql-template-tag
<https://www.npmjs.com/package/sql-template-tag#oracledb>`__ module, then you
can pass the object returned by this function in :meth:`connection.execute()`.
This object exposes the SQL statement and values properties to retrieve the
SQL string and bind values.
.. code-block:: javascript
import sql from sql-template-tag;
const id = 20;
let options = { maxRows: 1 };
query = sql`SELECT * FROM departments WHERE department_id = ${id}`;
result = await connection.execute(query, options);
console.log(result.rows);
If the object returned by the ``sql`` function contains a SQL statement with a
``RETURNING INTO`` clause, then :meth:`connection.execute()` will not work and
an error will be thrown.
.. _resultsethandling:
Fetching Rows with Result Sets

View File

@ -35,7 +35,6 @@ const oracledb = require('oracledb');
const assert = require('assert');
const dbConfig = require('./dbconfig.js');
const testsUtil = require('./testsUtil.js');
const util = require('util');
describe('192. implicitResults.js', function() {
@ -162,7 +161,7 @@ describe('192. implicitResults.js', function() {
rs = await results.implicitResults[1];
let row, len = 0;
while ((row = await rs.getRow())) {
assert(util.isDate(row[1]));
assert(testsUtil.isDate(row[1]));
len++;
}
const tab2Len = 5;
@ -185,7 +184,7 @@ describe('192. implicitResults.js', function() {
rs = await results.implicitResults[1];
let row, len = 0;
while ((row = await rs.getRow())) {
assert(util.isDate(row.TSVAL));
assert(testsUtil.isDate(row.TSVAL));
len++;
}
const tab2Len = 5;

View File

@ -37,7 +37,7 @@ const dbConfig = require('./dbconfig.js');
describe('45. instanceof1.js', function() {
it('45.2 instanceof works for pool instances', async function() {
it('45.1 instanceof works for pool instances', async function() {
const config = {
...dbConfig,
poolMin: 0,
@ -47,34 +47,34 @@ describe('45. instanceof1.js', function() {
const pool = await oracledb.createPool(config);
assert(pool instanceof oracledb.Pool);
await pool.close(0);
});
}); // 45.1
it('45.3 instanceof works for connection instances', async function() {
it('45.2 instanceof works for connection instances', async function() {
const conn = await oracledb.getConnection(dbConfig);
assert(conn instanceof oracledb.Connection);
await conn.close();
});
}); // 45.2
it('45.4 instanceof works for resultset instances', async function() {
it('45.3 instanceof works for resultset instances', async function() {
const conn = await oracledb.getConnection(dbConfig);
const sql = 'select 1 from dual union select 2 from dual';
const binds = [];
const options = {
resultSet: true
};
}; // 45.3
const result = await conn.execute(sql, binds, options);
assert(result.resultSet instanceof oracledb.ResultSet);
await result.resultSet.close();
await conn.close();
});
it('45.5 instanceof works for lob instances', async function() {
it('45.4 instanceof works for lob instances', async function() {
const conn = await oracledb.getConnection(dbConfig);
const result = await conn.execute('select to_clob(dummy) from dual');
const lob = result.rows[0][0];
assert(lob instanceof oracledb.Lob);
lob.destroy();
await conn.close();
}); // 45.5
}); // 45.4
});

View File

@ -736,10 +736,10 @@ Overview of node-oracledb functional tests
44.8 maxSize option applies to each elements of an array
45. instanceof1.js
45.2 instanceof works for pool instances
45.3 instanceof works for connection instances
45.4 instanceof works for resultset instances
45.5 instanceof works for lob instances
45.1 instanceof works for pool instances
45.2 instanceof works for connection instances
45.3 instanceof works for resultset instances
45.4 instanceof works for lob instances
51. poolClose.js
51.1 can not get connections from the terminated pool
@ -800,16 +800,16 @@ Overview of node-oracledb functional tests
55.7 getting multiple resultSets
55.7.1 can access multiple resultSet on one connection
55.7.2 can access multiple REF Cursor
55.9 test querying a PL/SQL function
55.8 test querying a PL/SQL function
55.8.1
55.9 calls getRows() once and then close RS before getting more rows
55.9.1
55.10 calls getRows() once and then close RS before getting more rows
55.10.1
55.11 result set with unsupported data types
55.11.1 INTERVAL YEAR TO MONTH data type
55.12 bind a cursor BIND_INOUT
55.12.1 has not supported binding a cursor with BIND_INOUT
55.13 Invalid Ref Cursor
55.13.1
55.10 result set with unsupported data types
55.10.1 INTERVAL YEAR TO MONTH data type
55.11 bind a cursor BIND_INOUT
55.11.1 has not supported binding a cursor with BIND_INOUT
55.12 Invalid Ref Cursor
55.12.1
56. fetchAs.js
56.1 property value check

View File

@ -187,7 +187,7 @@ describe('12. resultSet1.js', function() {
);
});
});
}); // 12.1
describe('12.2 Testing fetchArraySize option', function() {
it('12.2.1 negative - negative value', async function() {
@ -255,7 +255,7 @@ describe('12. resultSet1.js', function() {
);
});
});
}); // 12.2
describe('12.3 Testing function getRows()', function() {
it('12.3.1 retrieved set is exactly the size of result', async function() {
@ -457,7 +457,7 @@ describe('12. resultSet1.js', function() {
);
});
});
}); // 12.3
describe('12.4 Testing function getRow()', function() {
it('12.4.1 works well with all correct setting', async function() {
@ -545,7 +545,7 @@ describe('12. resultSet1.js', function() {
await rs.close();
});
});
}); // 12.4
describe('12.5 Testing function close()', function() {
it('12.5.1 does not call close()', async function() {
@ -622,7 +622,7 @@ describe('12. resultSet1.js', function() {
});
});
}); // 12.5
describe('12.6 Testing metaData', function() {
@ -767,7 +767,7 @@ describe('12. resultSet1.js', function() {
await rs.close();
await conn.execute("DROP TABLE " + tableName + " PURGE");
});
});
}); // 12.6
describe('12.7 Testing maxRows', function() {
it('12.7.1 maxRows option is ignored when resultSet option is true', async function() {

View File

@ -88,7 +88,7 @@ describe('55. resultSet2.js', function() {
assert.strictEqual(rowCount, 100);
});
});
}); // 55.2
describe('55.3 alternating getRow() & getRows() function', function() {
before(async function() {
@ -157,7 +157,7 @@ describe('55. resultSet2.js', function() {
assert.strictEqual(accessCount, (100 / (numRows + 1)) * 2);
});
});
}); // 55.3
describe('55.4 automatically close result sets and LOBs when the connection is closed', function() {
before(async function() {
@ -204,7 +204,7 @@ describe('55. resultSet2.js', function() {
await fetchRowFromRS(result.outBinds.out);
});
});
}); // 55.4
describe('55.5 the content of resultSet should be consistent', function() {
before(async function() {
@ -233,7 +233,7 @@ describe('55. resultSet2.js', function() {
await rs.close();
});
});
}); // 55.5
describe('55.6 access resultSet simultaneously', function() {
before(async function() {
@ -306,7 +306,7 @@ describe('55. resultSet2.js', function() {
assert.match(values[1].reason.message, /NJS-017:/);
});
});
}); // 55.6
describe('55.7 getting multiple resultSets', function() {
before(async function() {
@ -371,9 +371,9 @@ describe('55. resultSet2.js', function() {
}
});
});
}); // 55.7
describe('55.9 test querying a PL/SQL function', function() {
describe('55.8 test querying a PL/SQL function', function() {
before(async function() {
await setUp(connection, tableName);
});
@ -382,7 +382,7 @@ describe('55. resultSet2.js', function() {
await clearUp(connection, tableName);
});
it('55.9.1 ', async function() {
it('55.8.1 ', async function() {
const proc =
"CREATE OR REPLACE FUNCTION nodb_rs2_testfunc RETURN VARCHAR2 \
IS \
@ -403,9 +403,9 @@ describe('55. resultSet2.js', function() {
await result.resultSet.close();
await connection.execute("DROP FUNCTION nodb_rs2_testfunc");
});
});
}); // 55.8
describe('55.10 calls getRows() once and then close RS before getting more rows', function() {
describe('55.9 calls getRows() once and then close RS before getting more rows', function() {
before(async function() {
await setUp(connection, tableName);
});
@ -414,7 +414,7 @@ describe('55. resultSet2.js', function() {
await clearUp(connection, tableName);
});
it('55.10.1 ', async function() {
it('55.9.1 ', async function() {
const numRows = 10;
const result = await connection.execute(
"SELECT * FROM nodb_rs2_emp ORDER BY employees_id",
@ -428,19 +428,19 @@ describe('55. resultSet2.js', function() {
/NJS-018:/
);
});
});
}); // 55.9
describe('55.11 result set with unsupported data types', function() {
it('55.11.1 INTERVAL YEAR TO MONTH data type', async function() {
describe('55.10 result set with unsupported data types', function() {
it('55.10.1 INTERVAL YEAR TO MONTH data type', async function() {
await assert.rejects(async () => {
await connection.execute(
"SELECT dummy, to_yminterval('1-3') FROM dual");
}, /NJS-010:/);
});
}); // 55.11
}); // 55.10
describe.skip('55.12 bind a cursor BIND_INOUT', function() {
describe.skip('55.11 bind a cursor BIND_INOUT', function() {
before('prepare table nodb_rs2_emp', async function() {
await setUp(connection, tableName);
@ -450,7 +450,7 @@ describe('55. resultSet2.js', function() {
await clearUp(connection, tableName);
});
it('55.12.1 has not supported binding a cursor with BIND_INOUT', async function() {
it('55.11.1 has not supported binding a cursor with BIND_INOUT', async function() {
const proc =
"CREATE OR REPLACE PROCEDURE nodb_rs2_get_emp_inout (p_in IN NUMBER, p_out IN OUT SYS_REFCURSOR) \
AS \
@ -467,13 +467,13 @@ describe('55. resultSet2.js', function() {
in: 200,
out: { type: oracledb.CURSOR, dir: oracledb.BIND_INOUT }
});
}, /NJS-0007:/);
}, /NJS-007:/);
await connection.execute("DROP PROCEDURE nodb_rs2_get_emp_inout");
});
}); // 55.12
}); // 55.11
describe('55.13 Invalid Ref Cursor', function() {
describe('55.12 Invalid Ref Cursor', function() {
const proc =
"CREATE OR REPLACE PROCEDURE get_invalid_refcur ( p OUT SYS_REFCURSOR) " +
" AS " +
@ -491,7 +491,7 @@ describe('55. resultSet2.js', function() {
await clearUp(connection, tableName);
});
it('55.13.1 ', async function() {
it('55.12.1 ', async function() {
await assert.rejects(async () => {
await connection.execute(
"BEGIN get_invalid_refcur ( :p ); END; ",
@ -500,8 +500,8 @@ describe('55. resultSet2.js', function() {
});
}, /NJS-107:/);
}); // 55.13.1
}); // 55.13
}); // 55.12.1
}); // 55.12
});