node-oracledb/test/dbObject9.js

284 lines
8.7 KiB
JavaScript
Raw Permalink Normal View History

2023-05-03 18:32:09 +08:00
/* Copyright (c) 2019, 2023, Oracle and/or its affiliates. */
/******************************************************************************
*
* This software is dual-licensed to you under the Universal Permissive License
* (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
* 2.0 as shown at https://www.apache.org/licenses/LICENSE-2.0. You may choose
* either license.
*
* If you elect to accept the software under the Apache License, Version 2.0,
* the following applies:
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* NAME
* 208. dbObject9.js
*
* DESCRIPTION
* REF Cursors and Implicit Results that fetch DbObjects.
*
*****************************************************************************/
'use strict';
const oracledb = require('oracledb');
2021-10-11 10:33:01 +08:00
const assert = require('assert');
2023-02-21 12:04:16 +08:00
const dbConfig = require('./dbconfig.js');
const testsUtil = require('./testsUtil.js');
describe('208. dbObject9.js', function() {
2019-11-25 10:13:17 +08:00
let isRunnable = false;
let conn;
const TYPE = 'NODB_PERSON_T';
const TABLE = 'NODB_TAB_EMPLOYEES';
const PEOPLE = [
{ ID: 123, NAME: 'Alice', GENDER: 'Female' },
{ ID: 234, NAME: 'Bob', GENDER: 'Male' },
{ ID: 345, NAME: 'Charlie', GENDER: 'Male' },
{ ID: 456, NAME: 'Dolores', GENDER: 'Female' }
];
2019-11-25 10:13:17 +08:00
before(async function() {
isRunnable = await testsUtil.checkPrerequisites();
2021-04-01 12:48:37 +08:00
if (!isRunnable) {
2019-11-25 10:13:17 +08:00
this.skip();
return;
} else {
2023-02-21 12:04:16 +08:00
conn = await oracledb.getConnection(dbConfig);
2023-02-21 11:20:36 +08:00
let sql =
`CREATE OR REPLACE TYPE ${TYPE} AS OBJECT (
id NUMBER,
name VARCHAR2(30),
gender VARCHAR2(20)
);`;
await conn.execute(sql);
sql =
`CREATE TABLE ${TABLE} (
empnum NUMBER,
person ${TYPE}
)`;
const plsql = testsUtil.sqlCreateTable(TABLE, sql);
await conn.execute(plsql);
const PersonType = await conn.getDbObjectClass(TYPE);
2023-08-17 16:11:49 +08:00
const bindArr = [];
2023-02-21 11:20:36 +08:00
for (let i = 0, num, p; i < PEOPLE.length; i++) {
num = i + 1;
p = new PersonType(PEOPLE[i]);
bindArr[i] = [num, p];
}
2023-02-21 11:20:36 +08:00
const opts = {
autoCommit: true,
bindDefs: [ { type: oracledb.NUMBER }, { type: PersonType } ]
};
const result = await conn.executeMany(
`INSERT INTO ${TABLE} VALUES (:1, :2)`,
bindArr,
opts
);
assert.strictEqual(result.rowsAffected, PEOPLE.length);
}
2019-11-25 10:13:17 +08:00
}); // before()
2019-11-25 10:13:17 +08:00
after(async function() {
2021-04-01 12:48:37 +08:00
if (!isRunnable) {
2019-11-25 10:13:17 +08:00
return;
} else {
2023-02-21 11:20:36 +08:00
let sql = `DROP TABLE ${TABLE} PURGE`;
await conn.execute(sql);
2023-02-21 11:20:36 +08:00
sql = `DROP TYPE ${TYPE}`;
await conn.execute(sql);
2023-02-21 11:20:36 +08:00
await conn.close();
}
2019-11-25 10:13:17 +08:00
}); // after()
it('208.1 REF cursors that fetch object', async () => {
2023-02-21 11:20:36 +08:00
const PROC = 'nodb_proc_getemp';
let plsql = `
CREATE OR REPLACE PROCEDURE ${PROC} (p_out OUT SYS_REFCURSOR)
AS
BEGIN
OPEN p_out FOR
SELECT * FROM ${TABLE};
END;
`;
await conn.execute(plsql);
plsql = `BEGIN ${PROC}(:out); END;`;
const opts = { out: { dir: oracledb.BIND_OUT, type: oracledb.DB_TYPE_CURSOR } };
const result = await conn.execute(plsql, opts);
// Fetch rows from ResultSet
const RS = result.outBinds.out;
const rows = await RS.getRows(PEOPLE.length);
for (let i = 0; i < PEOPLE.length; i++) {
2023-05-03 18:32:09 +08:00
assert.deepStrictEqual(rows[i][1]._toPojo(), PEOPLE[i]);
2023-02-21 11:20:36 +08:00
assert.strictEqual(JSON.stringify(rows[i][1]), JSON.stringify(PEOPLE[i]));
}
2023-02-21 11:20:36 +08:00
await RS.close();
const sql = `DROP PROCEDURE ${PROC}`;
await conn.execute(sql);
}); // 208.1
const queryImpres = `
DECLARE
c SYS_REFCURSOR;
BEGIN
OPEN c FOR
SELECT * FROM ${TABLE};
DBMS_SQL.RETURN_RESULT(C);
END;
`;
2023-06-05 20:44:13 +08:00
it('208.2 Implicit results that fetch objects', async function() {
if (dbConfig.test.isCmanTdm) this.skip();
2023-02-21 11:20:36 +08:00
const result = await conn.execute(queryImpres);
const rows = result.implicitResults[0];
for (let i = 0; i < PEOPLE.length; i++) {
2023-05-03 18:32:09 +08:00
assert.deepStrictEqual(rows[i][1]._toPojo(), PEOPLE[i]);
2023-02-21 11:20:36 +08:00
assert.strictEqual(JSON.stringify(rows[i][1]), JSON.stringify(PEOPLE[i]));
}
}); // 208.2
2023-06-05 20:44:13 +08:00
it('208.3 Implicit results that fetch objects with Result Set', async function() {
if (dbConfig.test.isCmanTdm) this.skip();
2023-02-21 11:20:36 +08:00
const result = await conn.execute(queryImpres, [], { resultSet: true});
const rows = await result.implicitResults[0].getRows(PEOPLE.length);
for (let i = 0; i < PEOPLE.length; i++) {
2023-05-03 18:32:09 +08:00
assert.deepStrictEqual(rows[i][1]._toPojo(), PEOPLE[i]);
2023-02-21 11:20:36 +08:00
assert.strictEqual(JSON.stringify(rows[i][1]), JSON.stringify(PEOPLE[i]));
}
}); // 208.3
it('208.4 DML RETURNING INTO, explicit bind type', async () => {
2023-02-21 11:20:36 +08:00
const PersonType = await conn.getDbObjectClass(TYPE);
const staff = { ID: 1123, NAME: 'Changjie', GENDER: 'Male' };
const staffNo = 23;
const p = new PersonType(staff);
const sql = `INSERT INTO ${TABLE} VALUES (:1, :2) RETURNING empnum, person INTO :3, :4`;
const bindVar = [
staffNo,
{ type: PersonType, val: p },
{ dir: oracledb.BIND_OUT, type: oracledb.DB_TYPE_NUMBER },
{ dir: oracledb.BIND_OUT, type: PersonType }
];
const result = await conn.execute(sql, bindVar);
assert.strictEqual(result.rowsAffected, 1);
assert.strictEqual(result.outBinds[0][0], staffNo);
2023-05-03 18:32:09 +08:00
assert.deepStrictEqual(
2023-02-21 11:20:36 +08:00
result.outBinds[1][0]._toPojo(),
staff
);
}); // 208.4
it('208.5 DML RETURNING INTO, implicit bind type', async () => {
2023-02-21 11:20:36 +08:00
const PersonType = await conn.getDbObjectClass(TYPE);
const staff = { ID: 23456, NAME: 'Chris', GENDER: 'Male' };
const staffNo = 101;
const p = new PersonType(staff);
const sql = `INSERT INTO ${TABLE} VALUES (:1, :2) RETURNING empnum, person INTO :3, :4`;
const bindVar = [
staffNo,
p,
{ dir: oracledb.BIND_OUT, type: oracledb.DB_TYPE_NUMBER },
{ dir: oracledb.BIND_OUT, type: PersonType }
];
const result = await conn.execute(sql, bindVar);
assert.strictEqual(result.rowsAffected, 1);
assert.strictEqual(result.outBinds[0][0], staffNo);
2023-05-03 18:32:09 +08:00
assert.deepStrictEqual(
2023-02-21 11:20:36 +08:00
result.outBinds[1][0]._toPojo(),
staff
);
}); // 208.5
it('208.6 DML RETURNING INTO, bind by named values', async () => {
2023-02-21 11:20:36 +08:00
const PersonType = await conn.getDbObjectClass(TYPE);
const staff = { ID: 789, NAME: 'Shelly', GENDER: 'Female' };
const staffNo = 102;
const p = new PersonType(staff);
const sql = `INSERT INTO ${TABLE} VALUES (:n, :i) RETURNING empnum, person INTO :o1, :o2`;
const bindVar = {
n: staffNo,
i: p,
o1: { dir: oracledb.BIND_OUT, type: oracledb.DB_TYPE_NUMBER },
o2: { dir: oracledb.BIND_OUT, type: PersonType }
};
const result = await conn.execute(sql, bindVar);
assert.strictEqual(result.rowsAffected, 1);
assert.strictEqual(result.outBinds.o1[0], staffNo);
2023-05-03 18:32:09 +08:00
assert.deepStrictEqual(
2023-02-21 11:20:36 +08:00
result.outBinds.o2[0]._toPojo(),
staff
);
}); // 208.6
it.skip('208.7 DML RETURNING INTO and executeMany()', async () => {
2023-02-21 11:20:36 +08:00
const PersonType = await conn.getDbObjectClass(TYPE);
const staffs = [
{ ID: 7001, NAME: 'Emma', GENDER: 'Female' },
{ ID: 7002, NAME: 'Ashley', GENDER: 'Female' },
{ ID: 7003, NAME: 'Alexanda', GENDER: 'Male' },
];
const staffNo = [201, 202, 203];
2023-08-17 16:11:49 +08:00
const bindArr = [];
2023-02-21 11:20:36 +08:00
for (let i = 0, num, p; i < staffs.length; i++) {
num = staffNo[i];
p = new PersonType(staffs[i]);
bindArr[i] = [num, p];
}
2023-02-21 11:20:36 +08:00
const opts = {
autoCommit: true,
bindDefs: [
{ type: oracledb.NUMBER },
{ type: PersonType },
{ dir: oracledb.BIND_OUT, type: oracledb.DB_TYPE_NUMBER },
{ dir: oracledb.BIND_OUT, type: PersonType }
]
};
const result = await conn.executeMany(
`INSERT INTO ${TABLE} VALUES (:1, :2) RETURNING empnum, person INTO :3, :4`,
bindArr,
opts
);
console.log("==== Result of RETURNING INTO ========");
for (let i = 0; i < staffs.length; i++) {
console.log(result.outBinds[i]);
}
console.log();
console.log("==== Result in table ========");
const res = await conn.execute(`SELECT * FROM ${TABLE} WHERE empnum > 200 AND empnum < 205`);
console.log(res);
}); // 208.7
2021-04-01 12:48:37 +08:00
});