From d25150c91d6a17721458dac29284fd157ec1698e Mon Sep 17 00:00:00 2001 From: Sharad Chandran R Date: Thu, 20 Jun 2024 12:34:38 +0530 Subject: [PATCH] Added capability to read XMLType data in DbObject in Thin mode --- doc/src/release_notes.rst | 15 ++++++++---- lib/thin/connection.js | 6 +++++ lib/thin/dbObject.js | 4 +++ test/dbObject20.js | 51 +++++++++++++++++++++++++++++++++++++++ test/list.txt | 2 ++ 5 files changed, 73 insertions(+), 5 deletions(-) diff --git a/doc/src/release_notes.rst b/doc/src/release_notes.rst index 4ff77ba5..d08dcf21 100644 --- a/doc/src/release_notes.rst +++ b/doc/src/release_notes.rst @@ -7,19 +7,24 @@ node-oracledb Release Notes For deprecated and desupported features, see :ref:`Deprecations and desupported features `. -node-oracledb `v6.6 `__ (TBD) +node-oracledb `v6.6.0 `__ (TBD) --------------------------------------------------------------------------------------------------------- Thin Mode Changes +++++++++++++++++ -#) Fixed bug which throws an error ``NJS-130`` when calling +#) Fixed bug which throws a ``TypeError: objType.attributes is not iterable`` + error when :ref:`DbObject Class ` instance contains an + attribute of type ``SYS.XMLTYPE``. + +#) Fixed bug which throws an ``NJS-130`` error when calling :meth:`connection.getDbObjectClass()` with an object type name containing ``%ROWTYPE``. -#) Fixed bug which throws an `NJS-112` error during fetching of JSON and - vector columns after table recreation. This is similar to the - fix provided for GitHub issue #1565. +#) Fixed bug which throws an ``NJS-112`` error during fetching of JSON and + vector columns after table recreation. This fix is similar to the one + provided for `Issue #1565 `__. node-oracledb `v6.5.1 `__ (23 May 2024) --------------------------------------------------------------------------------------------------------- diff --git a/lib/thin/connection.js b/lib/thin/connection.js index 3af0c996..25066963 100644 --- a/lib/thin/connection.js +++ b/lib/thin/connection.js @@ -385,6 +385,9 @@ class ThinConnectionImpl extends ConnectionImpl { info.elementType = this._parseTDSAttr(buf, info.elementTypeInfo); if (info.elementType === types.DB_TYPE_OBJECT) { await this._getElementTypeObj(info); + if (info.elementTypeClass.isXmlType) { + info.elementType = types.DB_TYPE_XMLTYPE; + } } } else { if (info.attributes) { // skip for XML type as it has no attributes. @@ -622,6 +625,9 @@ class ThinConnectionImpl extends ConnectionImpl { attrInfo.oid ); + if (attr.typeClass.isXmlType) { + attr.type = types.DB_TYPE_XMLTYPE; + } if (attr.typeClass.partial) { this._partialDbObjectTypes.push(attr.typeClass); } diff --git a/lib/thin/dbObject.js b/lib/thin/dbObject.js index 28bd01c5..f60e6a2b 100644 --- a/lib/thin/dbObject.js +++ b/lib/thin/dbObject.js @@ -397,10 +397,14 @@ class ThinDbObjectImpl extends DbObjectImpl { case types.DB_TYPE_BOOLEAN: return buf.readBool(); case types.DB_TYPE_OBJECT: + case types.DB_TYPE_XMLTYPE: isNull = buf.getIsAtomicNull(); if (isNull) return null; obj = new ThinDbObjectImpl(typeClass); + if (obj._objType.isXmlType) { + return readXML(obj._objType._connection, buf.readBytesWithLength()); + } if (obj._objType.isCollection || this._objType.isCollection) { obj.packedData = Buffer.from(buf.readBytesWithLength()); } else { diff --git a/test/dbObject20.js b/test/dbObject20.js index 53dd37f7..f263120f 100644 --- a/test/dbObject20.js +++ b/test/dbObject20.js @@ -1218,4 +1218,55 @@ describe('290. dbObject20.js', () => { }); }); + (oracledb.thin ? describe : describe.skip)(`290.6 db Object tests with XML Value type`, () => { + let conn; + const TYPE1 = 'NODB_TEST_XMLTYPE'; + const maxVarCharLen = 40; + + before(async () => { + const sql = `CREATE TYPE ${TYPE1} FORCE AS OBJECT ( ID NUMBER, + XMLDATA sys.xmltype, NAME VARCHAR2(${maxVarCharLen}))`; + conn = await oracledb.getConnection(dbConfig); + await testsUtil.createType(conn, TYPE1, sql); + }); // before() + + after(async () => { + if (conn) { + await testsUtil.dropType(conn, TYPE1); + await conn.close(); + } + }); // after() + + it('290.6.1 Verify XML value and metaData inside object', async () => { + const testXMLData = + '\n ' + + '1\n ' + + 'Melbourne, Australia\n ' + + 'Owned\n ' + + '2020\n ' + + '1\n ' + + 'Rear load\n ' + + 'false\n ' + + 'N\n ' + + 'Garage\n ' + + '20\n' + + '\n'; + const numVal = 234; + const charVal = 'JOHN'; + const expectedData = { "ID": numVal, "XMLDATA": testXMLData, "NAME": charVal }; + const sql = `select ${TYPE1}(${expectedData.ID}, sys.xmltype('${expectedData.XMLDATA}'), + '${expectedData.NAME}') from dual`; + + const result = await conn.execute(sql); + assert.strictEqual(JSON.stringify(result.rows[0][0]), JSON.stringify(expectedData)); + + // Validate metadata. + const xmlObjClass = result.metaData[0]; + const pInObj = new xmlObjClass.dbTypeClass(); + assert.strictEqual(pInObj.attributes.XMLDATA.type, oracledb.DB_TYPE_XMLTYPE); + assert.strictEqual(pInObj.attributes.ID.type, oracledb.DB_TYPE_NUMBER); + assert.strictEqual(pInObj.attributes.NAME.type, oracledb.DB_TYPE_VARCHAR); + }); + }); + }); diff --git a/test/list.txt b/test/list.txt index 163bffcd..9ec775b0 100755 --- a/test/list.txt +++ b/test/list.txt @@ -5686,6 +5686,8 @@ oracledb.OUT_FORMAT_OBJECT and resultSet = true 290.4.4 Verify table of VARCHAR2 with CHAR/BYTE specifier 290.5 Associative Arrays fetch 290.5.1 verify associative array outbinds + 290.6 db Object tests with XML Value type + 290.6.1 Verify XML value and metaData inside object 291. dbSchema.js 291.1 dbSchema and Annotations