node-oracledb/test/stream2.js

452 lines
16 KiB
JavaScript

/* Copyright (c) 2016, 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
* 14. stream2.js
*
* DESCRIPTION
* Testing driver query results via stream feature.
*
*****************************************************************************/
'use strict';
const oracledb = require('oracledb');
const assert = require('assert');
const dbConfig = require('./dbconfig.js');
describe('14. stream2.js', function() {
let connection = null;
let rowsAmount = 217;
before(async function() {
connection = await oracledb.getConnection(dbConfig);
let proc = "BEGIN \n" +
" DECLARE \n" +
" e_table_exists EXCEPTION; \n" +
" PRAGMA EXCEPTION_INIT(e_table_exists, -00942);\n " +
" BEGIN \n" +
" EXECUTE IMMEDIATE ('DROP TABLE nodb_stream2 PURGE'); \n" +
" EXCEPTION \n" +
" WHEN e_table_exists \n" +
" THEN NULL; \n" +
" END; \n" +
" EXECUTE IMMEDIATE (' \n" +
" CREATE TABLE nodb_stream2 ( \n" +
" employee_id NUMBER, \n" +
" employee_name VARCHAR2(20), \n" +
" employee_history CLOB \n" +
" ) \n" +
" '); \n" +
"END; ";
await connection.execute(proc);
proc = "DECLARE \n" +
" x NUMBER := 0; \n" +
" n VARCHAR2(20); \n" +
" clobData CLOB; \n" +
"BEGIN \n" +
" FOR i IN 1..217 LOOP \n" +
" x := x + 1; \n" +
" n := 'staff ' || x; \n" +
" INSERT INTO nodb_stream2 VALUES (x, n, EMPTY_CLOB()) RETURNING employee_history INTO clobData; \n" +
" DBMS_LOB.WRITE(clobData, 20, 1, '12345678901234567890'); \n" +
" END LOOP; \n" +
"end; ";
await connection.execute(proc);
}); // before
after(async function() {
await connection.execute("DROP TABLE nodb_stream2 PURGE");
await connection.close();
}); // after
it('14.1 Bind by position and return an array', async function() {
let sql = 'SELECT employee_name FROM nodb_stream2 WHERE employee_id = :1';
let stream = connection.queryStream(sql, [40]);
await new Promise((resolve, reject) => {
stream.on('data', function(data) {
assert(data);
assert.deepStrictEqual(data, ['staff 40']);
});
stream.on('end', stream.destroy);
stream.on('error', reject);
stream.on('close', resolve);
});
}); // 14.1
it('14.2 Bind by name and return an array', async function() {
let sql = 'SELECT employee_name FROM nodb_stream2 WHERE employee_id = :id';
let stream = connection.queryStream(sql, {id: 40});
await new Promise((resolve, reject) => {
stream.on('data', function(data) {
assert(data);
assert.deepStrictEqual(data, ['staff 40']);
});
stream.on('end', stream.destroy);
stream.on('error', reject);
stream.on('close', resolve);
});
}); // 14.2
it('14.3 Bind by position and return an object', async function() {
let sql = 'SELECT employee_name FROM nodb_stream2 WHERE employee_id = :1';
let stream = connection.queryStream(sql, [40], {outFormat: oracledb.OUT_FORMAT_OBJECT});
await new Promise((resolve, reject) => {
stream.on('data', function(data) {
assert(data);
assert.strictEqual(data.EMPLOYEE_NAME, 'staff 40');
});
stream.on('end', stream.destroy);
stream.on('error', reject);
stream.on('close', resolve);
});
}); // 14.3
it('14.4 Bind by name and return an object', async function() {
let sql = 'SELECT employee_name FROM nodb_stream2 WHERE employee_id = :id';
let stream = connection.queryStream(sql, {id: 40}, {outFormat: oracledb.OUT_FORMAT_OBJECT});
await new Promise((resolve, reject) => {
stream.on('data', function(data) {
assert(data);
assert.strictEqual(data.EMPLOYEE_NAME, 'staff 40');
});
stream.on('end', stream.destroy);
stream.on('error', reject);
stream.on('close', resolve);
});
}); // 14.4
it('14.5 explicitly setting resultSet option to be false takes no effect', async function() {
let sql = 'SELECT employee_name FROM nodb_stream2 WHERE employee_id = :1';
let stream = connection.queryStream(sql, [40], {resultSet: false});
await new Promise((resolve, reject) => {
stream.on('data', function(data) {
assert(data);
assert.deepStrictEqual(data, ['staff 40']);
});
stream.on('end', stream.destroy);
stream.on('error', reject);
stream.on('close', resolve);
});
}); // 14.5
it('14.6 maxRows option is ignored as expect', async function() {
let sql = 'SELECT employee_name FROM nodb_stream2 ORDER BY employee_name';
let stream = connection.queryStream(sql, [], {maxRows: 40});
let rowCount = 0;
await new Promise((resolve, reject) => {
stream.on('data', function(data) {
assert(data);
rowCount++;
});
stream.on('end', function() {
assert.strictEqual(rowCount, rowsAmount);
stream.destroy();
});
stream.on('error', reject);
stream.on('close', resolve);
});
}); // 14.6
it('14.7 Negative - queryStream() has no parameters', function() {
assert.throws(
function() {
connection.queryStream();
},
/NJS-009: invalid number of parameters/
);
}); //14.7
it('14.8 metadata event - single column', async function() {
let sql = 'SELECT employee_name FROM nodb_stream2 WHERE employee_id = :id';
let stream = connection.queryStream(sql, { id: 40 });
let metaDataRead = false;
await new Promise((resolve, reject) => {
stream.on('metadata', function(metaData) {
assert.strictEqual(metaData[0].name, 'EMPLOYEE_NAME');
metaDataRead = true;
});
stream.on('data', function(data) {
assert(data);
assert.strictEqual(metaDataRead, true);
});
stream.on('end', stream.destroy);
stream.on('error', reject);
stream.on('close', resolve);
});
}); // 14.8
it('14.9 metadata event - multiple columns', async function() {
let sql = 'SELECT employee_name, employee_history FROM nodb_stream2 WHERE employee_id = :id';
let stream = connection.queryStream(sql, { id: 40 });
let metaDataRead = false;
await new Promise((resolve, reject) => {
stream.on('metadata', function(metaData) {
assert.strictEqual(metaData[0].name, 'EMPLOYEE_NAME');
assert.strictEqual(metaData[1].name, 'EMPLOYEE_HISTORY');
metaDataRead = true;
});
stream.on('data', function(data) {
assert(data);
data[1].destroy(); // close the CLOB
assert.strictEqual(metaDataRead, true);
});
stream.on('end', stream.destroy);
stream.on('error', reject);
stream.on('close', resolve);
});
}); // 14.9
it('14.10 metadata event - all column names occurring', async function() {
let sql = 'SELECT * FROM nodb_stream2 WHERE employee_id = :id';
let stream = connection.queryStream(sql, { id: 40 });
let metaDataRead = false;
await new Promise((resolve, reject) => {
stream.on('metadata', function(metaData) {
assert.strictEqual(metaData[0].name, 'EMPLOYEE_ID');
assert.strictEqual(metaData[1].name, 'EMPLOYEE_NAME');
assert.strictEqual(metaData[2].name, 'EMPLOYEE_HISTORY');
metaDataRead = true;
});
stream.on('data', function(data) {
assert(data);
data[2].destroy(); // close the CLOB
assert.strictEqual(metaDataRead, true);
});
stream.on('end', stream.destroy);
stream.on('error', reject);
stream.on('close', resolve);
});
}); // 14.10
it('14.11 metadata event - no return rows', async function() {
let sql = 'SELECT employee_name FROM nodb_stream2 WHERE employee_id = :id';
let stream = connection.queryStream(sql, { id: 400 });
let metaDataRead = false;
await new Promise((resolve, reject) => {
stream.on('metadata', function(metaData) {
assert.strictEqual(metaData[0].name, 'EMPLOYEE_NAME');
metaDataRead = true;
});
stream.on('data', function(data) {
assert(data);
assert.strictEqual(metaDataRead, true);
});
stream.on('end', stream.destroy);
stream.on('error', reject);
stream.on('close', resolve);
});
}); // 14.11
it('14.12 metadata event - case sensitive columns', async function() {
const proc = "BEGIN \n" +
" DECLARE \n" +
" e_table_missing EXCEPTION; \n" +
" PRAGMA EXCEPTION_INIT(e_table_missing, -00942);\n " +
" BEGIN \n" +
" EXECUTE IMMEDIATE ('DROP TABLE nodb_streamcases PURGE'); \n" +
" EXCEPTION \n" +
" WHEN e_table_missing \n" +
" THEN NULL; \n" +
" END; \n" +
" EXECUTE IMMEDIATE (' \n" +
" CREATE TABLE nodb_streamcases ( \n" +
" id NUMBER, \n" +
' "nAmE" VARCHAR2(20) \n' +
" ) \n" +
" '); \n" +
" EXECUTE IMMEDIATE (' \n" +
" INSERT INTO nodb_streamcases VALUES (23, ''Changjie'') \n" +
" '); \n" +
" EXECUTE IMMEDIATE (' \n" +
" INSERT INTO nodb_streamcases VALUES (24, ''Nancy'') \n" +
" '); \n" +
" EXECUTE IMMEDIATE (' \n" +
" INSERT INTO nodb_streamcases VALUES (25, ''Chris'') \n" +
" '); \n" +
"END; ";
await connection.execute(proc);
let sql = 'SELECT "nAmE" FROM nodb_streamcases ORDER BY id';
let stream = connection.queryStream(sql);
let resultArray = new Array();
let metaDataRead = false;
await new Promise((resolve, reject) => {
stream.on('metadata', function(metaData) {
assert.strictEqual(metaData[0].name, 'nAmE');
metaDataRead = true;
});
stream.on('error', reject);
stream.on('data', function(data) {
assert(data);
resultArray.push(data);
assert.strictEqual(metaDataRead, true);
});
stream.on('end', function() {
assert.deepStrictEqual(
resultArray,
[ [ 'Changjie' ], [ 'Nancy' ], [ 'Chris' ] ]
);
stream.destroy();
});
stream.on('close', resolve);
});
await connection.execute("DROP TABLE nodb_streamcases PURGE");
}); // 14.12
it('14.13 metadata event - large number of columns', async function() {
let column_size = 10;
let columns_string = genColumns(column_size);
function genColumns(size) {
let buffer = [];
for (let i = 0; i < size; i++) {
buffer[i] = " column_" + i + " NUMBER";
}
return buffer.join();
}
let table_name = "nodb_streamstess";
let sqlSelect = "SELECT * FROM " + table_name;
let sqlDrop = "DROP TABLE " + table_name + " PURGE";
let proc = "BEGIN \n" +
" DECLARE \n" +
" e_table_missing EXCEPTION; \n" +
" PRAGMA EXCEPTION_INIT(e_table_missing, -00942);\n " +
" BEGIN \n" +
" EXECUTE IMMEDIATE ('DROP TABLE nodb_streamstess PURGE'); \n" +
" EXCEPTION \n" +
" WHEN e_table_missing \n" +
" THEN NULL; \n" +
" END; \n" +
" EXECUTE IMMEDIATE (' \n" +
" CREATE TABLE nodb_streamstess ( \n" +
columns_string +
" ) \n" +
" '); \n" +
"END; ";
await connection.execute(proc);
let stream = connection.queryStream(sqlSelect);
let metaDataRead = false;
await new Promise((resolve, reject) => {
stream.on('metadata', function(metaData) {
for (let i = 0; i < column_size; i++) {
assert.strictEqual(metaData[i].name, 'COLUMN_' + i);
}
metaDataRead = true;
});
stream.on('data', function(data) {
assert(data);
assert.strictEqual(metaDataRead, true);
});
stream.on('error', reject);
stream.on('end', stream.destroy);
stream.on('close', resolve);
});
await connection.execute(sqlDrop);
}); // 14.13
it('14.14 metadata event - single character column', async function() {
let tableName = "nodb_streamsinglechar";
let sqlCreate =
"BEGIN \n" +
" DECLARE \n" +
" e_table_missing EXCEPTION; \n" +
" PRAGMA EXCEPTION_INIT(e_table_missing, -00942); \n" +
" BEGIN \n" +
" EXECUTE IMMEDIATE ('DROP TABLE " + tableName + " PURGE'); \n" +
" EXCEPTION \n" +
" WHEN e_table_missing \n" +
" THEN NULL; \n" +
" END; \n" +
" EXECUTE IMMEDIATE (' \n" +
" CREATE TABLE " + tableName + " ( \n" +
" a VARCHAR2(20), \n" +
' b VARCHAR2(20) \n' +
" ) \n" +
" '); \n" +
"END; \n";
let sqlSelect = "SELECT * FROM " + tableName;
let sqlDrop = "DROP TABLE " + tableName + " PURGE";
await connection.execute(sqlCreate);
let stream = connection.queryStream(sqlSelect);
let metaDataRead = false;
await new Promise((resolve, reject) => {
stream.on('metadata', function(metaData) {
assert.strictEqual(metaData[0].name, 'A');
assert.strictEqual(metaData[1].name, 'B');
metaDataRead = true;
});
stream.on('error', reject);
stream.on('data', function() {
assert.strictEqual(metaDataRead, true);
});
stream.on('end', stream.destroy);
stream.on('close', resolve);
});
await connection.execute(sqlDrop);
}); // 14.14
it('14.15 metadata event - duplicate column alias', async function() {
let stream = connection.queryStream("SELECT 1 a, 'abc' a FROM dual");
let metaDataRead = false;
await new Promise((resolve, reject) => {
stream.on('metadata', function(metaData) {
assert.strictEqual(metaData[0].name, 'A');
assert.strictEqual(metaData[1].name, 'A_1');
metaDataRead = true;
});
stream.on('error', reject);
stream.on('data', function(data) {
assert(data);
assert.deepStrictEqual(data, [1, 'abc']);
assert.strictEqual(metaDataRead, true);
});
stream.on('end', stream.destroy);
stream.on('close', resolve);
});
}); // 14.15
});