node-oracledb/test/plsqlBindList.js

529 lines
16 KiB
JavaScript

/* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. */
/******************************************************************************
*
* You may not use the identified files except in compliance with the Apache
* License, Version 2.0 (the "License.")
*
* You may obtain a copy of the License at
* http://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.
*
* The node-oracledb test suite uses 'mocha', 'should' and 'async'.
* See LICENSE.md for relevant licenses.
*
* NAME
* 187. plsqlBindList.js
*
* DESCRIPTION
* Test of the behavior when user pass list or object of list to the bind
* parameter of conn.execute.
*
*****************************************************************************/
'use strict';
const oracledb = require('oracledb');
const should = require('should');
const dbconfig = require('./dbconfig.js');
const testsUtil = require('./testsUtil.js');
describe('187. plsqlBindList.js', function () {
async function bindNumberListByPosition (conn, binds) {
const callSql = "begin pkg_bind_number_list_test.TestArrays(:1, :2); end;";
try {
return await conn.execute(callSql, binds);
} catch (err) {
should.not.exist(err);
}
}
async function bindStringListByPosition (conn, binds) {
const callSql = "begin pkg_bind_string_list_test.TestArrays(:1, :2); end;";
try {
return await conn.execute(callSql, binds);
} catch (err) {
should.not.exist(err);
}
}
async function bindNumberListByName (conn, binds) {
const callSql = "begin pkg_bind_number_list_test.TestArrays( :bind_arg1 , :bind_arg2 ); end;";
try {
return await conn.execute(callSql, binds);
} catch (err) {
should.not.exist(err);
}
}
async function bindStringListByName (conn, binds) {
const callSql = "begin pkg_bind_string_list_test.TestArrays( :bind_arg1 , :bind_arg2 ); end;";
try {
return await conn.execute(callSql, binds);
} catch (err) {
should.not.exist(err);
}
}
before(async function() {
let conn;
try {
conn = await oracledb.getConnection(dbconfig);
let packageSql =
"create or replace package pkg_bind_number_list_test as \n" +
" type udt_NumberList is table of number index by binary_integer; \n" +
" procedure TestArrays ( \n" +
" a_InArray udt_NumberList, \n" +
" a_Sum out number \n" +
" ); \n" +
"end;";
await conn.execute(packageSql);
packageSql =
"create or replace package body pkg_bind_number_list_test as \n" +
" procedure TestArrays ( \n" +
" a_InArray udt_NumberList,\n" +
" a_Sum out number \n" +
" ) is \n" +
" begin \n" +
" a_Sum := 0; \n" +
" for i in 1..a_InArray.count loop \n" +
" a_Sum := a_Sum + a_InArray(i); \n" +
" end loop; \n" +
" end; \n" +
"end; \n";
await conn.execute(packageSql);
packageSql =
"create or replace package pkg_bind_string_list_test as \n" +
" type udt_StringList is table of VARCHAR2(64) index by binary_integer; \n" +
" procedure TestArrays ( \n" +
" a_InArray udt_StringList, \n" +
" a_Sum out VARCHAR2 \n" +
" ); \n" +
"end;";
await conn.execute(packageSql);
packageSql =
"create or replace package body pkg_bind_string_list_test as \n" +
" procedure TestArrays ( \n" +
" a_InArray udt_StringList,\n" +
" a_Sum out VARCHAR2 \n" +
" ) is \n" +
" begin \n" +
" a_Sum := ''; \n" +
" for i in 1..a_InArray.count loop \n" +
" a_Sum := a_Sum || a_InArray(i); \n" +
" end loop; \n" +
" end; \n" +
"end; \n";
await conn.execute(packageSql);
} catch (err) {
should.not.exist(err);
} finally {
if (conn) {
try {
await conn.close();
} catch (err) {
should.not.exist(err);
}
}
}
});
after(async function() {
let conn;
try {
conn = await oracledb.getConnection(dbconfig);
await conn.execute("drop package pkg_bind_number_list_test");
await conn.execute("drop package pkg_bind_string_list_test");
} catch (err) {
should.not.exist(err);
} finally {
if (conn) {
try {
await conn.close();
} catch (err) {
should.not.exist(err);
}
}
}
});
describe('187.1 Positive Cases', function () {
it('187.1.1 Bind Object of List by position with type specified', async function () {
let conn;
try {
conn = await oracledb.getConnection(dbconfig);
const res = await bindNumberListByPosition(conn, [
{ type: oracledb.NUMBER, val: [ 1, 2, 3, 4, 5 ] },
{ type: oracledb.NUMBER, dir: oracledb.BIND_OUT },
]);
should.strictEqual(res.outBinds[0], 15);
} catch (err) {
should.not.exist(err);
} finally {
if (conn) {
try {
await conn.close();
} catch (err) {
should.not.exist(err);
}
}
}
});
it('187.1.2 Bind Object of List by name with type specified', async function () {
let conn;
try {
conn = await oracledb.getConnection(dbconfig);
const res = await bindNumberListByName(conn, {
bind_arg1: { type: oracledb.NUMBER, val: [ 1, 2, 3, 4, 5 ] },
bind_arg2: { type: oracledb.NUMBER, dir: oracledb.BIND_OUT },
});
should.strictEqual(res.outBinds.bind_arg2, 15);
} catch (err) {
should.not.exist(err);
} finally {
if (conn) {
try {
await conn.close();
} catch (err) {
should.not.exist(err);
}
}
}
});
it('187.1.3 Bind List by position without type specified', async function () {
let conn;
try {
conn = await oracledb.getConnection(dbconfig);
const res = await bindNumberListByPosition(conn, [
[ 1, 2, 3, 4, 5 ],
{ type: oracledb.NUMBER, dir: oracledb.BIND_OUT },
]);
should.strictEqual(res.outBinds[0], 15);
} catch (err) {
should.not.exist(err);
} finally {
if (conn) {
try {
await conn.close();
} catch (err) {
should.not.exist(err);
}
}
}
});
it('187.1.4 Bind List by name without type specified', async function () {
let conn;
try {
conn = await oracledb.getConnection(dbconfig);
const res = await bindNumberListByName(conn, {
bind_arg1: [ 1, 2, 3, 4, 5 ],
bind_arg2: { type: oracledb.NUMBER, dir: oracledb.BIND_OUT },
});
should.strictEqual(res.outBinds.bind_arg2, 15);
} catch (err) {
should.not.exist(err);
} finally {
if (conn) {
try {
await conn.close();
} catch (err) {
should.not.exist(err);
}
}
}
});
it('187.1.5 Bind STRING List by name without type specified', async function () {
let conn;
try {
conn = await oracledb.getConnection(dbconfig);
const res = await bindStringListByName(conn, {
bind_arg1: [ "1", "2", "3", "4", "5" ],
bind_arg2: { type: oracledb.STRING, dir: oracledb.BIND_OUT },
});
should.strictEqual(res.outBinds.bind_arg2, "12345");
} catch (err) {
should.not.exist(err);
} finally {
if (conn) {
try {
await conn.close();
} catch (err) {
should.not.exist(err);
}
}
}
});
it('187.1.6 Bind STRING List by position without type specified', async function () {
let conn;
try {
conn = await oracledb.getConnection(dbconfig);
const res = await bindStringListByPosition(conn, [
[ "1", "2", "3", "4", "5" ],
{ type: oracledb.STRING, dir: oracledb.BIND_OUT },
]);
should.strictEqual(res.outBinds[0], "12345");
} catch (err) {
should.not.exist(err);
} finally {
if (conn) {
try {
await conn.close();
} catch (err) {
should.not.exist(err);
}
}
}
});
});
describe('187.2 Negative Cases', function () {
it('187.2.1 Bind Empty List by position with type specified', async function () {
let conn;
try {
conn = await oracledb.getConnection(dbconfig);
let res = await bindNumberListByPosition(conn, [
{ type: oracledb.NUMBER, val: [] },
{ type: oracledb.NUMBER, dir: oracledb.BIND_OUT },
]);
should.strictEqual(res.outBinds[0], 0);
} catch (err) {
should.not.exist(err);
} finally {
if (conn) {
try {
await conn.close();
} catch (err) {
should.not.exist(err);
}
}
}
});
it('187.2.2 Bind Empty List by position without type specified', async function () {
let conn;
try {
conn = await oracledb.getConnection(dbconfig);
await testsUtil.assertThrowsAsync(async () => {
await bindNumberListByPosition(conn, [
[],
{ type: oracledb.NUMBER, dir: oracledb.BIND_OUT },
]);
// PLS-00418: array bind type must match PL/SQL table row type
}, /PLS-00418:/);
} catch (err) {
should.not.exist(err);
} finally {
if (conn) {
try {
await conn.close();
} catch (err) {
should.not.exist(err);
}
}
}
});
it('187.2.3 Bind Empty List by name with type specified', async function () {
let conn;
try {
conn = await oracledb.getConnection(dbconfig);
const res = await bindNumberListByName(conn, {
bind_arg1: { type: oracledb.NUMBER, val: [] },
bind_arg2: { type: oracledb.NUMBER, dir: oracledb.BIND_OUT },
});
should.strictEqual(res.outBinds.bind_arg2, 0);
} catch (err) {
should.not.exist(err);
} finally {
if (conn) {
try {
await conn.close();
} catch (err) {
should.not.exist(err);
}
}
}
});
it('187.2.4 Bind Empty List by name without type specified', async function () {
let conn;
try {
conn = await oracledb.getConnection(dbconfig);
await testsUtil.assertThrowsAsync(async () => {
await bindNumberListByName(conn, {
bind_arg1: [],
bind_arg2: { type: oracledb.NUMBER, dir: oracledb.BIND_OUT },
});
// PLS-00418: array bind type must match PL/SQL table row type
}, /PLS-00418:/);
} catch (err) {
should.not.exist(err);
} finally {
if (conn) {
try {
await conn.close();
} catch (err) {
should.not.exist(err);
}
}
}
});
it('187.2.5 Bind NUMBER List by name with STRING as first element', async function () {
let conn;
try {
conn = await oracledb.getConnection(dbconfig);
await testsUtil.assertThrowsAsync(async () => {
await bindNumberListByName(conn, {
bind_arg1: [ "1", 2, 3, 4, 5 ],
bind_arg2: { type: oracledb.NUMBER, dir: oracledb.BIND_OUT },
});
// NJS-037: invalid data type at array index 0 for bind ":bind_arg1"
}, /NJS-037:/);
} catch (err) {
should.not.exist(err);
} finally {
if (conn) {
try {
await conn.close();
} catch (err) {
should.not.exist(err);
}
}
}
});
it('187.2.6 Bind NUMBER List by position with STRING as second element', async function () {
let conn;
try {
conn = await oracledb.getConnection(dbconfig);
await testsUtil.assertThrowsAsync(async () => {
await bindNumberListByPosition(conn, [
[ 1, "2", 3, 4, 5 ],
{ type: oracledb.NUMBER, dir: oracledb.BIND_OUT },
]);
// NJS-052: invalid data type at array index 1 for bind position 1
}, /NJS-052:/);
} catch (err) {
should.not.exist(err);
} finally {
if (conn) {
try {
await conn.close();
} catch (err) {
should.not.exist(err);
}
}
}
});
it('187.2.7 Bind STRING List by name while required type is NUMBER', async function () {
let conn;
try {
conn = await oracledb.getConnection(dbconfig);
await testsUtil.assertThrowsAsync(async () => {
await bindNumberListByName(conn, {
bind_arg1: [ "1", "2", "3", "4", "5" ],
bind_arg2: { type: oracledb.NUMBER, dir: oracledb.BIND_OUT },
});
// PLS-00418: array bind type must match PL/SQL table row type"
}, /PLS-00418:/);
} catch (err) {
should.not.exist(err);
} finally {
if (conn) {
try {
await conn.close();
} catch (err) {
should.not.exist(err);
}
}
}
});
it('187.2.8 Bind STRING List by position while required type is NUMBER', async function () {
let conn;
try {
conn = await oracledb.getConnection(dbconfig);
await testsUtil.assertThrowsAsync(async () => {
await bindNumberListByPosition(conn, [
[ "1", "2", "3", "4", "5" ],
{ type: oracledb.NUMBER, dir: oracledb.BIND_OUT },
]);
// PLS-00418: array bind type must match PL/SQL table row type"
}, /PLS-00418:/);
} catch (err) {
should.not.exist(err);
} finally {
if (conn) {
try {
await conn.close();
} catch (err) {
should.not.exist(err);
}
}
}
});
it('187.2.9 Bind NUMBER List by name while required type is STRING', async function () {
let conn;
try {
conn = await oracledb.getConnection(dbconfig);
await testsUtil.assertThrowsAsync(async () => {
await bindStringListByName(conn, {
bind_arg1: [ 1, 2, 3, 4, 5 ],
bind_arg2: { type: oracledb.NUMBER, dir: oracledb.BIND_OUT },
});
// PLS-00418: array bind type must match PL/SQL table row type"
}, /PLS-00418:/);
} catch (err) {
should.not.exist(err);
} finally {
if (conn) {
try {
await conn.close();
} catch (err) {
should.not.exist(err);
}
}
}
});
it('187.2.10 Bind NUMBER List by position while required type is STRING', async function () {
let conn;
try {
conn = await oracledb.getConnection(dbconfig);
await testsUtil.assertThrowsAsync(async () => {
await bindStringListByPosition(conn, [
[ 1, 2, 3, 4, 5 ],
{ type: oracledb.NUMBER, dir: oracledb.BIND_OUT },
]);
// PLS-00418: array bind type must match PL/SQL table row type"
}, /PLS-00418:/);
} catch (err) {
should.not.exist(err);
} finally {
if (conn) {
try {
await conn.close();
} catch (err) {
should.not.exist(err);
}
}
}
});
});
});