Skip to content

Commit c2feec0

Browse files
committed
Test case cleanup and documentation update for the JsonId class
1 parent b9ba65d commit c2feec0

File tree

8 files changed

+116
-35
lines changed

8 files changed

+116
-35
lines changed

doc/src/api_manual/oracledb.rst

+14
Original file line numberDiff line numberDiff line change
@@ -3511,3 +3511,17 @@ node-oracledb, allowing use of new features.
35113511

35123512
BLOB columns with the ``IS JSON FORMAT OSON`` check constraint enabled
35133513
can now be fetched as JSON type columns when this property is set.
3514+
3515+
.. _jsonid:
3516+
3517+
Oracledb JsonId Class
3518+
=====================
3519+
3520+
Objects of this class are returned by :ref:`SODA <sodaoverview>` in the
3521+
``_id`` attribute of documents stored in native collections when using
3522+
Oracle Database 23.4 (or later). The JsonId class is a subclass of `Uint8Array
3523+
<https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
3524+
Global_Objects/Uint8Array>`__ and can be instantiated in the same way as an
3525+
Uint8Array datatype object.
3526+
3527+
.. versionadded:: 6.5

doc/src/user_guide/soda.rst

+63
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,69 @@ operations using :meth:`sodaCollection.save()` and
299299
are similar to the insertion methods, however if an existing document
300300
with the same key already exists in the collection, it is replaced.
301301

302+
If you are using Oracle Database 23.4 (or later), you can define the key
303+
directly in the document content by specifying the key in the ``_id`` field
304+
as shown below:
305+
306+
.. code-block:: javascript
307+
308+
try {
309+
const myContent = {_id: 1, name: "Sally", address: {city: "Melbourne"}};
310+
const newDoc = soda.createDocument(myContent);
311+
await collection.insertOne(newDoc);
312+
} catch(err) {
313+
console.error(err);
314+
}
315+
316+
If you do not specify the ``_id`` field, then the :ref:`jsonid` returns an
317+
automatically generated hex-encoded string as the key value. Once the key is
318+
automatically generated, it cannot be overwritten with a new value. If you do
319+
try to update the value, then the following error will be returned::
320+
321+
ORA-54059:/ // cannot update an immutable column to a different value
322+
323+
The JsonId value from one SODA document collection can be specified in another
324+
document collection. For example, ``STUDENTS`` collection can have courseID
325+
set from ``COURSES`` collection _id:
326+
327+
.. code-block:: javascript
328+
329+
// Create STUDENTS Collection
330+
await connection.execute(`CREATE JSON COLLECTION TABLE if not exists STUDENTS`);
331+
332+
// Create COURSES Collection
333+
await connection.execute(`CREATE JSON COLLECTION TABLE if not exists COURSES`);
334+
335+
// Add a course document
336+
const courseDoc = {"department": "Physics", "Professor": "Fred"};
337+
let sql = `INSERT INTO COURSES VALUES (:1)`;
338+
let result = await connection.execute(sql, [{
339+
type: oracledb.DB_TYPE_JSON,
340+
val: courseDoc
341+
}]);
342+
343+
// Read the course inserted above which would have _id (JsonId type) populated.
344+
sql = `SELECT * FROM COURSES`;
345+
result = await connection.execute(sql);
346+
347+
// Add a student document with foreign key, courseID referring to COURSES collection.
348+
const studentDoc = {"name": "Jenny"};
349+
studentDoc.courseID = [];
350+
studentDoc.courseID.push(result.rows[0][0]._id);
351+
sql = `INSERT INTO STUDENTS VALUES (:1)`;
352+
result = await connection.execute(sql, [{
353+
type: oracledb.DB_TYPE_JSON,
354+
val: studentDoc
355+
}]);
356+
357+
// Read the student documents
358+
sql = `SELECT * FROM STUDENTS`;
359+
result = await connection.execute(sql);
360+
console.log('Student Document:', JSON.stringify(result.rows[0][0])) // Student Document:
361+
{"name":"Jenny","courseID":
362+
["661e0fea4583f699cc6a0b2a"],"_id":"661e105445ac389beaaf05ec"
363+
}
364+
302365
To extract documents from a collection, the
303366
:meth:`~sodaCollection.find()` method can be used to build a
304367
:ref:`SodaOperation <sodaoperationclass>` object specifying the keys of

test/aq1.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -188,20 +188,20 @@ describe('217. aq1.js', function() {
188188
assert.strictEqual(messages2[0].payload.toString(), messages1[0]);
189189
assert.strictEqual(messages2.length, messages1.length);
190190
}
191-
}); // 217.4
191+
}); // 217.4
192192

193193
it('217.5 deqOne on empty queue', async () => {
194194
const queue2 = await conn.getQueue(rawQueueName);
195195
queue2.deqOptions.wait = oracledb.AQ_DEQ_NO_WAIT;
196196
const message = await queue2.deqOne();
197197
assert.strictEqual(message, undefined);
198-
});
198+
}); // 217.5
199199

200200
it('217.6 deqMany on empty queue', async () => {
201201
const queue2 = await conn.getQueue(rawQueueName);
202202
queue2.deqOptions.wait = oracledb.AQ_DEQ_NO_WAIT;
203203
const messages = await queue2.deqMany(1);
204204
assert.deepStrictEqual(messages, []);
205-
});
205+
}); // 217.6
206206

207207
});

test/aq4.js

+12-12
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2022, 2023, Oracle and/or its affiliates. */
1+
/* Copyright (c) 2022, 2024, Oracle and/or its affiliates. */
22

33
/******************************************************************************
44
*
@@ -151,7 +151,7 @@ describe('267. aq4.js', function() {
151151
},
152152
/ORA-24033:/
153153
);
154-
});
154+
}); // 267.1
155155

156156
it('267.2 single element in array', async () => {
157157
// Enqueue
@@ -179,7 +179,7 @@ describe('267. aq4.js', function() {
179179
const msg = await queue2.deqOne ();
180180
assert.strictEqual(msg.payload.NAME, "scott");
181181
await conn.commit();
182-
});
182+
}); // 267.2
183183

184184

185185
it('267.3 Negative - numbers as recipients ', async () => {
@@ -197,7 +197,7 @@ describe('267. aq4.js', function() {
197197
},
198198
/NJS-007:/
199199
);
200-
});
200+
}); // 267.3
201201

202202
it('267.4 Negative - number, string, date as recipients ', async () => {
203203
const queue1 = await conn.getQueue(
@@ -214,7 +214,7 @@ describe('267. aq4.js', function() {
214214
},
215215
/NJS-007:/
216216
);
217-
});
217+
}); // 267.4
218218

219219
it('267.5 Negative - null value for recipient', async () => {
220220
const queue1 = await conn.getQueue(
@@ -231,7 +231,7 @@ describe('267. aq4.js', function() {
231231
},
232232
/NJS-007:/
233233
);
234-
});
234+
}); // 267.5
235235

236236
it('267.6 Negative - undefined value for recipient', async () => {
237237
const queue1 = await conn.getQueue(
@@ -248,7 +248,7 @@ describe('267. aq4.js', function() {
248248
},
249249
/NJS-007:/
250250
);
251-
});
251+
}); // 267.6
252252

253253
it('267.7 Negative - dequeue non-existent name', async () => {
254254
await assert.rejects(
@@ -279,7 +279,7 @@ describe('267. aq4.js', function() {
279279
},
280280
/ORA-25242:/
281281
);
282-
});
282+
}); // 267.7
283283

284284

285285
it('267.8 empty recipient list with enqMany', async () => {
@@ -297,7 +297,7 @@ describe('267. aq4.js', function() {
297297
},
298298
/ORA-24033:/
299299
);
300-
});
300+
}); // 267.8
301301

302302
it('267.9 recipient list with enqMany', async () => {
303303
const msgList = [];
@@ -322,7 +322,7 @@ describe('267. aq4.js', function() {
322322
);
323323
const msgs = await queue2.deqMany(5);
324324
assert.strictEqual(msgs.length, 4);
325-
});
325+
}); // 267.9
326326

327327

328328
it('267.10 recipient list with enqMany non-existent in dequeue', async () => {
@@ -348,7 +348,7 @@ describe('267. aq4.js', function() {
348348
);
349349
const msgs = await queue2.deqMany(5);
350350
assert.strictEqual(msgs.length, 0);
351-
});
351+
}); // 267.10
352352

353353
it('267.11 recipient list with enqMany invalid datatype in dequeue', async () => {
354354
const msgList = [];
@@ -366,6 +366,6 @@ describe('267. aq4.js', function() {
366366
},
367367
/NJS-007:/
368368
);
369-
});
369+
}); // 267.11
370370

371371
});

test/aq5.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2023, Oracle and/or its affiliates. */
1+
/* Copyright (c) 2023, 2024, Oracle and/or its affiliates. */
22

33
/******************************************************************************
44
*
@@ -129,6 +129,6 @@ describe('281.aq5.js', function() {
129129
assert(msg);
130130

131131
await conn.unsubscribe(objQueueName);
132-
});
132+
}); // 281.1
133133

134134
});

test/aq7.js

+16-16
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2023, Oracle and/or its affiliates. */
1+
/* Copyright (c) 2023, 2024, Oracle and/or its affiliates. */
22

33
/******************************************************************************
44
*
@@ -112,7 +112,7 @@ describe('283. aq7.js', function() {
112112

113113
assert.strictEqual(msg.payload.empName, "Chris");
114114
assert.strictEqual(msg.payload.empCity, "Melbourne");
115-
});
115+
}); // 283.1
116116

117117
it('283.2 JSON type in enqMany/deqMany', async () => {
118118
const queue3 = await conn.getQueue(objQueueName,
@@ -146,7 +146,7 @@ describe('283. aq7.js', function() {
146146
assert.equal(msgs[0].payload.empId, 101);
147147
assert.equal(msgs[1].payload.empId, 102);
148148
assert.equal(msgs[2].payload.empId, 103);
149-
});
149+
}); // 283.2
150150

151151
it('283.3 Map JS object directly into JSON - enqOne/deqOne', async () => {
152152
const queue = await conn.getQueue(objQueueName,
@@ -171,7 +171,7 @@ describe('283. aq7.js', function() {
171171

172172
assert.equal(msg.payload.empName, "employee name");
173173
assert.equal(msg.payload.empCity, "City");
174-
});
174+
}); // 283.3
175175

176176
it('283.4 Map JS object directly into JSON - enqMany/deqMany', async () => {
177177
const queue = await conn.getQueue(objQueueName,
@@ -185,7 +185,7 @@ describe('283. aq7.js', function() {
185185
];
186186

187187
await queue.enqMany(dataList);
188-
await conn.commit ();
188+
await conn.commit();
189189

190190
const queue2 = await conn.getQueue(objQueueName,
191191
{payloadType: oracledb.DB_TYPE_JSON});
@@ -205,7 +205,7 @@ describe('283. aq7.js', function() {
205205
assert.equal(msgs[0].payload.empCity, "City1");
206206
assert.equal(msgs[1].payload.empCity, "City2");
207207
assert.equal(msgs[2].payload.empCity, "City3");
208-
});
208+
}); // 283.4
209209

210210
it('283.5 enqOne and deqOne Null & Boolean in JSON', async function() {
211211
const queue = await conn.getQueue(objQueueName,
@@ -229,7 +229,7 @@ describe('283. aq7.js', function() {
229229

230230
assert.equal(msg.payload.empName, null);
231231
assert.equal(msg.payload.empCity, true);
232-
});
232+
}); // 283.5
233233

234234
it('283.6 enqMany and deqMany Null & Boolean in JSON', async function() {
235235
const queue = await conn.getQueue(objQueueName,
@@ -263,7 +263,7 @@ describe('283. aq7.js', function() {
263263
assert.equal(msgs[0].payload.empCity, true);
264264
assert.equal(msgs[1].payload.empCity, false);
265265
assert.equal(msgs[2].payload.empCity, true);
266-
});
266+
}); // 283.6
267267

268268
it('283.7 enqOne and deqOne with JSON val as array type', async function() {
269269
const queue = await conn.getQueue(objQueueName,
@@ -278,11 +278,11 @@ describe('283. aq7.js', function() {
278278
const queue2 = await conn.getQueue(objQueueName,
279279
{payloadType: oracledb.DB_TYPE_JSON});
280280
const msg = await queue2.deqOne();
281-
await conn.commit ();
281+
await conn.commit();
282282

283283
assert.deepStrictEqual(msg.payload.employees,
284284
[ "Employee1", "Employee2", "Employee3" ]);
285-
});
285+
}); // 283.7
286286

287287
it('283.8 enqMany and deqMany with JSON val as array type', async function() {
288288
const queue3 = await conn.getQueue (objQueueName,
@@ -294,8 +294,8 @@ describe('283. aq7.js', function() {
294294
{payload: { empName3: ["Employee #3", 103] }}
295295
];
296296

297-
await queue3.enqMany (empList);
298-
await conn.commit ();
297+
await queue3.enqMany(empList);
298+
await conn.commit();
299299

300300
const queue4 = await conn.getQueue(objQueueName,
301301
{payloadType: oracledb.DB_TYPE_JSON});
@@ -311,7 +311,7 @@ describe('283. aq7.js', function() {
311311
assert.deepStrictEqual(msgs[0].payload.empName1, ["Employee #1", 101]);
312312
assert.deepStrictEqual(msgs[1].payload.empName2, ["Employee #2", 102]);
313313
assert.deepStrictEqual(msgs[2].payload.empName3, ["Employee #3", 103]);
314-
});
314+
}); // 283.8
315315

316316
it('283.9 enqOne and deqOne JSON val as object type', async function() {
317317
const queue = await conn.getQueue(objQueueName,
@@ -331,7 +331,7 @@ describe('283. aq7.js', function() {
331331

332332
assert.deepStrictEqual(msg.payload.employee,
333333
{ "name": "Employee1", "age": 30, "city": "New City" });
334-
});
334+
}); // 283.9
335335

336336
it('283.10 enqMany and deqMany with JSON val as object type', async function() {
337337
const queue3 = await conn.getQueue (objQueueName,
@@ -366,7 +366,7 @@ describe('283. aq7.js', function() {
366366
{ "name": "Employee2", "age": 30, "city": "New York" });
367367
assert.deepStrictEqual(msgs[2].payload.empDetails3,
368368
{ "name": "Employee3", "age": 28, "city": "New Land" });
369-
});
369+
}); // 283.10
370370

371371
it('283.11 enqOne and deqOne CLOB value into a JSON key', async function() {
372372
const inFileName = './test/clobexample.txt';
@@ -391,5 +391,5 @@ describe('283. aq7.js', function() {
391391
await conn.commit();
392392

393393
assert.deepStrictEqual(msg.payload, jsonDoc);
394-
});
394+
}); // 283.11
395395
});

test/instanceof1.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,11 @@ describe('45. instanceof1.js', function() {
7373
const result = await conn.execute('select to_clob(dummy) from dual');
7474
const lob = result.rows[0][0];
7575
assert(lob instanceof oracledb.Lob);
76-
lob.destroy();
76+
await new Promise((resolve, reject) => {
77+
lob.on('error', reject);
78+
lob.on('close', resolve);
79+
lob.destroy();
80+
});
7781
await conn.close();
7882
}); // 45.4
7983

test/jsonDualityViews7.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,7 @@ describe('297. jsonDualityViews7.js', function() {
710710
let lob = await connection.createLob(oracledb.CLOB);
711711

712712
// Write the buffer to the CLOB
713-
await lob.write(JSON.stringify (arr));
713+
await lob.write(JSON.stringify(arr));
714714

715715
await connection.execute(
716716
`INSERT INTO vector

0 commit comments

Comments
 (0)