Skip to content

Commit 9859ebc

Browse files
committed
Change outconverter for isOson formatted columns to return JSON object
1 parent 5c292fa commit 9859ebc

File tree

3 files changed

+57
-24
lines changed

3 files changed

+57
-24
lines changed

doc/src/release_notes.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,16 @@ node-oracledb `v6.4.0 <https://github.com/oracle/node-oracledb/compare/v6.3.0...
1313
Common Changes
1414
++++++++++++++
1515

16+
#) Add support for fetching BLOB columns which have "IS JSON FORMAT OSON"
17+
constraint enabled in the same way as columns of type JSON.
18+
In node-oracledb :ref:`Thick mode <enablingthick>` this requires
19+
Oracle Client 21c or higher. Applications can get this new fetch behaviour
20+
by setting the oracledb property :attr:`oracledb.future.oldJsonColumnAsObj`
21+
to `true`. The default value for this property is `false` which retains
22+
the existing fetch behaviour.
23+
In a future version, the new fetch behaviour will become default and
24+
setting this property will no longer be needed.
25+
1626
#) Added methods :meth:`~Connection.decodeOSON` and
1727
:meth:`~Connection.encodeOSON` to support fetching and inserting into
1828
columns which have the check constraint ``IS JSON FORMAT OSON``

lib/impl/resultset.js

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ const settings = require('../settings.js');
3333
const future = require('../future.js');
3434
const types = require('../types.js');
3535
const Lob = require('../lob.js');
36+
const oson = require('./datahandlers/oson.js');
3637

3738
// define implementation class
3839
class ResultSetImpl {
@@ -105,26 +106,42 @@ class ResultSetImpl {
105106
let converter;
106107
const userConverter = metadata.converter;
107108

108-
// If IsJson is set convert to JSON objects unless
109+
// If IsJson or IsOson is set, convert to JSON objects unless
109110
// user defined output type handler overwrites it.
110-
if (future.oldJsonColumnAsObj && metadata.isJson && metadata.dbType !== types.DB_TYPE_JSON
111+
if (metadata.dbType !== types.DB_TYPE_JSON && future.oldJsonColumnAsObj
111112
&& userConverter === undefined) {
112-
const outConverter = async function(val) {
113-
if (!val) {
114-
return val;
115-
}
113+
let outConverter;
114+
if (metadata.isOson) {
115+
outConverter = async function(val) {
116+
if (!val) {
117+
return val;
118+
}
119+
let result = val;
120+
if (val instanceof Lob) {
121+
result = await val.getData();
122+
}
123+
const decoder = new oson.OsonDecoder(result);
124+
return decoder.decode();
125+
};
126+
converter = outConverter;
127+
} else if (metadata.isJson) {
128+
outConverter = async function(val) {
129+
if (!val) {
130+
return val;
131+
}
116132

117-
let result = val;
118-
if (val instanceof Lob) {
119-
result = await val.getData();
120-
}
121-
if (result instanceof Buffer) {
122-
result = result.toString();
123-
}
124-
result = JSON.parse(result);
125-
return result;
126-
};
127-
converter = outConverter;
133+
let result = val;
134+
if (val instanceof Lob) {
135+
result = await val.getData();
136+
}
137+
if (result instanceof Buffer) {
138+
result = result.toString();
139+
}
140+
result = JSON.parse(result);
141+
return result;
142+
};
143+
converter = outConverter;
144+
}
128145
}
129146

130147
// in thin mode, Oracle NUMBER values are internally fetched as string in

test/dataTypeBlob.js

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,6 @@ describe('41. dataTypeBlob.js', function() {
167167
const plsql = testsUtil.sqlCreateTable(TABLE, createTable);
168168

169169
before('create table', async function() {
170-
oracledb.fetchAsBuffer = [oracledb.BLOB];
171170
if (testsUtil.getClientVersion() >= 2100000000 &&
172171
connection.oracleServerVersion >= 2100000000) {
173172
isRunnable = true;
@@ -177,11 +176,13 @@ describe('41. dataTypeBlob.js', function() {
177176
this.skip();
178177
}
179178

179+
// Allows automatically converting OSON formatted columns to JSON objects.
180+
oracledb.future.oldJsonColumnAsObj = true;
180181
await connection.execute(plsql);
181182
});
182183

183184
after(async function() {
184-
oracledb.fetchAsBuffer = [];
185+
oracledb.future.oldJsonColumnAsObj = false;
185186
await connection.execute(testsUtil.sqlDropTable(TABLE));
186187
});
187188

@@ -203,25 +204,30 @@ describe('41. dataTypeBlob.js', function() {
203204
values (1, :1, :2) `,
204205
[byteBuf, byteBuf]);
205206
result = await connection.execute(`select OSONCOL from ${TABLE}`);
206-
let generatedObj = connection.decodeOSON(result.rows[0][0]);
207-
assert.deepStrictEqual(expectedObj1, generatedObj);
207+
assert.deepStrictEqual(expectedObj1, result.rows[0][0]);
208208

209209
// Generate OSON bytes and insert these bytes and verify with decode.
210210
const osonBytes = connection.encodeOSON(expectedObj2);
211211
result = await connection.execute(`insert into ${TABLE}(IntCol, OsonCol, blobCol)
212212
values (2, :1, :2) `,
213213
[osonBytes, byteBuf]);
214214
result = await connection.execute(`select OSONCOL from ${TABLE} where IntCol = 2`);
215-
generatedObj = connection.decodeOSON(result.rows[0][0]);
216-
assert.deepStrictEqual(expectedObj2, generatedObj);
215+
assert.deepStrictEqual(expectedObj2, result.rows[0][0]);
217216

218217
// Verify vector inside OSON image for 23.4 server onwards.
219218
if (connection.oracleServerVersion >= 2304000000) {
220219
result = await connection.execute(`insert into ${TABLE}(IntCol, OsonCol, blobCol)
221220
values (3, :1, :2) `,
222221
[connection.encodeOSON(expectedObj3), byteBuf]);
223222
result = await connection.execute(`select OSONCOL from ${TABLE} where IntCol = 3`);
224-
generatedObj = connection.decodeOSON(result.rows[0][0]);
223+
assert.deepStrictEqual(expectedObj3, result.rows[0][0]);
224+
225+
// Verify LOB is returned by default (oracledb.future.oldJsonColumnAsObj = false).
226+
// We need to explicitly use decodeOSON to convert the LOB data into JSON object.
227+
oracledb.future.oldJsonColumnAsObj = false;
228+
result = await connection.execute(`select OSONCOL from ${TABLE} where IntCol = 3`);
229+
const lob = result.rows[0][0];
230+
const generatedObj = connection.decodeOSON(await lob.getData());
225231
assert.deepStrictEqual(expectedObj3, generatedObj);
226232
}
227233

0 commit comments

Comments
 (0)