Skip to content

Commit 53838eb

Browse files
committed
Throw proper error when non-collection DBObjects call collection methods
1 parent da5150b commit 53838eb

File tree

3 files changed

+122
-16
lines changed

3 files changed

+122
-16
lines changed

doc/src/release_notes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ Common Changes
3535
#) Added error ``NJS-174`` which is thrown if payload type does not match the
3636
queue type in :ref:`Advanced Queuing <aq>`.
3737

38+
#) Fixed bug when attempting to use collection-specific methods for
39+
:ref:`database objects <dbobjectclass>` which is not actually a collection.
40+
3841
Thin Mode Changes
3942
+++++++++++++++++
4043

lib/dbObject.js

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,18 @@ function validatePropertyValue(objType, metaData, value, index) {
7979
// instantiated; a cache of these classes are maintained on each connection
8080
class BaseDbObject {
8181

82+
//---------------------------------------------------------------------------
83+
// _ensureCollection()
84+
//
85+
// Ensures that the object is a collection.
86+
//---------------------------------------------------------------------------
87+
_ensureCollection() {
88+
if (!this.isCollection) {
89+
errors.throwErr(errors.ERR_OBJECT_IS_NOT_A_COLLECTION,
90+
this.name);
91+
}
92+
}
93+
8294
//---------------------------------------------------------------------------
8395
// _getAttrValue()
8496
//
@@ -165,6 +177,7 @@ class BaseDbObject {
165177
//---------------------------------------------------------------------------
166178
append(value) {
167179
errors.assertArgCount(arguments, 1, 1);
180+
this._ensureCollection();
168181
const info = {
169182
fqn: this._objType.fqn,
170183
type: this._objType.elementType,
@@ -238,6 +251,7 @@ class BaseDbObject {
238251
//---------------------------------------------------------------------------
239252
deleteElement(index) {
240253
errors.assertArgCount(arguments, 1, 1);
254+
this._ensureCollection();
241255
errors.assertParamValue(Number.isInteger(index), 1);
242256
return this._impl.deleteElement(index);
243257
}
@@ -300,6 +314,7 @@ class BaseDbObject {
300314
//---------------------------------------------------------------------------
301315
getElement(index) {
302316
errors.assertArgCount(arguments, 1, 1);
317+
this._ensureCollection();
303318
errors.assertParamValue(Number.isInteger(index), 1);
304319
const value = this._impl.getElement(index);
305320
return this._transformValueOut(value, this.elementTypeClass, this._objType.elementTypeInfo);
@@ -312,6 +327,7 @@ class BaseDbObject {
312327
//---------------------------------------------------------------------------
313328
getKeys() {
314329
errors.assertArgCount(arguments, 0, 0);
330+
this._ensureCollection();
315331
return this._impl.getKeys();
316332
}
317333

@@ -322,6 +338,7 @@ class BaseDbObject {
322338
//---------------------------------------------------------------------------
323339
getFirstIndex() {
324340
errors.assertArgCount(arguments, 0, 0);
341+
this._ensureCollection();
325342
return this._impl.getFirstIndex();
326343
}
327344

@@ -332,6 +349,7 @@ class BaseDbObject {
332349
//---------------------------------------------------------------------------
333350
getLastIndex() {
334351
errors.assertArgCount(arguments, 0, 0);
352+
this._ensureCollection();
335353
return this._impl.getLastIndex();
336354
}
337355

@@ -342,6 +360,7 @@ class BaseDbObject {
342360
//---------------------------------------------------------------------------
343361
getNextIndex(index) {
344362
errors.assertArgCount(arguments, 1, 1);
363+
this._ensureCollection();
345364
errors.assertParamValue(Number.isInteger(index), 1);
346365
return this._impl.getNextIndex(index);
347366
}
@@ -353,6 +372,7 @@ class BaseDbObject {
353372
//---------------------------------------------------------------------------
354373
getPrevIndex(index) {
355374
errors.assertArgCount(arguments, 1, 1);
375+
this._ensureCollection();
356376
errors.assertParamValue(Number.isInteger(index), 1);
357377
return this._impl.getPrevIndex(index);
358378
}
@@ -364,6 +384,7 @@ class BaseDbObject {
364384
//---------------------------------------------------------------------------
365385
getValues() {
366386
errors.assertArgCount(arguments, 0, 0);
387+
this._ensureCollection();
367388
const values = this._impl.getValues();
368389
for (let i = 0; i < values.length; i++) {
369390
values[i] = this._transformValueOut(values[i], this.elementTypeClass, this._objType.elementTypeInfo);
@@ -378,6 +399,7 @@ class BaseDbObject {
378399
//---------------------------------------------------------------------------
379400
hasElement(index) {
380401
errors.assertArgCount(arguments, 1, 1);
402+
this._ensureCollection();
381403
errors.assertParamValue(Number.isInteger(index), 1);
382404
return this._impl.hasElement(index);
383405
}
@@ -426,6 +448,7 @@ class BaseDbObject {
426448
//---------------------------------------------------------------------------
427449
setElement(index, value) {
428450
errors.assertArgCount(arguments, 2, 2);
451+
this._ensureCollection();
429452
errors.assertParamValue(Number.isInteger(index), 1);
430453
const info = {
431454
fqn: this._objType.fqn,
@@ -445,6 +468,7 @@ class BaseDbObject {
445468
//---------------------------------------------------------------------------
446469
trim(numToTrim) {
447470
errors.assertArgCount(arguments, 1, 1);
471+
this._ensureCollection();
448472
errors.assertParamValue(Number.isInteger(numToTrim) && numToTrim >= 0, 1);
449473
this._impl.trim(numToTrim);
450474
}
@@ -487,10 +511,7 @@ class BaseDbObject {
487511
//---------------------------------------------------------------------------
488512
toMap() {
489513
errors.assertArgCount(arguments, 0, 0);
490-
if (!this.isCollection) {
491-
errors.throwErr(errors.ERR_OBJECT_IS_NOT_A_COLLECTION,
492-
this.name);
493-
}
514+
this._ensureCollection();
494515
const result = new Map();
495516
this.getKeys().forEach(element => {
496517
result.set(element, this.getElement(element));

test/dbObject1.js

Lines changed: 94 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,6 @@ describe('200. dbObject1.js', () => {
9797
const sql = `DROP TYPE ${TYPE}`;
9898
await conn.execute(sql);
9999

100-
await conn.execute(`DROP PROCEDURE nodb_getDataCursor3`);
101-
await conn.execute(`DROP PROCEDURE nodb_getDataCursor2`);
102-
await conn.execute(`DROP PROCEDURE nodb_getDataCursor1`);
103-
104100
await conn.close();
105101
}); // after()
106102

@@ -271,7 +267,89 @@ describe('200. dbObject1.js', () => {
271267
assert.strictEqual(result.rows[0].PERSON.NAME, objData.NAME);
272268
}); // 200.1.7
273269

274-
it('200.1.8 insert multiple rows using executeMany() with inferred data type', async () => {
270+
it('200.1.8 Negative - test collection methods', async () => {
271+
const objData = {
272+
ID: 208,
273+
NAME: 'Christopher Jones'
274+
};
275+
const objClass = await conn.getDbObjectClass(TYPE);
276+
const testObj = new objClass(objData);
277+
278+
assert.throws(
279+
() => {
280+
testObj.append(5);
281+
},
282+
/NJS-146:/
283+
);
284+
assert.throws(
285+
() => {
286+
testObj.deleteElement(5);
287+
},
288+
/NJS-146:/
289+
);
290+
assert.throws(
291+
() => {
292+
testObj.getElement(5);
293+
},
294+
/NJS-146:/
295+
);
296+
assert.throws(
297+
() => {
298+
testObj.getKeys();
299+
},
300+
/NJS-146:/
301+
);
302+
assert.throws(
303+
() => {
304+
testObj.getLastIndex();
305+
},
306+
/NJS-146:/
307+
);
308+
assert.throws(
309+
() => {
310+
testObj.getNextIndex(5);
311+
},
312+
/NJS-146:/
313+
);
314+
assert.throws(
315+
() => {
316+
testObj.getPrevIndex(5);
317+
},
318+
/NJS-146:/
319+
);
320+
assert.throws(
321+
() => {
322+
testObj.getValues();
323+
},
324+
/NJS-146:/
325+
);
326+
assert.throws(
327+
() => {
328+
testObj.hasElement(5);
329+
},
330+
/NJS-146:/
331+
);
332+
assert.throws(
333+
() => {
334+
testObj.setElement(5, 'a');
335+
},
336+
/NJS-146:/
337+
);
338+
assert.throws(
339+
() => {
340+
testObj.toMap();
341+
},
342+
/NJS-146:/
343+
);
344+
assert.throws(
345+
() => {
346+
testObj.trim(2);
347+
},
348+
/NJS-146:/
349+
);
350+
}); // 200.1.8
351+
352+
it('200.1.9 insert multiple rows using executeMany() with inferred data type', async () => {
275353
const objClass = await conn.getDbObjectClass(TYPE);
276354
let initialID = 208;
277355
const initialSeq = 108;
@@ -312,9 +390,9 @@ describe('200. dbObject1.js', () => {
312390
assert.strictEqual(result.rows[j][1]['ID'], objDataArray[j].ID);
313391
assert.strictEqual(result.rows[j][1].NAME, objDataArray[j].NAME);
314392
}
315-
}); // 200.1.8
393+
}); // 200.1.9
316394

317-
it('200.1.9 insert multiple rows using executeMany() with explicit data type', async () => {
395+
it('200.1.10 insert multiple rows using executeMany() with explicit data type', async () => {
318396
const objClass = await conn.getDbObjectClass(TYPE);
319397
let initialID = 3000;
320398
const initialSeq = 300;
@@ -358,9 +436,9 @@ describe('200. dbObject1.js', () => {
358436
assert.strictEqual(result.rows[j][1]['ID'], objDataArray[j].ID);
359437
assert.strictEqual(result.rows[j][1].NAME, objDataArray[j].NAME);
360438
}
361-
}); // 200.1.9
439+
}); // 200.1.10
362440

363-
it('200.1.10 call procedure with 2 OUT binds of DbObject', async function() {
441+
it('200.1.11 call procedure with 2 OUT binds of DbObject', async function() {
364442
await conn.execute(proc1);
365443
await conn.execute(proc2);
366444
await conn.execute(proc3);
@@ -381,9 +459,13 @@ describe('200. dbObject1.js', () => {
381459
resultSet = await result.outBinds.p_cur2.getRows();
382460
assert.equal(resultSet.length, 3);
383461
await result.outBinds.p_cur2.close();
384-
}); // 200.1.10;
385462

386-
it('200.1.11 insert an object with large string values', async () => {
463+
await conn.execute(`DROP PROCEDURE nodb_getDataCursor3`);
464+
await conn.execute(`DROP PROCEDURE nodb_getDataCursor2`);
465+
await conn.execute(`DROP PROCEDURE nodb_getDataCursor1`);
466+
}); // 200.1.11
467+
468+
it('200.1.12 insert an object with large string values', async () => {
387469
let sql = `INSERT INTO ${TABLE} VALUES (:1, :2)`;
388470
const maxLen = 1024;
389471
const largeString = 'A'.repeat(maxLen);
@@ -402,7 +484,7 @@ describe('200. dbObject1.js', () => {
402484

403485
assert.strictEqual(result.rows[0][0], seq);
404486
assert.strictEqual(result.rows[0][1]['ADDRESS'], objData.ADDRESS);
405-
}); // 200.1.11
487+
}); // 200.1.12
406488
});
407489

408490
describe('200.2 Number property with Precision', function() {

0 commit comments

Comments
 (0)