Update tests for new functionality
This commit is contained in:
parent
1042166e2e
commit
a8b69f0c0a
|
@ -58,20 +58,21 @@ Note: these are listed in `devDependencies` in `package.json` so `npm
|
|||
install` will install them when executed inside a node-oracledb
|
||||
package directory.
|
||||
|
||||
### 4. Edit database credentials
|
||||
### 4. Database credentials
|
||||
|
||||
The database credentials for node-oracledb test suite are defined in dbConfig.js file. You can set the credentials via environment variables or dbConfig.js file.
|
||||
Change the credentials to a user who has privileges to connect and create tables.
|
||||
|
||||
```
|
||||
vi <some-directory>/node_modules/oracledb/test/dbConfig.js
|
||||
```
|
||||
|
||||
Change the credentials to a user who has privileges to connect and create tables:
|
||||
|
||||
```javascript
|
||||
module.exports = {
|
||||
user : "hr",
|
||||
password : "welcome",
|
||||
connectString : "localhost/orcl",
|
||||
externalAuth : false
|
||||
user : process.env.NODE_ORACLEDB_USER || "hr",
|
||||
password : process.env.NODE_ORACLEDB_PASSWORD || "welcome",
|
||||
connectString : process.env.NODE_ORACLEDB_CONNECTIONSTRING || "localhost/orcl",
|
||||
externalAuth : process.env.NODE_ORACLEDB_EXTERNALAUTH ? true : false
|
||||
};
|
||||
```
|
||||
|
||||
|
@ -113,3 +114,7 @@ assigned a number. The following number ranges have been chosen:
|
|||
- 1 - 20 are reserved for basic functional tests
|
||||
- 21 - 50 are reserved for data type supporting tests
|
||||
- 51 onwards are for other tests
|
||||
|
||||
## Test List
|
||||
|
||||
See test/list.txt file for the list of existing tests.
|
||||
|
|
|
@ -31,142 +31,168 @@
|
|||
* 51 - are for other tests
|
||||
*
|
||||
*****************************************************************************/
|
||||
"use strict";
|
||||
|
||||
var oracledb = require('oracledb');
|
||||
var should = require('should');
|
||||
var async = require('async');
|
||||
var dbConfig = require('./dbConfig.js');
|
||||
|
||||
describe('7. autoCommit.js', function(){
|
||||
|
||||
describe('7. autoCommit.js', function() {
|
||||
|
||||
if(dbConfig.externalAuth){
|
||||
var credential = { externalAuth: true, connectString: dbConfig.connectString };
|
||||
} else {
|
||||
var credential = dbConfig;
|
||||
}
|
||||
}
|
||||
|
||||
var connection = false;
|
||||
var anotherConnection = false;
|
||||
var script =
|
||||
"BEGIN \
|
||||
DECLARE \
|
||||
e_table_exists EXCEPTION; \
|
||||
PRAGMA EXCEPTION_INIT(e_table_exists, -00942); \
|
||||
BEGIN \
|
||||
EXECUTE IMMEDIATE ('DROP TABLE oracledb_departments'); \
|
||||
EXCEPTION \
|
||||
WHEN e_table_exists \
|
||||
THEN NULL; \
|
||||
END; \
|
||||
EXECUTE IMMEDIATE (' \
|
||||
CREATE TABLE oracledb_departments ( \
|
||||
department_id NUMBER, \
|
||||
department_name VARCHAR2(20) \
|
||||
) \
|
||||
'); \
|
||||
END; ";
|
||||
|
||||
beforeEach(function(done){
|
||||
oracledb.outFormat = oracledb.OBJECT;
|
||||
oracledb.autoCommit = true;
|
||||
|
||||
var pool = null;
|
||||
var connection = null;
|
||||
|
||||
before('create pool, get one connection, create table', function(done) {
|
||||
var script =
|
||||
"BEGIN \
|
||||
DECLARE \
|
||||
e_table_exists EXCEPTION; \
|
||||
PRAGMA EXCEPTION_INIT(e_table_exists, -00942); \
|
||||
BEGIN \
|
||||
EXECUTE IMMEDIATE ('DROP TABLE oracledb_departments'); \
|
||||
EXCEPTION \
|
||||
WHEN e_table_exists \
|
||||
THEN NULL; \
|
||||
END; \
|
||||
EXECUTE IMMEDIATE (' \
|
||||
CREATE TABLE oracledb_departments ( \
|
||||
department_id NUMBER, \
|
||||
department_name VARCHAR2(20) \
|
||||
) \
|
||||
'); \
|
||||
END; ";
|
||||
|
||||
async.series([
|
||||
function(callback){
|
||||
oracledb.getConnection(credential, function(err, conn){
|
||||
if(err) { console.error(err.message); return; }
|
||||
connection = conn;
|
||||
callback();
|
||||
});
|
||||
},
|
||||
function(callback){
|
||||
oracledb.getConnection(credential, function(err, conn){
|
||||
if(err) { console.error(err.message); return; }
|
||||
anotherConnection = conn;
|
||||
callback();
|
||||
});
|
||||
},
|
||||
function(callback){
|
||||
connection.execute(script, function(err){
|
||||
if(err) { console.error(err.message); return; }
|
||||
connection.commit( function(err){
|
||||
if(err) { console.error(err.message); return; }
|
||||
callback();
|
||||
});
|
||||
});
|
||||
}
|
||||
], done);
|
||||
|
||||
|
||||
})
|
||||
|
||||
afterEach(function(done){
|
||||
oracledb.outFormat = oracledb.ARRAY;
|
||||
oracledb.autoCommit = false;
|
||||
|
||||
async.series([
|
||||
function(callback){
|
||||
connection.execute(
|
||||
'DROP TABLE oracledb_departments',
|
||||
function(err){
|
||||
if(err) { console.error(err.message); return; }
|
||||
function(callback) {
|
||||
oracledb.createPool(
|
||||
{
|
||||
externalAuth : credential.externalAuth,
|
||||
user : credential.user,
|
||||
password : credential.password,
|
||||
connectString : credential.connectString,
|
||||
poolMin : 3,
|
||||
poolMax : 7,
|
||||
poolIncrement : 1
|
||||
},
|
||||
function(err, connectionPool) {
|
||||
should.not.exist(err);
|
||||
pool = connectionPool;
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback){
|
||||
connection.release( function(err){
|
||||
if(err) { console.error(err.message); return; }
|
||||
function(callback) {
|
||||
pool.getConnection( function(err, conn) {
|
||||
should.not.exist(err);
|
||||
connection = conn;
|
||||
callback();
|
||||
});
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
script,
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
}
|
||||
], done);
|
||||
})
|
||||
|
||||
after('drop table, release connection, terminate pool', function(done) {
|
||||
async.series([
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"DROP TABLE oracledb_departments",
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.release( function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
});
|
||||
},
|
||||
function(callback){
|
||||
anotherConnection.release( function(err){
|
||||
if(err) { console.error(err.message); return; }
|
||||
function(callback) {
|
||||
pool.terminate(function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
], done);
|
||||
})
|
||||
|
||||
afterEach('truncate table, reset the oracledb properties', function(done) {
|
||||
oracledb.autoCommit = false; /* Restore to default value */
|
||||
|
||||
connection.execute(
|
||||
"TRUNCATE TABLE oracledb_departments",
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
done();
|
||||
}
|
||||
);
|
||||
})
|
||||
|
||||
it('7.1 auto commit takes effect for DML - insert', function(done){
|
||||
it('7.1 autoCommit takes effect when setting oracledb.autoCommit before connecting', function(done) {
|
||||
var conn1 = null;
|
||||
var conn2 = null;
|
||||
|
||||
oracledb.autoCommit = true;
|
||||
|
||||
async.series([
|
||||
function(callback){
|
||||
connection.execute(
|
||||
function(callback) {
|
||||
pool.getConnection(
|
||||
function(err, conn) {
|
||||
should.not.exist(err);
|
||||
conn1 = conn;
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
conn1.execute(
|
||||
"INSERT INTO oracledb_departments VALUES (82, 'Security')",
|
||||
function(err){
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback){
|
||||
anotherConnection.execute(
|
||||
"SELECT department_id FROM oracledb_departments WHERE department_name = 'Security'",
|
||||
function(err, result){
|
||||
function(callback) { // get another connection
|
||||
pool.getConnection(
|
||||
function(err, conn) {
|
||||
should.not.exist(err);
|
||||
conn2 = conn;
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
conn2.execute(
|
||||
"SELECT department_id FROM oracledb_departments WHERE department_name = 'Security'",
|
||||
[],
|
||||
{ outFormat: oracledb.OBJECT },
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
should.exist(result);
|
||||
// console.log(result);
|
||||
result.rows[0].DEPARTMENT_ID.should.eql(82).and.be.a.Number;
|
||||
callback();
|
||||
}
|
||||
);
|
||||
}
|
||||
], done);
|
||||
})
|
||||
|
||||
it('7.2 auto commit takes effect for DML - update', function(done){
|
||||
async.series([
|
||||
function(callback){
|
||||
connection.execute(
|
||||
"INSERT INTO oracledb_departments VALUES (82, 'Security')",
|
||||
function(err){
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback){
|
||||
connection.execute(
|
||||
function(callback) {
|
||||
conn1.execute(
|
||||
"UPDATE oracledb_departments SET department_id = 101 WHERE department_name = 'Security'",
|
||||
function(err){
|
||||
should.not.exist(err);
|
||||
|
@ -174,18 +200,206 @@ describe('7. autoCommit.js', function(){
|
|||
}
|
||||
);
|
||||
},
|
||||
function(callback){
|
||||
anotherConnection.execute(
|
||||
function(callback) {
|
||||
conn2.execute(
|
||||
"SELECT department_id FROM oracledb_departments WHERE department_name = 'Security'",
|
||||
function(err, result){
|
||||
[],
|
||||
{ outFormat: oracledb.OBJECT },
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
should.exist(result);
|
||||
// console.log(result);
|
||||
result.rows[0].DEPARTMENT_ID.should.eql(101).and.be.a.Number;
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
conn1.release(function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
});
|
||||
},
|
||||
function(callback) {
|
||||
conn2.release(function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
], done);
|
||||
})
|
||||
|
||||
it('7.2 autoCommit takes effect when setting oracledb.autoCommit after connecting', function(done) {
|
||||
var conn1 = null;
|
||||
var conn2 = null;
|
||||
|
||||
async.series([
|
||||
function(callback) {
|
||||
pool.getConnection(
|
||||
function(err, conn) {
|
||||
should.not.exist(err);
|
||||
conn1 = conn;
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
oracledb.autoCommit = true; // change autoCommit after connection
|
||||
conn1.execute(
|
||||
"INSERT INTO oracledb_departments VALUES (82, 'Security')",
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
pool.getConnection(
|
||||
function(err, conn) {
|
||||
should.not.exist(err);
|
||||
conn2 = conn;
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
conn2.execute(
|
||||
"SELECT department_id FROM oracledb_departments WHERE department_name = 'Security'",
|
||||
[],
|
||||
{ outFormat: oracledb.OBJECT },
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
result.rows[0].DEPARTMENT_ID.should.eql(82).and.be.a.Number;
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
conn1.execute(
|
||||
"UPDATE oracledb_departments SET department_id = 101 WHERE department_name = 'Security'",
|
||||
function(err){
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
conn2.execute(
|
||||
"SELECT department_id FROM oracledb_departments WHERE department_name = 'Security'",
|
||||
[],
|
||||
{ outFormat: oracledb.OBJECT },
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
result.rows[0].DEPARTMENT_ID.should.eql(101).and.be.a.Number;
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
conn1.release(function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
});
|
||||
},
|
||||
function(callback) {
|
||||
conn2.release(function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
], done);
|
||||
})
|
||||
|
||||
it('7.3 autoCommit setting does not affect previous SQL result', function(done) {
|
||||
var conn1 = null;
|
||||
var conn2 = null;
|
||||
|
||||
async.series([
|
||||
function(callback) {
|
||||
pool.getConnection(
|
||||
function(err, conn) {
|
||||
should.not.exist(err);
|
||||
conn1 = conn;
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
conn1.execute(
|
||||
"INSERT INTO oracledb_departments VALUES (82, 'Security')",
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
pool.getConnection(
|
||||
function(err, conn) {
|
||||
should.not.exist(err);
|
||||
conn2 = conn;
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
oracledb.autoCommit = true; // change autoCommit after connection
|
||||
conn2.execute(
|
||||
"SELECT department_id FROM oracledb_departments WHERE department_name = 'Security'",
|
||||
[],
|
||||
{ outFormat: oracledb.OBJECT },
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
(result.rows).should.eql([]);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
conn2.execute(
|
||||
"INSERT INTO oracledb_departments VALUES (99, 'Marketing')",
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
conn2.execute(
|
||||
"SELECT COUNT(*) as amount FROM oracledb_departments",
|
||||
[],
|
||||
{ outFormat: oracledb.OBJECT },
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
result.rows[0].AMOUNT.should.eql(1);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
conn1.execute(
|
||||
"SELECT COUNT(*) as amount FROM oracledb_departments",
|
||||
[],
|
||||
{ outFormat: oracledb.OBJECT },
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
result.rows[0].AMOUNT.should.eql(2); // autoCommit for SELECT
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
conn1.release(function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
});
|
||||
},
|
||||
function(callback) {
|
||||
conn2.release(function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
], done);
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
|
|
948
test/binding.js
948
test/binding.js
|
@ -47,318 +47,644 @@ describe('4. binding.js', function() {
|
|||
var credential = dbConfig;
|
||||
}
|
||||
|
||||
var connection = false;
|
||||
beforeEach(function(done) {
|
||||
oracledb.getConnection(credential, function(err, conn) {
|
||||
if(err) { console.error(err.message); return; }
|
||||
connection = conn;
|
||||
done();
|
||||
});
|
||||
})
|
||||
describe('4.1 test STRING, NUMBER, ARRAY & JSON format', function() {
|
||||
var connection = null;
|
||||
before(function(done) {
|
||||
oracledb.getConnection(credential, function(err, conn) {
|
||||
if(err) { console.error(err.message); return; }
|
||||
connection = conn;
|
||||
done();
|
||||
});
|
||||
})
|
||||
|
||||
afterEach(function(done) {
|
||||
connection.release( function(err) {
|
||||
if(err) { console.error(err.message); return; }
|
||||
done();
|
||||
});
|
||||
})
|
||||
|
||||
|
||||
it('4.1 VARCHAR2 binding, Object & Array formats', function(done) {
|
||||
async.series([
|
||||
function(callback) {
|
||||
var proc = "CREATE OR REPLACE PROCEDURE oracledb_testproc (p_out OUT VARCHAR2) \
|
||||
AS \
|
||||
BEGIN \
|
||||
p_out := 'abcdef'; \
|
||||
END;";
|
||||
connection.should.be.ok;
|
||||
connection.execute(
|
||||
proc,
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"BEGIN oracledb_testproc(:o); END;",
|
||||
{
|
||||
o: { type: oracledb.STRING, dir: oracledb.BIND_OUT }
|
||||
},
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
// console.log(result);
|
||||
result.outBinds.o.should.be.exactly('abcdef');
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"BEGIN oracledb_testproc(:o); END;",
|
||||
[
|
||||
{ type: oracledb.STRING, dir: oracledb.BIND_OUT }
|
||||
],
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
// console.log(result);
|
||||
result.outBinds.should.be.eql(['abcdef']);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"DROP PROCEDURE oracledb_testproc",
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
}
|
||||
], done);
|
||||
})
|
||||
|
||||
it('4.2 NUMBER binding, Object & Array formats', function(done) {
|
||||
async.series([
|
||||
function(callback) {
|
||||
var proc = "CREATE OR REPLACE PROCEDURE oracledb_testproc (p_out OUT NUMBER) \
|
||||
AS \
|
||||
BEGIN \
|
||||
p_out := 10010; \
|
||||
END;";
|
||||
connection.should.be.ok;
|
||||
connection.execute(
|
||||
proc,
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"BEGIN oracledb_testproc(:o); END;",
|
||||
{
|
||||
o: { type: oracledb.NUMBER, dir: oracledb.BIND_OUT }
|
||||
},
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
// console.log(result);
|
||||
result.outBinds.o.should.be.exactly(10010);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"BEGIN oracledb_testproc(:o); END;",
|
||||
[
|
||||
{ type: oracledb.NUMBER, dir: oracledb.BIND_OUT }
|
||||
],
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
// console.log(result);
|
||||
result.outBinds.should.be.eql([ 10010 ]);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"DROP PROCEDURE oracledb_testproc",
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
}
|
||||
], done);
|
||||
})
|
||||
|
||||
it('4.3 Multiple binding values, Object & Array formats', function(done) {
|
||||
async.series([
|
||||
function(callback) {
|
||||
var proc = "CREATE OR REPLACE PROCEDURE oracledb_testproc (p_in IN VARCHAR2, p_inout IN OUT VARCHAR2, p_out OUT NUMBER) \
|
||||
after(function(done) {
|
||||
connection.release( function(err) {
|
||||
if(err) { console.error(err.message); return; }
|
||||
done();
|
||||
});
|
||||
})
|
||||
|
||||
it('4.1.1 VARCHAR2 binding, Object & Array formats', function(done) {
|
||||
async.series([
|
||||
function(callback) {
|
||||
var proc = "CREATE OR REPLACE PROCEDURE oracledb_testproc (p_out OUT VARCHAR2) \
|
||||
AS \
|
||||
BEGIN \
|
||||
p_inout := p_in || ' ' || p_inout; \
|
||||
p_out := 101; \
|
||||
END; ";
|
||||
connection.should.be.ok;
|
||||
connection.execute(
|
||||
proc,
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"BEGIN oracledb_testproc(:i, :io, :o); END;",
|
||||
{
|
||||
i: 'Alan', // bind type is determined from the data type
|
||||
io: { val: 'Turing', dir : oracledb.BIND_INOUT },
|
||||
o: { type: oracledb.NUMBER, dir : oracledb.BIND_OUT }
|
||||
},
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
// console.log(result);
|
||||
result.outBinds.io.should.be.exactly('Alan Turing');
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"BEGIN oracledb_testproc(:i, :io, :o); END;",
|
||||
[
|
||||
'Alan', // bind type is determined from the data type
|
||||
{ val: 'Turing', dir : oracledb.BIND_INOUT },
|
||||
{ type: oracledb.NUMBER, dir : oracledb.BIND_OUT }
|
||||
],
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
// console.log(result);
|
||||
result.outBinds.should.be.eql([ 'Alan Turing', 101 ]);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"DROP PROCEDURE oracledb_testproc",
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
}
|
||||
], done);
|
||||
})
|
||||
|
||||
it('4.4 Multiple binding values, Change binding order', function(done) {
|
||||
async.series([
|
||||
function(callback) {
|
||||
var proc = "CREATE OR REPLACE PROCEDURE oracledb_testproc (p_inout IN OUT VARCHAR2, p_out OUT NUMBER, p_in IN VARCHAR2) \
|
||||
AS \
|
||||
BEGIN \
|
||||
p_inout := p_in || ' ' || p_inout; \
|
||||
p_out := 101; \
|
||||
END; ";
|
||||
connection.should.be.ok;
|
||||
connection.execute(
|
||||
proc,
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"BEGIN oracledb_testproc(:io, :o, :i); END;",
|
||||
{
|
||||
i: 'Alan', // bind type is determined from the data type
|
||||
io: { val: 'Turing', dir : oracledb.BIND_INOUT },
|
||||
o: { type: oracledb.NUMBER, dir : oracledb.BIND_OUT }
|
||||
},
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
// console.log(result);
|
||||
result.outBinds.io.should.be.exactly('Alan Turing');
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"BEGIN oracledb_testproc(:io, :o, :i); END;",
|
||||
[
|
||||
{ val: 'Turing', dir : oracledb.BIND_INOUT },
|
||||
{ type: oracledb.NUMBER, dir : oracledb.BIND_OUT },
|
||||
'Alan', // bind type is determined from the data type
|
||||
],
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
// console.log(result);
|
||||
result.outBinds.should.be.eql([ 'Alan Turing', 101 ]);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"DROP PROCEDURE oracledb_testproc",
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
}
|
||||
], done);
|
||||
})
|
||||
|
||||
it('4.5 outBind & maxSize restriction', function(done) {
|
||||
async.series([
|
||||
function(callback) {
|
||||
var proc = "CREATE OR REPLACE PROCEDURE oracledb_testproc (p_out OUT VARCHAR2) \
|
||||
AS \
|
||||
BEGIN \
|
||||
p_out := 'ABCDEF GHIJK LMNOP QRSTU'; \
|
||||
END;";
|
||||
connection.should.be.ok;
|
||||
connection.execute(
|
||||
proc,
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"BEGIN oracledb_testproc(:o); END;",
|
||||
{
|
||||
o: { type: oracledb.STRING, dir: oracledb.BIND_OUT, maxSize:2 }
|
||||
},
|
||||
function(err, result) {
|
||||
should.exist(err);
|
||||
// console.log(err.message);
|
||||
err.message.should.startWith('ORA-06502:');
|
||||
// console.log(result);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"BEGIN oracledb_testproc(:o); END;",
|
||||
[
|
||||
{ type: oracledb.STRING, dir: oracledb.BIND_OUT, maxSize:3 }
|
||||
],
|
||||
function(err, result) {
|
||||
should.exist(err);
|
||||
// console.log(err.message);
|
||||
err.message.should.startWith('ORA-06502:');
|
||||
// console.log(result);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"DROP PROCEDURE oracledb_testproc",
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
}
|
||||
], done);
|
||||
})
|
||||
BEGIN \
|
||||
p_out := 'abcdef'; \
|
||||
END;";
|
||||
connection.should.be.ok;
|
||||
connection.execute(
|
||||
proc,
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"BEGIN oracledb_testproc(:o); END;",
|
||||
{
|
||||
o: { type: oracledb.STRING, dir: oracledb.BIND_OUT }
|
||||
},
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
// console.log(result);
|
||||
result.outBinds.o.should.be.exactly('abcdef');
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"BEGIN oracledb_testproc(:o); END;",
|
||||
[
|
||||
{ type: oracledb.STRING, dir: oracledb.BIND_OUT }
|
||||
],
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
// console.log(result);
|
||||
result.outBinds.should.be.eql(['abcdef']);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"DROP PROCEDURE oracledb_testproc",
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
}
|
||||
], done);
|
||||
})
|
||||
|
||||
it('4.1.2 NUMBER binding, Object & Array formats', function(done) {
|
||||
async.series([
|
||||
function(callback) {
|
||||
var proc = "CREATE OR REPLACE PROCEDURE oracledb_testproc (p_out OUT NUMBER) \
|
||||
AS \
|
||||
BEGIN \
|
||||
p_out := 10010; \
|
||||
END;";
|
||||
connection.should.be.ok;
|
||||
connection.execute(
|
||||
proc,
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"BEGIN oracledb_testproc(:o); END;",
|
||||
{
|
||||
o: { type: oracledb.NUMBER, dir: oracledb.BIND_OUT }
|
||||
},
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
// console.log(result);
|
||||
result.outBinds.o.should.be.exactly(10010);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"BEGIN oracledb_testproc(:o); END;",
|
||||
[
|
||||
{ type: oracledb.NUMBER, dir: oracledb.BIND_OUT }
|
||||
],
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
// console.log(result);
|
||||
result.outBinds.should.be.eql([ 10010 ]);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"DROP PROCEDURE oracledb_testproc",
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
}
|
||||
], done);
|
||||
})
|
||||
|
||||
it('4.1.3 Multiple binding values, Object & Array formats', function(done) {
|
||||
async.series([
|
||||
function(callback) {
|
||||
var proc = "CREATE OR REPLACE PROCEDURE oracledb_testproc (p_in IN VARCHAR2, p_inout IN OUT VARCHAR2, p_out OUT NUMBER) \
|
||||
AS \
|
||||
BEGIN \
|
||||
p_inout := p_in || ' ' || p_inout; \
|
||||
p_out := 101; \
|
||||
END; ";
|
||||
connection.should.be.ok;
|
||||
connection.execute(
|
||||
proc,
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"BEGIN oracledb_testproc(:i, :io, :o); END;",
|
||||
{
|
||||
i: 'Alan', // bind type is determined from the data type
|
||||
io: { val: 'Turing', dir : oracledb.BIND_INOUT },
|
||||
o: { type: oracledb.NUMBER, dir : oracledb.BIND_OUT }
|
||||
},
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
// console.log(result);
|
||||
result.outBinds.io.should.be.exactly('Alan Turing');
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"BEGIN oracledb_testproc(:i, :io, :o); END;",
|
||||
[
|
||||
'Alan', // bind type is determined from the data type
|
||||
{ val: 'Turing', dir : oracledb.BIND_INOUT },
|
||||
{ type: oracledb.NUMBER, dir : oracledb.BIND_OUT }
|
||||
],
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
// console.log(result);
|
||||
result.outBinds.should.be.eql([ 'Alan Turing', 101 ]);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"DROP PROCEDURE oracledb_testproc",
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
}
|
||||
], done);
|
||||
})
|
||||
|
||||
it('4.1.4 Multiple binding values, Change binding order', function(done) {
|
||||
async.series([
|
||||
function(callback) {
|
||||
var proc = "CREATE OR REPLACE PROCEDURE oracledb_testproc (p_inout IN OUT VARCHAR2, p_out OUT NUMBER, p_in IN VARCHAR2) \
|
||||
AS \
|
||||
BEGIN \
|
||||
p_inout := p_in || ' ' || p_inout; \
|
||||
p_out := 101; \
|
||||
END; ";
|
||||
connection.should.be.ok;
|
||||
connection.execute(
|
||||
proc,
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"BEGIN oracledb_testproc(:io, :o, :i); END;",
|
||||
{
|
||||
i: 'Alan', // bind type is determined from the data type
|
||||
io: { val: 'Turing', dir : oracledb.BIND_INOUT },
|
||||
o: { type: oracledb.NUMBER, dir : oracledb.BIND_OUT }
|
||||
},
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
// console.log(result);
|
||||
result.outBinds.io.should.be.exactly('Alan Turing');
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"BEGIN oracledb_testproc(:io, :o, :i); END;",
|
||||
[
|
||||
{ val: 'Turing', dir : oracledb.BIND_INOUT },
|
||||
{ type: oracledb.NUMBER, dir : oracledb.BIND_OUT },
|
||||
'Alan', // bind type is determined from the data type
|
||||
],
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
// console.log(result);
|
||||
result.outBinds.should.be.eql([ 'Alan Turing', 101 ]);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"DROP PROCEDURE oracledb_testproc",
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
}
|
||||
], done);
|
||||
})
|
||||
|
||||
it('4.1.5 default bind type - STRING', function(done) {
|
||||
connection.should.be.ok;
|
||||
var sql = "begin :n := 1001; end;";
|
||||
var bindVar = { n : { dir: oracledb.BIND_OUT } };
|
||||
var options = { };
|
||||
|
||||
connection.execute(
|
||||
sql,
|
||||
bindVar,
|
||||
options,
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
// console.log(result);
|
||||
result.outBinds.n.should.be.a.String;
|
||||
result.outBinds.n.should.eql('1001');
|
||||
done();
|
||||
}
|
||||
);
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe('4.2 mixing named with positional binding', function() {
|
||||
var connection = null;
|
||||
var createTable =
|
||||
"BEGIN \
|
||||
DECLARE \
|
||||
e_table_exists EXCEPTION; \
|
||||
PRAGMA EXCEPTION_INIT(e_table_exists, -00942); \
|
||||
BEGIN \
|
||||
EXECUTE IMMEDIATE ('DROP TABLE oracledb_binding'); \
|
||||
EXCEPTION \
|
||||
WHEN e_table_exists \
|
||||
THEN NULL; \
|
||||
END; \
|
||||
EXECUTE IMMEDIATE (' \
|
||||
CREATE TABLE oracledb_binding ( \
|
||||
id NUMBER(4), \
|
||||
name VARCHAR2(32) \
|
||||
) \
|
||||
'); \
|
||||
END; ";
|
||||
var insert = 'insert into oracledb_binding (id, name) values (:0, :1) returning id into :2';
|
||||
var param1 = [ 1, 'changjie', { type: oracledb.NUMBER, dir: oracledb.BIND_OUT } ];
|
||||
var param2 = [ 2, 'changjie', { ignored_name: { type: oracledb.NUMBER, dir: oracledb.BIND_OUT } } ];
|
||||
var options = { autoCommit: true, outFormat: oracledb.OBJECT };
|
||||
|
||||
beforeEach(function(done) {
|
||||
oracledb.getConnection(credential, function(err, conn) {
|
||||
should.not.exist(err);
|
||||
connection = conn;
|
||||
conn.execute(
|
||||
createTable,
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
})
|
||||
|
||||
afterEach(function(done) {
|
||||
connection.should.be.ok;
|
||||
connection.execute(
|
||||
"DROP TABLE oracledb_binding",
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
connection.release(function(err) {
|
||||
should.not.exist(err);
|
||||
done();
|
||||
});
|
||||
}
|
||||
);
|
||||
})
|
||||
|
||||
it('4.2.1 array binding is ok', function(done) {
|
||||
connection.execute(
|
||||
insert,
|
||||
param1,
|
||||
options,
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
result.rowsAffected.should.be.exactly(1);
|
||||
result.outBinds[0].should.eql([1]);
|
||||
// console.log(result);
|
||||
connection.execute(
|
||||
"SELECT * FROM oracledb_binding",
|
||||
[],
|
||||
options,
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
//console.log(result);
|
||||
result.rows[0].ID.should.be.exactly(1);
|
||||
result.rows[0].NAME.should.eql('changjie');
|
||||
done();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
})
|
||||
|
||||
it.skip('4.2.2 array binding with mixing JSON should throw an error', function(done) {
|
||||
connection.execute(
|
||||
insert,
|
||||
param2,
|
||||
options,
|
||||
function(err, result) {
|
||||
should.exist(err); // pending to fix
|
||||
result.rowsAffected.should.be.exactly(1);
|
||||
//result.outBinds[0].should.eql([1]);
|
||||
//console.log(result);
|
||||
connection.execute(
|
||||
"SELECT * FROM oracledb_binding",
|
||||
[],
|
||||
options,
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
//console.log(result);
|
||||
result.rows[0].ID.should.be.exactly(2);
|
||||
result.rows[0].NAME.should.eql('changjie');
|
||||
done();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe('4.3 insert with DATE column and DML returning', function(done) {
|
||||
var connection = null;
|
||||
var createTable =
|
||||
"BEGIN \
|
||||
DECLARE \
|
||||
e_table_exists EXCEPTION; \
|
||||
PRAGMA EXCEPTION_INIT(e_table_exists, -00942); \
|
||||
BEGIN \
|
||||
EXECUTE IMMEDIATE ('DROP TABLE oracledb_binding'); \
|
||||
EXCEPTION \
|
||||
WHEN e_table_exists \
|
||||
THEN NULL; \
|
||||
END; \
|
||||
EXECUTE IMMEDIATE (' \
|
||||
CREATE TABLE oracledb_binding ( \
|
||||
num NUMBER(4), \
|
||||
str VARCHAR2(32), \
|
||||
dt DATE \
|
||||
) \
|
||||
'); \
|
||||
END; ";
|
||||
|
||||
beforeEach(function(done) {
|
||||
oracledb.getConnection(credential, function(err, conn) {
|
||||
should.not.exist(err);
|
||||
connection = conn;
|
||||
conn.execute(
|
||||
createTable,
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
})
|
||||
|
||||
afterEach(function(done) {
|
||||
connection.should.be.ok;
|
||||
connection.execute(
|
||||
"DROP TABLE oracledb_binding",
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
connection.release(function(err) {
|
||||
should.not.exist(err);
|
||||
done();
|
||||
});
|
||||
}
|
||||
);
|
||||
})
|
||||
|
||||
var insert1 = 'insert into oracledb_binding (num, str, dt) values (:0, :1, :2)';
|
||||
var insert2 = 'insert into oracledb_binding (num, str, dt) values (:0, :1, :2) returning num into :3';
|
||||
var param1 = { 0: 123, 1: 'str', 2: new Date() };
|
||||
var param2 = { 0: 123, 1: 'str', 2: new Date(), 3: { type: oracledb.NUMBER, dir: oracledb.BIND_OUT } };
|
||||
var param3 = [ 123, 'str', new Date() ];
|
||||
var param4 = [ 123, 'str', new Date(), { type: oracledb.NUMBER, dir: oracledb.BIND_OUT } ];
|
||||
|
||||
var options = { autoCommit: true };
|
||||
|
||||
it('4.3.1 passes in object syntax without returning into', function(done) {
|
||||
connection.execute(
|
||||
insert1,
|
||||
param1,
|
||||
options,
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
result.rowsAffected.should.be.exactly(1);
|
||||
connection.execute(
|
||||
"SELECT * FROM oracledb_binding",
|
||||
[],
|
||||
options,
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
// console.log(result);
|
||||
done();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
})
|
||||
|
||||
it('4.3.2 passes in object syntax with returning into', function(done) {
|
||||
connection.execute(
|
||||
insert2,
|
||||
param2,
|
||||
options,
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
result.rowsAffected.should.be.exactly(1);
|
||||
//console.log(result);
|
||||
result.outBinds.should.eql({ '3': [123] });
|
||||
connection.execute(
|
||||
"SELECT * FROM oracledb_binding",
|
||||
[],
|
||||
options,
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
// console.log(result);
|
||||
done();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
})
|
||||
|
||||
it('4.3.3 passes in array syntax without returning into', function(done) {
|
||||
connection.execute(
|
||||
insert1,
|
||||
param3,
|
||||
options,
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
result.rowsAffected.should.be.exactly(1);
|
||||
// console.log(result);
|
||||
connection.execute(
|
||||
"SELECT * FROM oracledb_binding",
|
||||
[],
|
||||
options,
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
// console.log(result);
|
||||
done();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
})
|
||||
|
||||
it ('4.3.4 should pass but fail in array syntax with returning into', function(done) {
|
||||
connection.execute(
|
||||
insert2,
|
||||
param4,
|
||||
options,
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
result.rowsAffected.should.be.exactly(1);
|
||||
// console.log(result);
|
||||
result.outBinds[0].should.eql([123]);
|
||||
connection.execute(
|
||||
"SELECT * FROM oracledb_binding",
|
||||
[],
|
||||
options,
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
// console.log(result);
|
||||
done();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe('4.4 test maxSize option', function() {
|
||||
var connection = null;
|
||||
|
||||
before(function(done) {
|
||||
oracledb.getConnection(credential, function(err, conn) {
|
||||
if(err) { console.error(err.message); return; }
|
||||
connection = conn;
|
||||
done();
|
||||
});
|
||||
})
|
||||
|
||||
after(function(done) {
|
||||
connection.release( function(err) {
|
||||
if(err) { console.error(err.message); return; }
|
||||
done();
|
||||
});
|
||||
})
|
||||
|
||||
it('4.4.1 outBind & maxSize restriction', function(done) {
|
||||
async.series([
|
||||
function(callback) {
|
||||
var proc = "CREATE OR REPLACE PROCEDURE oracledb_testproc (p_out OUT VARCHAR2) \
|
||||
AS \
|
||||
BEGIN \
|
||||
p_out := 'ABCDEF GHIJK LMNOP QRSTU'; \
|
||||
END;";
|
||||
connection.should.be.ok;
|
||||
connection.execute(
|
||||
proc,
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"BEGIN oracledb_testproc(:o); END;",
|
||||
{
|
||||
o: { type: oracledb.STRING, dir: oracledb.BIND_OUT, maxSize:2 }
|
||||
},
|
||||
function(err, result) {
|
||||
should.exist(err);
|
||||
// console.log(err.message);
|
||||
err.message.should.startWith('ORA-06502:'); // ORA-06502: PL/SQL: numeric or value error: character string buffer too small
|
||||
// console.log(result);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"BEGIN oracledb_testproc(:o); END;",
|
||||
[
|
||||
{ type: oracledb.STRING, dir: oracledb.BIND_OUT, maxSize:22 }
|
||||
],
|
||||
function(err, result) {
|
||||
should.exist(err);
|
||||
// console.log(err.message);
|
||||
err.message.should.startWith('ORA-06502:');
|
||||
// console.log(result);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"DROP PROCEDURE oracledb_testproc",
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
}
|
||||
], done);
|
||||
})
|
||||
|
||||
it.skip('4.4.2 default value is 200', function(done) {
|
||||
connection.execute(
|
||||
"BEGIN :o := lpad('A',201,'x'); END;",
|
||||
{ o: { type: oracledb.STRING, dir : oracledb.BIND_OUT } },
|
||||
function (err, result) {
|
||||
should.exist(err);
|
||||
err.message.should.startWith('ORA-06502:');
|
||||
console.log(result.outBinds.o.length);
|
||||
done();
|
||||
}
|
||||
);
|
||||
})
|
||||
|
||||
it.skip('4.4.3 maximum value is 32767', function(done) {
|
||||
connection.execute(
|
||||
"BEGIN :o := lpad('A',32767,'x'); END;",
|
||||
{ o: { type: oracledb.STRING, dir : oracledb.BIND_OUT, maxSize:50000 } },
|
||||
function(err, result) {
|
||||
should.exist(err);
|
||||
console.log(result.outBinds.o.length);
|
||||
done();
|
||||
}
|
||||
);
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
This is example text used for node-oracledb CLOB examples.
|
||||
|
||||
The Oracle Database Node.js driver powers high performance Node.js applications.
|
||||
|
||||
The node-oracledb home page is at http://www.oracle.com/technetwork/database/database-technologies/node_js/index.html
|
|
@ -258,7 +258,7 @@ describe('9. columnMetadata.js', function(){
|
|||
], done);
|
||||
})
|
||||
|
||||
it('9.8 only works for SELECT statament, does not work for INSERT', function(done){
|
||||
it('9.8 only works for SELECT statement, does not work for INSERT', function(done){
|
||||
connection.should.be.ok;
|
||||
connection.execute(
|
||||
"INSERT INTO oracledb_departments VALUES (99, 'FACILITY', 456, 1700)",
|
||||
|
|
|
@ -141,7 +141,7 @@ describe('1. connection.js', function(){
|
|||
);
|
||||
})
|
||||
|
||||
it('1.1.4 Negatve test - invalid outFormat value', function(done){
|
||||
it('1.1.4 Negative test - invalid outFormat value', function(done){
|
||||
connection.should.be.ok;
|
||||
connection.execute(
|
||||
query, {id: 20}, {outFormat:0 },
|
||||
|
@ -186,6 +186,7 @@ describe('1. connection.js', function(){
|
|||
INSERT INTO oracledb_employees VALUES (x, n); \
|
||||
END LOOP; \
|
||||
END; ";
|
||||
var rowsAmount = 107;
|
||||
|
||||
before(function(done){
|
||||
oracledb.getConnection(credential, function(err, conn) {
|
||||
|
@ -274,6 +275,19 @@ describe('1. connection.js', function(){
|
|||
}
|
||||
);
|
||||
})
|
||||
|
||||
it('1.2.5 sets maxRows to be very large value', function(done) {
|
||||
connection.execute(
|
||||
"SELECT * FROM oracledb_employees",
|
||||
{},
|
||||
{maxRows: 500000},
|
||||
function(err, result){
|
||||
should.not.exist(err);
|
||||
(result.rows.length).should.eql(rowsAmount);
|
||||
done();
|
||||
}
|
||||
);
|
||||
})
|
||||
})
|
||||
|
||||
describe('1.3 can call PL/SQL procedures', function(){
|
||||
|
@ -309,7 +323,7 @@ describe('1. connection.js', function(){
|
|||
);
|
||||
})
|
||||
|
||||
it('bind parameters in various ways', function(done){
|
||||
it('1.3.1 bind parameters in various ways', function(done){
|
||||
var bindValues = {
|
||||
i: 'Alan', // default is type STRING and direction Infinity
|
||||
io: { val: 'Turing', type: oracledb.STRING, dir: oracledb.BIND_INOUT },
|
||||
|
@ -329,9 +343,7 @@ describe('1. connection.js', function(){
|
|||
})
|
||||
})
|
||||
|
||||
describe('1.4 stmtCacheSize = 0, which disable statement caching', function() {
|
||||
var connection = false;
|
||||
|
||||
describe('1.4 statementCacheSize controls statement caching', function() {
|
||||
var makeTable =
|
||||
"BEGIN \
|
||||
DECLARE \
|
||||
|
@ -364,12 +376,12 @@ describe('1. connection.js', function(){
|
|||
VALUES \
|
||||
(2001, ''Karen Morton'') \
|
||||
'); \
|
||||
END; ";
|
||||
END; ";
|
||||
|
||||
var connection = false;
|
||||
var defaultStmtCache = oracledb.stmtCacheSize; // 30
|
||||
|
||||
before('get connection and prepare table', function(done) {
|
||||
oracledb.stmtCacheSize = 0;
|
||||
|
||||
beforeEach('get connection and prepare table', function(done) {
|
||||
oracledb.getConnection(credential, function(err, conn) {
|
||||
if(err) { console.error(err.message); return; }
|
||||
connection = conn;
|
||||
|
@ -383,7 +395,7 @@ describe('1. connection.js', function(){
|
|||
});
|
||||
})
|
||||
|
||||
after('drop table and release connection', function(done) {
|
||||
afterEach('drop table and release connection', function(done) {
|
||||
oracledb.stmtCacheSize = defaultStmtCache;
|
||||
connection.execute(
|
||||
"DROP TABLE oracledb_employees",
|
||||
|
@ -396,10 +408,51 @@ describe('1. connection.js', function(){
|
|||
}
|
||||
);
|
||||
})
|
||||
|
||||
it('works well when statement cache disabled', function(done) {
|
||||
|
||||
it('1.4.1 stmtCacheSize = 0, which disable statement caching', function(done) {
|
||||
connection.should.be.ok;
|
||||
(oracledb.stmtCacheSize).should.be.exactly(0);
|
||||
oracledb.stmtCacheSize = 0;
|
||||
|
||||
async.series([
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"INSERT INTO oracledb_employees VALUES (:num, :str)",
|
||||
{ num: 1003, str: 'Robyn Sands' },
|
||||
{ autoCommit: true },
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"INSERT INTO oracledb_employees VALUES (:num, :str)",
|
||||
{ num: 1004, str: 'Bryant Lin' },
|
||||
{ autoCommit: true },
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"INSERT INTO oracledb_employees VALUES (:num, :str)",
|
||||
{ num: 1005, str: 'Patrick Engebresson' },
|
||||
{ autoCommit: true },
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
}
|
||||
], done);
|
||||
})
|
||||
|
||||
it('1.4.2 works well when statement cache enabled (stmtCacheSize > 0) ', function(done) {
|
||||
connection.should.be.ok;
|
||||
oracledb.stmtCacheSize = 100;
|
||||
|
||||
async.series([
|
||||
function(callback) {
|
||||
|
@ -437,11 +490,10 @@ describe('1. connection.js', function(){
|
|||
}
|
||||
], done);
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe('1.5 stmtCacheSize > 0', function() {
|
||||
var connection = false;
|
||||
|
||||
describe('1.5 Testing commit() & rollback() functions', function() {
|
||||
var makeTable =
|
||||
"BEGIN \
|
||||
DECLARE \
|
||||
|
@ -462,83 +514,39 @@ describe('1. connection.js', function(){
|
|||
EXECUTE IMMEDIATE (' \
|
||||
INSERT INTO oracledb_employees \
|
||||
VALUES \
|
||||
(1001,''Chris Jones'') \
|
||||
(1001,''Tom Kyte'') \
|
||||
'); \
|
||||
EXECUTE IMMEDIATE (' \
|
||||
INSERT INTO oracledb_employees \
|
||||
VALUES \
|
||||
(1002,''Tom Kyte'') \
|
||||
(1002, ''Karen Morton'') \
|
||||
'); \
|
||||
EXECUTE IMMEDIATE (' \
|
||||
INSERT INTO oracledb_employees \
|
||||
VALUES \
|
||||
(2001, ''Karen Morton'') \
|
||||
'); \
|
||||
END; ";
|
||||
END; ";
|
||||
|
||||
var defaultStmtCache = oracledb.stmtCacheSize; // 30
|
||||
|
||||
before('get connection and prepare table', function(done) {
|
||||
oracledb.stmtCacheSize = 100;
|
||||
oracledb.getConnection(credential, function(err, conn) {
|
||||
if(err) { console.error(err.message); return; }
|
||||
connection = conn;
|
||||
conn.execute(
|
||||
makeTable,
|
||||
function(err){
|
||||
if(err) { console.error(err.message); return; }
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
})
|
||||
|
||||
after('drop table and release connection', function(done) {
|
||||
oracledb.stmtCacheSize = defaultStmtCache;
|
||||
connection.execute(
|
||||
"DROP TABLE oracledb_employees",
|
||||
function(err){
|
||||
if(err) { console.error(err.message); return; }
|
||||
connection.release( function(err){
|
||||
if(err) { console.error(err.message); return; }
|
||||
done();
|
||||
});
|
||||
}
|
||||
);
|
||||
})
|
||||
|
||||
it('works well when statement cache enabled', function(done) {
|
||||
connection.should.be.ok;
|
||||
(oracledb.stmtCacheSize).should.be.exactly(100);
|
||||
|
||||
var conn1 = false;
|
||||
var conn2 = false;
|
||||
beforeEach('get 2 connections and create the table', function(done) {
|
||||
async.series([
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"INSERT INTO oracledb_employees VALUES (:num, :str)",
|
||||
{ num: 1003, str: 'Robyn Sands' },
|
||||
{ autoCommit: true },
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
oracledb.getConnection(credential, function(err, conn) {
|
||||
should.not.exist(err);
|
||||
conn1 = conn;
|
||||
callback();
|
||||
});
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"INSERT INTO oracledb_employees VALUES (:num, :str)",
|
||||
{ num: 1004, str: 'Bryant Lin' },
|
||||
{ autoCommit: true },
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
oracledb.getConnection(credential, function(err, conn) {
|
||||
should.not.exist(err);
|
||||
conn2 = conn;
|
||||
callback();
|
||||
});
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"INSERT INTO oracledb_employees VALUES (:num, :str)",
|
||||
{ num: 1005, str: 'Patrick Engebresson' },
|
||||
{ autoCommit: true },
|
||||
conn1.should.be.ok;
|
||||
conn1.execute(
|
||||
makeTable,
|
||||
[],
|
||||
{ autoCommit: true },
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
|
@ -547,6 +555,138 @@ describe('1. connection.js', function(){
|
|||
}
|
||||
], done);
|
||||
})
|
||||
|
||||
afterEach('drop table and release connections', function(done) {
|
||||
conn1.should.be.ok;
|
||||
conn2.should.be.ok;
|
||||
async.series([
|
||||
function(callback) {
|
||||
conn2.execute(
|
||||
"DROP TABLE oracledb_employees",
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
conn1.release(function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
});
|
||||
},
|
||||
function(callback) {
|
||||
conn2.release(function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
], done);
|
||||
})
|
||||
|
||||
|
||||
it('1.5.1 commit() function works well', function(done) {
|
||||
async.series([
|
||||
function(callback) {
|
||||
conn2.execute(
|
||||
"INSERT INTO oracledb_employees VALUES (:num, :str)",
|
||||
{ num: 1003, str: 'Patrick Engebresson' },
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
conn1.execute(
|
||||
"SELECT COUNT(*) FROM oracledb_employees",
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
result.rows[0][0].should.be.exactly(2);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
conn2.execute(
|
||||
"SELECT COUNT(*) FROM oracledb_employees",
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
result.rows[0][0].should.be.exactly(3);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
conn2.commit(function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
});
|
||||
},
|
||||
function(callback) {
|
||||
conn1.execute(
|
||||
"SELECT COUNT(*) FROM oracledb_employees",
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
result.rows[0][0].should.be.exactly(3);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
], done);
|
||||
|
||||
})
|
||||
|
||||
it('1.5.2 rollback() function works well', function(done) {
|
||||
async.series([
|
||||
function(callback) {
|
||||
conn2.execute(
|
||||
"INSERT INTO oracledb_employees VALUES (:num, :str)",
|
||||
{ num: 1003, str: 'Patrick Engebresson' },
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
conn1.execute(
|
||||
"SELECT COUNT(*) FROM oracledb_employees",
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
result.rows[0][0].should.be.exactly(2);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
conn2.execute(
|
||||
"SELECT COUNT(*) FROM oracledb_employees",
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
result.rows[0][0].should.be.exactly(3);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
conn2.rollback(function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
});
|
||||
},
|
||||
function(callback) {
|
||||
conn2.execute(
|
||||
"SELECT COUNT(*) FROM oracledb_employees",
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
result.rows[0][0].should.be.exactly(2);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
], done);
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
|
|
|
@ -0,0 +1,242 @@
|
|||
/* Copyright (c) 2015, 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
|
||||
* 41. dataTypeBlob.js
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Testing Oracle data type support - BLOB.
|
||||
* This test corresponds to example files:
|
||||
* blobinsert1.js, blobstream1.js and blobstream2.js
|
||||
* Firstly, Loads an image data and INSERTs it into a BLOB column.
|
||||
* Secondly, SELECTs the BLOB and pipes it to a file, blobstreamout.jpg
|
||||
* Thirdly, SELECTs the BLOB and compares it with the original image
|
||||
*
|
||||
* NUMBERING RULE
|
||||
* Test numbers follow this numbering rule:
|
||||
* 1 - 20 are reserved for basic functional tests
|
||||
* 21 - 50 are reserved for data type supporting tests
|
||||
* 51 onwards are for other tests
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
var oracledb = require('oracledb');
|
||||
var fs = require('fs');
|
||||
var async = require('async');
|
||||
var should = require('should');
|
||||
var dbConfig = require('./dbConfig.js');
|
||||
var assist = require('./dataTypeAssist.js');
|
||||
|
||||
var inFileName = './test/fuzzydinosaur.jpg'; // contains the image to be inserted
|
||||
var outFileName = './test/blobstreamout.jpg';
|
||||
|
||||
describe('41. dataTypeBlob', function() {
|
||||
if(dbConfig.externalAuth){
|
||||
var credential = { externalAuth: true, connectString: dbConfig.connectString };
|
||||
} else {
|
||||
var credential = dbConfig;
|
||||
}
|
||||
|
||||
var connection = null;
|
||||
var tableName = "oracledb_myblobs";
|
||||
var sqlCreate =
|
||||
"BEGIN " +
|
||||
" DECLARE " +
|
||||
" e_table_exists EXCEPTION; " +
|
||||
" PRAGMA EXCEPTION_INIT(e_table_exists, -00942); " +
|
||||
" BEGIN " +
|
||||
" EXECUTE IMMEDIATE ('DROP TABLE " + tableName + " '); " +
|
||||
" EXCEPTION " +
|
||||
" WHEN e_table_exists " +
|
||||
" THEN NULL; " +
|
||||
" END; " +
|
||||
" EXECUTE IMMEDIATE (' " +
|
||||
" CREATE TABLE " + tableName +" ( " +
|
||||
" num NUMBER, " +
|
||||
" content BLOB " +
|
||||
" )" +
|
||||
" '); " +
|
||||
"END; ";
|
||||
|
||||
before(function(done) {
|
||||
oracledb.getConnection(credential, function(err, conn) {
|
||||
if(err) { console.error(err.message); return; }
|
||||
connection = conn;
|
||||
conn.execute(
|
||||
sqlCreate,
|
||||
function(err) {
|
||||
if(err) { console.error(err.message); return; }
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
})
|
||||
|
||||
after( function(done){
|
||||
connection.execute(
|
||||
"DROP table " + tableName,
|
||||
function(err) {
|
||||
if(err) { console.error(err.message); return; }
|
||||
connection.release( function(err) {
|
||||
if(err) { console.error(err.message); return; }
|
||||
done();
|
||||
});
|
||||
}
|
||||
);
|
||||
})
|
||||
|
||||
it('41.1 processes null value correctly', function(done) {
|
||||
assist.nullValueSupport(connection, tableName, done);
|
||||
})
|
||||
|
||||
it('41.2 stores BLOB value correctly', function(done) {
|
||||
connection.should.be.ok;
|
||||
async.series([
|
||||
function blobinsert1(callback) {
|
||||
var streamEndEventFired = false;
|
||||
setTimeout( function() {
|
||||
streamEndEventFired.should.equal(true, "inStream does not call 'end' event!")
|
||||
callback();
|
||||
}, 500);
|
||||
|
||||
connection.execute(
|
||||
"INSERT INTO oracledb_myblobs (num, content) VALUES (:n, EMPTY_BLOB()) RETURNING content INTO :lobbv",
|
||||
{ n: 2, lobbv: {type: oracledb.BLOB, dir: oracledb.BIND_OUT} },
|
||||
{ autoCommit: false }, // a transaction needs to span the INSERT and pipe()
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
(result.rowsAffected).should.be.exactly(1);
|
||||
(result.outBinds.lobbv.length).should.be.exactly(1);
|
||||
|
||||
var inStream = fs.createReadStream(inFileName);
|
||||
inStream.on('error', function(err) {
|
||||
should.not.exist(err, "inStream.on 'end' event");
|
||||
});
|
||||
|
||||
inStream.on('end', function() {
|
||||
streamEndEventFired = true;
|
||||
// now commit updates
|
||||
connection.commit( function(err) {
|
||||
should.not.exist(err);
|
||||
});
|
||||
});
|
||||
|
||||
var lob = result.outBinds.lobbv[0];
|
||||
|
||||
lob.on('error', function(err) {
|
||||
should.not.exist(err, "lob.on 'error' event");
|
||||
});
|
||||
|
||||
inStream.pipe(lob); // pipes the data to the BLOB
|
||||
}
|
||||
);
|
||||
},
|
||||
function blobstream1(callback) {
|
||||
var streamFinishEventFired = false;
|
||||
setTimeout( function() {
|
||||
streamFinishEventFired.should.equal(true, "stream does not call 'finish' Event!");
|
||||
callback();
|
||||
}, 500);
|
||||
|
||||
connection.execute(
|
||||
"SELECT content FROM oracledb_myblobs WHERE num = :n",
|
||||
{ n: 2 },
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
|
||||
var lob = result.rows[0][0];
|
||||
should.exist(lob);
|
||||
|
||||
lob.on('error', function(err) {
|
||||
should.not.exist(err, "lob.on 'end' event");
|
||||
});
|
||||
|
||||
var outStream = fs.createWriteStream(outFileName);
|
||||
|
||||
outStream.on('error', function(err) {
|
||||
should.not.exist(err, "outStream.on 'end' event");
|
||||
});
|
||||
|
||||
lob.pipe(outStream);
|
||||
outStream.on('finish', function() {
|
||||
fs.readFile( inFileName, function(err, originalData) {
|
||||
should.not.exist(err);
|
||||
|
||||
fs.readFile( outFileName, function(err, generatedData) {
|
||||
should.not.exist(err);
|
||||
originalData.should.eql(generatedData);
|
||||
|
||||
streamFinishEventFired = true;
|
||||
});
|
||||
});
|
||||
|
||||
}); // finish event
|
||||
}
|
||||
);
|
||||
},
|
||||
function blobstream2(callback) {
|
||||
var lobEndEventFired = false;
|
||||
var lobDataEventFired = false;
|
||||
setTimeout( function(){
|
||||
lobDataEventFired.should.equal(true, "lob does not call 'data' event!");
|
||||
lobEndEventFired.should.equal(true, "lob does not call 'end' event!");
|
||||
callback();
|
||||
}, 500);
|
||||
|
||||
connection.execute(
|
||||
"SELECT content FROM oracledb_myblobs WHERE num = :n",
|
||||
{ n: 2 },
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
|
||||
var blob = Buffer(0);
|
||||
var blobLength = 0;
|
||||
var lob = result.rows[0][0];
|
||||
|
||||
should.exist(lob);
|
||||
|
||||
lob.on('error', function(err) {
|
||||
should.not.exist(err, "lob.on 'end' event");
|
||||
});
|
||||
|
||||
lob.on('data', function(chunk) {
|
||||
// console.log("lob.on 'data' event");
|
||||
// console.log(' - got %d bytes of data', chunk.length);
|
||||
lobDataEventFired = true;
|
||||
blobLength = blobLength + chunk.length;
|
||||
blob = Buffer.concat([blob, chunk], blobLength);
|
||||
});
|
||||
|
||||
lob.on('end', function() {
|
||||
fs.readFile( inFileName, function(err, data) {
|
||||
should.not.exist(err);
|
||||
lobEndEventFired = true;
|
||||
|
||||
data.length.should.be.exactly(blob.length);
|
||||
data.should.eql(blob);
|
||||
});
|
||||
}); // end event
|
||||
|
||||
}
|
||||
);
|
||||
}
|
||||
], done);
|
||||
})
|
||||
})
|
|
@ -0,0 +1,241 @@
|
|||
/* Copyright (c) 2015, 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
|
||||
* 40. dataTypeClob.js
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Testing Oracle data type support - CLOB.
|
||||
* This test corresponds to example files:
|
||||
* clobinsert1.js, clobstream1.js and clobstream2.js
|
||||
* Firstly, reads text from clobexample.txt and INSERTs it into a CLOB column.
|
||||
* Secondly, SELECTs a CLOB and pipes it to a file, clobstreamout.txt
|
||||
* Thirdly, SELECTs the CLOB and compares it with the content in clobexample.txt
|
||||
*
|
||||
* NUMBERING RULE
|
||||
* Test numbers follow this numbering rule:
|
||||
* 1 - 20 are reserved for basic functional tests
|
||||
* 21 - 50 are reserved for data type supporting tests
|
||||
* 51 onwards are for other tests
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
var oracledb = require('oracledb');
|
||||
var fs = require('fs');
|
||||
var async = require('async');
|
||||
var should = require('should');
|
||||
var dbConfig = require('./dbConfig.js');
|
||||
var assist = require('./dataTypeAssist.js');
|
||||
|
||||
var inFileName = './test/clobexample.txt'; // the file with text to be inserted into the database
|
||||
var outFileName = './test/clobstreamout.txt';
|
||||
|
||||
describe('40. dataTypeClob.js', function() {
|
||||
|
||||
if(dbConfig.externalAuth){
|
||||
var credential = { externalAuth: true, connectString: dbConfig.connectString };
|
||||
} else {
|
||||
var credential = dbConfig;
|
||||
}
|
||||
|
||||
var connection = null;
|
||||
var tableName = "oracledb_myclobs";
|
||||
var sqlCreate =
|
||||
"BEGIN " +
|
||||
" DECLARE " +
|
||||
" e_table_exists EXCEPTION; " +
|
||||
" PRAGMA EXCEPTION_INIT(e_table_exists, -00942); " +
|
||||
" BEGIN " +
|
||||
" EXECUTE IMMEDIATE ('DROP TABLE " + tableName + " '); " +
|
||||
" EXCEPTION " +
|
||||
" WHEN e_table_exists " +
|
||||
" THEN NULL; " +
|
||||
" END; " +
|
||||
" EXECUTE IMMEDIATE (' " +
|
||||
" CREATE TABLE " + tableName +" ( " +
|
||||
" num NUMBER, " +
|
||||
" content CLOB " +
|
||||
" )" +
|
||||
" '); " +
|
||||
"END; ";
|
||||
|
||||
before(function(done) {
|
||||
oracledb.getConnection(credential, function(err, conn) {
|
||||
if(err) { console.error(err.message); return; }
|
||||
connection = conn;
|
||||
conn.execute(
|
||||
sqlCreate,
|
||||
function(err) {
|
||||
if(err) { console.error(err.message); return; }
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
})
|
||||
|
||||
after( function(done){
|
||||
connection.execute(
|
||||
"DROP table " + tableName,
|
||||
function(err) {
|
||||
if(err) { console.error(err.message); return; }
|
||||
connection.release( function(err) {
|
||||
if(err) { console.error(err.message); return; }
|
||||
done();
|
||||
});
|
||||
}
|
||||
);
|
||||
})
|
||||
|
||||
it('40.1 processes null value correctly', function(done) {
|
||||
assist.nullValueSupport(connection, tableName, done);
|
||||
})
|
||||
|
||||
it('40.2 stores CLOB value correctly', function(done) {
|
||||
connection.should.be.ok;
|
||||
async.series([
|
||||
function clobinsert1(callback) {
|
||||
var streamEndEventFired = false;
|
||||
setTimeout( function() {
|
||||
streamEndEventFired.should.equal(true, "inStream does not call 'end' event!")
|
||||
callback();
|
||||
}, 500);
|
||||
|
||||
connection.execute(
|
||||
"INSERT INTO oracledb_myclobs (num, content) VALUES (:n, EMPTY_CLOB()) RETURNING content INTO :lobbv",
|
||||
{ n: 1, lobbv: {type: oracledb.CLOB, dir: oracledb.BIND_OUT} },
|
||||
{ autoCommit: false }, // a transaction needs to span the INSERT and pipe()
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
(result.rowsAffected).should.be.exactly(1);
|
||||
(result.outBinds.lobbv.length).should.be.exactly(1);
|
||||
|
||||
var inStream = fs.createReadStream(inFileName);
|
||||
var lob = result.outBinds.lobbv[0];
|
||||
|
||||
lob.on('error', function(err) {
|
||||
should.not.exist(err, "lob.on 'error' event");
|
||||
});
|
||||
|
||||
inStream.on('error', function(err) {
|
||||
should.not.exist(err, "inStream.on 'end' event");
|
||||
});
|
||||
|
||||
inStream.on('end', function() {
|
||||
streamEndEventFired = true;
|
||||
// now commit updates
|
||||
connection.commit( function(err) {
|
||||
should.not.exist(err);
|
||||
});
|
||||
});
|
||||
inStream.pipe(lob); // copies the text to the CLOB
|
||||
}
|
||||
);
|
||||
},
|
||||
function clobstream1(callback) {
|
||||
var streamFinishEventFired = false;
|
||||
setTimeout( function() {
|
||||
streamFinishEventFired.should.equal(true, "stream does not call 'Finish' Event!");
|
||||
callback();
|
||||
}, 500);
|
||||
|
||||
connection.execute(
|
||||
"SELECT content FROM oracledb_myclobs WHERE num = :n",
|
||||
{ n: 1 },
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
|
||||
var lob = result.rows[0][0];
|
||||
should.exist(lob);
|
||||
lob.setEncoding('utf8');
|
||||
|
||||
lob.on('error', function(err) {
|
||||
should.not.exist(err, "lob.on 'end' event");
|
||||
});
|
||||
|
||||
var outStream = fs.createWriteStream(outFileName);
|
||||
outStream.on('error', function(err) {
|
||||
should.not.exist(err, "outStream.on 'end' event");
|
||||
});
|
||||
|
||||
lob.pipe(outStream);
|
||||
|
||||
outStream.on('finish', function() {
|
||||
|
||||
fs.readFile( inFileName, { encoding: 'utf8' }, function(err, originalData) {
|
||||
should.not.exist(err);
|
||||
|
||||
fs.readFile( outFileName, { encoding: 'utf8' }, function(err, generatedData) {
|
||||
should.not.exist(err);
|
||||
originalData.should.equal(generatedData);
|
||||
|
||||
streamFinishEventFired = true;
|
||||
});
|
||||
});
|
||||
})
|
||||
}
|
||||
);
|
||||
},
|
||||
function clobstream2(callback) {
|
||||
var lobEndEventFired = false;
|
||||
var lobDataEventFired = false;
|
||||
setTimeout( function(){
|
||||
lobDataEventFired.should.equal(true, "lob does not call 'data' event!");
|
||||
lobEndEventFired.should.equal(true, "lob does not call 'end' event!");
|
||||
callback();
|
||||
}, 500);
|
||||
|
||||
connection.execute(
|
||||
"SELECT content FROM oracledb_myclobs WHERE num = :n",
|
||||
{ n: 1 },
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
|
||||
var clob = '';
|
||||
var lob = result.rows[0][0];
|
||||
should.exist(lob);
|
||||
lob.setEncoding('utf8'); // set the encoding so we get a 'string' not a 'buffer'
|
||||
|
||||
lob.on('data', function(chunk) {
|
||||
// console.log("lob.on 'data' event");
|
||||
// console.log(' - got %d bytes of data', chunk.length);
|
||||
lobDataEventFired = true;
|
||||
clob += chunk;
|
||||
});
|
||||
|
||||
lob.on('end', function() {
|
||||
fs.readFile( inFileName, { encoding: 'utf8' }, function(err, data) {
|
||||
should.not.exist(err);
|
||||
lobEndEventFired = true;
|
||||
|
||||
data.length.should.be.exactly(clob.length);
|
||||
data.should.equal(clob);
|
||||
});
|
||||
});
|
||||
|
||||
lob.on('error', function(err) {
|
||||
should.not.exist(err, "lob.on 'end' event");
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
], done);
|
||||
|
||||
})
|
||||
})
|
|
@ -0,0 +1,127 @@
|
|||
/* Copyright (c) 2015, 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
|
||||
* 39. dataTypeRowid.js
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Testing Oracle data type support - ROWID.
|
||||
*
|
||||
* NOTE
|
||||
* Native ROWID support is still under enhancement request.
|
||||
*
|
||||
* NUMBERING RULE
|
||||
* Test numbers follow this numbering rule:
|
||||
* 1 - 20 are reserved for basic functional tests
|
||||
* 21 - 50 are reserved for data type supporting tests
|
||||
* 51 - are for other tests
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
var oracledb = require('oracledb');
|
||||
var should = require('should');
|
||||
var async = require('async');
|
||||
var dbConfig = require('./dbConfig.js');
|
||||
|
||||
describe('39. dataTypeRowid.js', function() {
|
||||
|
||||
if(dbConfig.externalAuth){
|
||||
var credential = { externalAuth: true, connectString: dbConfig.connectString };
|
||||
} else {
|
||||
var credential = dbConfig;
|
||||
}
|
||||
|
||||
var connection = false;
|
||||
before(function(done) {
|
||||
oracledb.getConnection(credential, function(err, conn) {
|
||||
if(err) { console.error(err.message); return; }
|
||||
connection = conn;
|
||||
done();
|
||||
});
|
||||
})
|
||||
|
||||
after(function(done) {
|
||||
connection.release(function(err) {
|
||||
if(err) { console.error(err.message); return; }
|
||||
done();
|
||||
});
|
||||
})
|
||||
|
||||
it('39.1 supports ROWID data type', function(done) {
|
||||
connection.should.be.ok;
|
||||
var createTable =
|
||||
"BEGIN \
|
||||
DECLARE \
|
||||
e_table_exists EXCEPTION; \
|
||||
PRAGMA EXCEPTION_INIT(e_table_exists, -00942); \
|
||||
BEGIN \
|
||||
EXECUTE IMMEDIATE ('DROP TABLE oracledb_row'); \
|
||||
EXCEPTION \
|
||||
WHEN e_table_exists \
|
||||
THEN NULL; \
|
||||
END; \
|
||||
EXECUTE IMMEDIATE (' \
|
||||
CREATE TABLE oracledb_row ( \
|
||||
ID NUMBER, \
|
||||
RID ROWID \
|
||||
) \
|
||||
'); \
|
||||
EXECUTE IMMEDIATE (' \
|
||||
INSERT INTO oracledb_row(ID) VALUES(1) \
|
||||
'); \
|
||||
EXECUTE IMMEDIATE (' \
|
||||
UPDATE oracledb_row T SET RID = T.ROWID \
|
||||
'); \
|
||||
END; ";
|
||||
|
||||
async.series([
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
createTable,
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"SELECT * FROM oracledb_row",
|
||||
[],
|
||||
{ outFormat: oracledb.OBJECT },
|
||||
function(err, result) {
|
||||
should.exist(err);
|
||||
err.message.should.startWith('NJS-010:'); // unsupported data type in select list
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"DROP TABLE oracledb_row",
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
}
|
||||
], done);
|
||||
})
|
||||
})
|
|
@ -98,7 +98,7 @@ describe('35. dataTypeTimestamp3.js', function() {
|
|||
);
|
||||
})
|
||||
|
||||
it.skip('supports TIMESTAMP WITH TIME ZONE data type', function(done) {
|
||||
it('supports TIMESTAMP WITH TIME ZONE data type', function(done) {
|
||||
connection.should.be.ok;
|
||||
|
||||
var timestamps = [
|
||||
|
@ -126,12 +126,14 @@ describe('35. dataTypeTimestamp3.js', function() {
|
|||
[],
|
||||
{ outFormat: oracledb.OBJECT },
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
// console.log(result);
|
||||
should.exist(err);
|
||||
err.message.should.startWith('NJS-010:'); // unsupported data type in select list
|
||||
/*
|
||||
console.log(result);
|
||||
for(var j = 0; j < timestamps.length; j++)
|
||||
result.rows[j].CONTENT.toUTCString().should.eql(timestamps[result.rows[j].NUM].toUTCString());
|
||||
|
||||
done();
|
||||
*/
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
|
|
@ -98,7 +98,7 @@ describe('36. dataTypeTimestamp4.js', function() {
|
|||
);
|
||||
})
|
||||
|
||||
it.skip('supports TIMESTAMP WITH TIME ZONE data type', function(done) {
|
||||
it('supports TIMESTAMP WITH TIME ZONE data type', function(done) {
|
||||
connection.should.be.ok;
|
||||
|
||||
var timestamps = [
|
||||
|
@ -126,12 +126,14 @@ describe('36. dataTypeTimestamp4.js', function() {
|
|||
[],
|
||||
{ outFormat: oracledb.OBJECT },
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
// console.log(result);
|
||||
should.exist(err);
|
||||
err.message.should.startWith('NJS-010:'); // unsupported data type in select list
|
||||
/*
|
||||
console.log(result);
|
||||
for(var j = 0; j < timestamps.length; j++)
|
||||
result.rows[j].CONTENT.toUTCString().should.eql(timestamps[result.rows[j].NUM].toUTCString());
|
||||
|
||||
done();
|
||||
*/
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
|
|
@ -31,8 +31,8 @@
|
|||
*****************************************************************************/
|
||||
|
||||
module.exports = {
|
||||
user : "hr",
|
||||
password : "welcome",
|
||||
connectString : "localhost/orcl",
|
||||
externalAuth : false
|
||||
user : process.env.NODE_ORACLEDB_USER || "hr",
|
||||
password : process.env.NODE_ORACLEDB_PASSWORD || "welcome",
|
||||
connectString : process.env.NODE_ORACLEDB_CONNECTIONSTRING || "localhost/orcl",
|
||||
externalAuth : process.env.NODE_ORACLEDB_EXTERNALAUTH ? true : false
|
||||
};
|
||||
|
|
|
@ -157,7 +157,7 @@ describe('6. dmlReturning.js', function(){
|
|||
{ autoCommit: true },
|
||||
function(err, result) {
|
||||
should.exist(err);
|
||||
err.message.should.eql('NJS-016: buffer is too small for OUT binds');
|
||||
err.message.should.startWith('NJS-016'); // NJS-016: buffer is too small for OUT binds
|
||||
//console.log(result);
|
||||
done();
|
||||
}
|
||||
|
|
221
test/examples.js
221
test/examples.js
|
@ -510,17 +510,7 @@ describe('3. examples.js', function(){
|
|||
|
||||
describe('3.7 plsql.js', function(){
|
||||
var connection = false;
|
||||
var proc = "CREATE OR REPLACE PROCEDURE testproc (p_in IN VARCHAR2, p_inout IN OUT VARCHAR2, p_out OUT NUMBER) \
|
||||
AS \
|
||||
BEGIN \
|
||||
p_inout := p_in || p_inout; \
|
||||
p_out := 101; \
|
||||
END; ";
|
||||
var bindVars = {
|
||||
i: 'Chris', // bind type is determined from the data type
|
||||
io: { val: 'Jones', dir : oracledb.BIND_INOUT },
|
||||
o: { type: oracledb.NUMBER, dir : oracledb.BIND_OUT }
|
||||
}
|
||||
|
||||
before(function(done){
|
||||
oracledb.getConnection(credential, function(err, conn){
|
||||
if(err) { console.error(err.message); return; }
|
||||
|
@ -537,6 +527,19 @@ describe('3. examples.js', function(){
|
|||
})
|
||||
|
||||
it('3.7.1 can call PL/SQL procedure and binding parameters in various ways', function(done){
|
||||
var proc =
|
||||
"CREATE OR REPLACE PROCEDURE testproc (p_in IN VARCHAR2, p_inout IN OUT VARCHAR2, p_out OUT NUMBER) \
|
||||
AS \
|
||||
BEGIN \
|
||||
p_inout := p_in || p_inout; \
|
||||
p_out := 101; \
|
||||
END; ";
|
||||
var bindVars = {
|
||||
i: 'Chris', // bind type is determined from the data type
|
||||
io: { val: 'Jones', dir : oracledb.BIND_INOUT },
|
||||
o: { type: oracledb.NUMBER, dir : oracledb.BIND_OUT }
|
||||
}
|
||||
|
||||
async.series([
|
||||
function(callback){
|
||||
connection.execute(
|
||||
|
@ -570,6 +573,53 @@ describe('3. examples.js', function(){
|
|||
}
|
||||
], done);
|
||||
})
|
||||
|
||||
it('3.7.2 can call PL/SQL function', function(done) {
|
||||
var proc =
|
||||
"CREATE OR REPLACE FUNCTION testfunc (p1_in IN VARCHAR2, p2_in IN VARCHAR2) RETURN VARCHAR2 \
|
||||
AS \
|
||||
BEGIN \
|
||||
return p1_in || p2_in; \
|
||||
END; ";
|
||||
var bindVars = {
|
||||
p1: 'Chris',
|
||||
p2: 'Jones',
|
||||
ret: { dir: oracledb.BIND_OUT, type: oracledb.STRING, maxSize: 40 }
|
||||
};
|
||||
|
||||
async.series([
|
||||
function(callback){
|
||||
connection.execute(
|
||||
proc,
|
||||
function(err){
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback){
|
||||
connection.execute(
|
||||
"BEGIN :ret := testfunc(:p1, :p2); END;",
|
||||
bindVars,
|
||||
function(err, result){
|
||||
should.not.exist(err);
|
||||
// console.log(result);
|
||||
(result.outBinds.ret).should.equal('ChrisJones');
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback){
|
||||
connection.execute(
|
||||
"DROP FUNCTION testfunc",
|
||||
function(err, result){
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
}
|
||||
], done);
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
|
@ -900,8 +950,155 @@ describe('3. examples.js', function(){
|
|||
});
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
})
|
||||
|
||||
describe('3.11 refcursor.js', function() {
|
||||
var connection = false;
|
||||
var script =
|
||||
"BEGIN \
|
||||
DECLARE \
|
||||
e_table_exists EXCEPTION; \
|
||||
PRAGMA EXCEPTION_INIT(e_table_exists, -00942); \
|
||||
BEGIN \
|
||||
EXECUTE IMMEDIATE ('DROP TABLE oracledb_employees'); \
|
||||
EXCEPTION \
|
||||
WHEN e_table_exists \
|
||||
THEN NULL; \
|
||||
END; \
|
||||
EXECUTE IMMEDIATE (' \
|
||||
CREATE TABLE oracledb_employees ( \
|
||||
name VARCHAR2(40), \
|
||||
salary NUMBER, \
|
||||
hire_date DATE \
|
||||
) \
|
||||
'); \
|
||||
EXECUTE IMMEDIATE (' \
|
||||
INSERT INTO oracledb_employees \
|
||||
(name, salary, hire_date) VALUES \
|
||||
(''Steven'',24000, TO_DATE(''20030617'', ''yyyymmdd'')) \
|
||||
'); \
|
||||
EXECUTE IMMEDIATE (' \
|
||||
INSERT INTO oracledb_employees \
|
||||
(name, salary, hire_date) VALUES \
|
||||
(''Neena'',17000, TO_DATE(''20050921'', ''yyyymmdd'')) \
|
||||
'); \
|
||||
EXECUTE IMMEDIATE (' \
|
||||
INSERT INTO oracledb_employees \
|
||||
(name, salary, hire_date) VALUES \
|
||||
(''Lex'',17000, TO_DATE(''20010112'', ''yyyymmdd'')) \
|
||||
'); \
|
||||
EXECUTE IMMEDIATE (' \
|
||||
INSERT INTO oracledb_employees \
|
||||
(name, salary, hire_date) VALUES \
|
||||
(''Nancy'',12008, TO_DATE(''20020817'', ''yyyymmdd'')) \
|
||||
'); \
|
||||
EXECUTE IMMEDIATE (' \
|
||||
INSERT INTO oracledb_employees \
|
||||
(name, salary, hire_date) VALUES \
|
||||
(''Karen'',14000, TO_DATE(''20050104'', ''yyyymmdd'')) \
|
||||
'); \
|
||||
EXECUTE IMMEDIATE (' \
|
||||
INSERT INTO oracledb_employees \
|
||||
(name, salary, hire_date) VALUES \
|
||||
(''Peter'',9000, TO_DATE(''20100525'', ''yyyymmdd'')) \
|
||||
'); \
|
||||
END; ";
|
||||
|
||||
var proc =
|
||||
"CREATE OR REPLACE PROCEDURE get_emp_rs (p_sal IN NUMBER, p_recordset OUT SYS_REFCURSOR) \
|
||||
AS \
|
||||
BEGIN \
|
||||
OPEN p_recordset FOR \
|
||||
SELECT * FROM oracledb_employees \
|
||||
WHERE salary > p_sal; \
|
||||
END; ";
|
||||
|
||||
before(function(done){
|
||||
async.series([
|
||||
function(callback) {
|
||||
oracledb.getConnection(
|
||||
credential,
|
||||
function(err, conn) {
|
||||
should.not.exist(err);
|
||||
connection = conn;
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
script,
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
proc,
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
}
|
||||
], done);
|
||||
})
|
||||
|
||||
after(function(done){
|
||||
connection.execute(
|
||||
'DROP TABLE oracledb_employees',
|
||||
function(err){
|
||||
if(err) { console.error(err.message); return; }
|
||||
connection.release( function(err){
|
||||
if(err) { console.error(err.message); return; }
|
||||
done();
|
||||
});
|
||||
}
|
||||
);
|
||||
})
|
||||
|
||||
it('3.11.1 REF CURSOR', function(done) {
|
||||
connection.should.be.ok;
|
||||
var numRows = 100; // number of rows to return from each call to getRows()
|
||||
|
||||
connection.execute(
|
||||
"BEGIN get_emp_rs(:sal, :cursor); END;",
|
||||
{
|
||||
sal: 12000,
|
||||
cursor: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||
},
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
result.outBinds.cursor.metaData[0].name.should.eql('NAME');
|
||||
result.outBinds.cursor.metaData[1].name.should.eql('SALARY');
|
||||
result.outBinds.cursor.metaData[2].name.should.eql('HIRE_DATE');
|
||||
fetchRowsFromRS(result.outBinds.cursor);
|
||||
}
|
||||
);
|
||||
|
||||
function fetchRowsFromRS(resultSet) {
|
||||
resultSet.getRows(
|
||||
numRows,
|
||||
function(err, rows) {
|
||||
should.not.exist(err);
|
||||
if(rows.length > 0) {
|
||||
// console.log("fetchRowsFromRS(): Got " + rows.length + " rows");
|
||||
// console.log(rows);
|
||||
rows.length.should.be.exactly(5);
|
||||
fetchRowsFromRS(resultSet);
|
||||
} else {
|
||||
resultSet.close( function(err) {
|
||||
should.not.exist(err);
|
||||
done();
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
|
|
|
@ -0,0 +1,260 @@
|
|||
/* Copyright (c) 2015, 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
|
||||
* 56. fetchAs.js
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Testing driver fetchAs feature.
|
||||
*
|
||||
* NUMBERING RULE
|
||||
* Test numbers follow this numbering rule:
|
||||
* 1 - 20 are reserved for basic functional tests
|
||||
* 21 - 50 are reserved for data type supporting tests
|
||||
* 51 onwards are for other tests
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
var oracledb = require ( 'oracledb' );
|
||||
var should = require ( 'should' );
|
||||
var async = require ( 'async' );
|
||||
var dbConfig = require ( './dbConfig.js' );
|
||||
|
||||
describe ('56. fetchAs.js',
|
||||
function ()
|
||||
{
|
||||
if (dbConfig.externalAuth )
|
||||
{
|
||||
var credential = { externalAuth : true,
|
||||
connectString : dbConfig.connectString
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
var credential = dbConfig;
|
||||
}
|
||||
|
||||
var connection = false;
|
||||
|
||||
|
||||
/* preparation work before test case(s). */
|
||||
before (
|
||||
function ( done )
|
||||
{
|
||||
oracledb.getConnection ( credential,
|
||||
function ( err, conn )
|
||||
{
|
||||
if ( err )
|
||||
{
|
||||
console.error ( err.message );
|
||||
return;
|
||||
}
|
||||
connection = conn;
|
||||
done ();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
/* clean up after test case(s) */
|
||||
after (
|
||||
function ( done )
|
||||
{
|
||||
connection.release (
|
||||
function ( err )
|
||||
{
|
||||
oracledb.fetchAsString = [] ;
|
||||
|
||||
if ( err )
|
||||
{
|
||||
console.error ( err.message );
|
||||
return;
|
||||
}
|
||||
done ();
|
||||
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
/* Fetch DATE column values as STRING - by-Column name */
|
||||
it ('56.1 FetchAs - DATE type as STRING',
|
||||
function ( done )
|
||||
{
|
||||
connection.should.be.ok;
|
||||
|
||||
connection.execute (
|
||||
"SELECT FIRST_NAME, LAST_NAME, HIRE_DATE FROM EMPLOYEES",
|
||||
[],
|
||||
{
|
||||
outFormat : oracledb.OBJECT,
|
||||
fetchInfo : { "HIRE_DATE" : { type : oracledb.STRING } }
|
||||
},
|
||||
function ( err, result )
|
||||
{
|
||||
should.not.exist ( err ) ;
|
||||
done ();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
/* Fetch DATE, NUMBER column values STRING - by Column-name */
|
||||
it ('56.2 FetchAs NUMBER & DATE type as STRING',
|
||||
function ( done )
|
||||
{
|
||||
connection.should.be.ok;
|
||||
|
||||
connection.execute (
|
||||
"SELECT employee_id as SEMPID, employee_id, " +
|
||||
"hire_date as SHDATE, hire_date FROM EMPLOYEES",
|
||||
[],
|
||||
{
|
||||
outFormat : oracledb.OBJECT,
|
||||
fetchInfo :
|
||||
{
|
||||
"SEMPID" : { type : oracledb.STRING },
|
||||
"SHDATE" : { type : oracledb.STRING }
|
||||
}
|
||||
},
|
||||
function ( err, result )
|
||||
{
|
||||
should.not.exist ( err ) ;
|
||||
done ();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
/* Fetch DATE, NUMBER as STRING by-time configuration and by-name */
|
||||
it ('56.3 FetchAs Oracledb property by-type',
|
||||
function ( done )
|
||||
{
|
||||
connection.should.be.ok;
|
||||
|
||||
oracledb.fetchAsString = [ oracledb.DATE, oracledb.NUMBER ];
|
||||
|
||||
connection.execute (
|
||||
"SELECT employee_id, first_name, last_name, hire_date " +
|
||||
"FROM EMPLOYEES",
|
||||
[],
|
||||
{
|
||||
outFormat : oracledb.OBJECT,
|
||||
fetchInfo :
|
||||
{
|
||||
"HIRE_DATE" : { type : oracledb.STRING }
|
||||
}
|
||||
},
|
||||
function ( err, result )
|
||||
{
|
||||
should.not.exist ( err ) ;
|
||||
done ();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
* Fetch DATE, NUMBER column as STRING by-type and override
|
||||
* HIRE_DATE to use default (from metadata type).
|
||||
*/
|
||||
it ('56.4 FetchAs override oracledb by-type (for DATE) at execute time',
|
||||
function ( done )
|
||||
{
|
||||
connection.should.be.ok;
|
||||
|
||||
oracledb.fetchAsString = [ oracledb.DATE, oracledb.NUMBER ];
|
||||
|
||||
connection.execute (
|
||||
"SELECT employee_id, first_name, last_name, hire_date " +
|
||||
"FROM EMPLOYEES",
|
||||
[],
|
||||
{
|
||||
outFormat : oracledb.OBJECT,
|
||||
fetchInfo :
|
||||
{
|
||||
"HIRE_DATE" : { type : oracledb.DEFAULT },
|
||||
"EMPLOYEE_ID" : { type : oracledb.STRING }
|
||||
}
|
||||
},
|
||||
function ( err, result )
|
||||
{
|
||||
should.not.exist ( err ) ;
|
||||
done ();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
/* Fetch ROWID column values STRING - non-ResultSet */
|
||||
it ('56.5 FetchInfo ROWID column values STRING non-ResultSet',
|
||||
function ( done )
|
||||
{
|
||||
connection.should.be.ok;
|
||||
|
||||
connection.execute (
|
||||
"SELECT ROWID from DUAL",
|
||||
[],
|
||||
{
|
||||
outFormat : oracledb.OBJECT,
|
||||
fetchInfo :
|
||||
{
|
||||
"ROWID" : { type : oracledb.STRING }
|
||||
}
|
||||
},
|
||||
function ( err, result )
|
||||
{
|
||||
should.not.exist ( err ) ;
|
||||
done ();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
/* Fetch ROWID column values STRING - ResultSet */
|
||||
it ('56.6 FetchInfo ROWID column values STRING ResultSet',
|
||||
function ( done )
|
||||
{
|
||||
connection.should.be.ok;
|
||||
|
||||
connection.execute (
|
||||
"SELECT ROWID from DUAL",
|
||||
[],
|
||||
{
|
||||
outFormat : oracledb.OBJECT,
|
||||
resultSet : true,
|
||||
fetchInfo :
|
||||
{
|
||||
"ROWID" : { type : oracledb.STRING }
|
||||
}
|
||||
},
|
||||
function ( err, result )
|
||||
{
|
||||
should.not.exist ( err ) ;
|
||||
done ();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
|
@ -0,0 +1,339 @@
|
|||
1. connection.js
|
||||
1.1 can run SQL query with different output formats
|
||||
1.1.1 ARRAY format by default
|
||||
1.1.2 ARRAY format explicitly
|
||||
1.1.3 OBJECT format
|
||||
1.1.4 Negative test - invalid outFormat value
|
||||
1.2 limits the number of rows fetched
|
||||
1.2.1 by default, the number is 100
|
||||
1.2.2 can also specify for each execution
|
||||
1.2.3 can set maxRows to be 0
|
||||
1.2.4 cannot set maxRows to be a negative number
|
||||
1.2.5 sets maxRows to be very large value
|
||||
1.3 can call PL/SQL procedures
|
||||
1.3.1 bind parameters in various ways
|
||||
1.4 statementCacheSize controls statement caching
|
||||
1.4.1 stmtCacheSize = 0, which disable statement caching
|
||||
1.4.2 works well when statement cache enabled (stmtCacheSize > 0)
|
||||
1.5 Testing commit() & rollback() functions
|
||||
1.5.1 commit() function works well
|
||||
1.5.2 rollback() function works well
|
||||
|
||||
2. pool.js
|
||||
2.1 default values
|
||||
2.1.1 set properties to default values if not explicitly specified
|
||||
2.2 poolMin
|
||||
2.2.1 poolMin cannot be a negative number
|
||||
2.2.2 poolMin must be a Number
|
||||
2.2.3 poolMin cannot equal to poolMax
|
||||
2.2.4 poolMin cannot greater than poolMax
|
||||
2.2.5 (poolMin + poolIncrement) cannot greater than poolMax
|
||||
2.2.6 (poolMin + poolIncrement) can equal to poolMax
|
||||
2.3 poolMax
|
||||
2.3.1 poolMax cannot be a negative value
|
||||
2.3.2 poolMax cannot be 0
|
||||
2.3.3 poolMax must be a number
|
||||
2.3.4 poolMax limits the pool capacity
|
||||
2.4 poolIncrement
|
||||
2.4.1 poolIncrement cannot be a negative value
|
||||
2.4.2 poolIncrement cannot be 0
|
||||
2.4.3 poolIncrement must be a Number
|
||||
2.4.4 the amount of open connections equals to poolMax when (connectionsOpen + poolIncrement) > poolMax
|
||||
2.5 poolTimeout
|
||||
2.5.1 poolTimeout cannot be a negative number
|
||||
2.5.2 poolTimeout can be 0, which disables timeout feature
|
||||
2.5.3 poolTimeout must be a number
|
||||
2.6 stmtCacheSize
|
||||
2.6.1 stmtCacheSize cannot be a negative value
|
||||
2.6.2 stmtCacheSize can be 0
|
||||
2.6.3 stmtCacheSize must be a Number
|
||||
|
||||
3. examples.js
|
||||
3.1 connect.js
|
||||
3.1.1 tests a basic connection to the database
|
||||
3.2 version.js
|
||||
3.2.1 shows the oracledb version attribute
|
||||
3.3 select1.js & select2.js
|
||||
3.3.1. execute a basic query
|
||||
3.3.2. execute queries to show array and object formats
|
||||
3.4 selectjson.js - 12.1.0.2 feature
|
||||
3.4.1 executes a query from a JSON table
|
||||
3.5 date.js
|
||||
3.5.1 inserts and query DATE and TIMESTAMP columns
|
||||
3.6 rowlimit.js
|
||||
3.6.1 by default, the number is 100
|
||||
3.6.2 can also specify for each execution
|
||||
3.7 plsql.js
|
||||
3.7.1 can call PL/SQL procedure and binding parameters in various ways
|
||||
3.7.2 can call PL/SQL function
|
||||
3.8 insert1.js
|
||||
3.8.1 creates a table and inserts data
|
||||
3.9 insert2.js
|
||||
3.9.1 tests the auto commit behavior
|
||||
3.10 resultset.js
|
||||
3.10.1 resultset1.js - getRow() function
|
||||
3.10.2 resultset2.js - getRows() function
|
||||
3.11 refcursor.js
|
||||
3.11.1 REF CURSOR
|
||||
|
||||
4. binding.js
|
||||
4.1 test STRING, NUMBER, ARRAY & JSON format
|
||||
4.1.1 VARCHAR2 binding, Object & Array formats
|
||||
4.1.2 NUMBER binding, Object & Array formats
|
||||
4.1.3 Multiple binding values, Object & Array formats
|
||||
4.1.4 Multiple binding values, Change binding order
|
||||
4.1.5 default bind type - STRING
|
||||
4.2 mixing named with positional binding
|
||||
4.2.1 array binding is ok
|
||||
- 4.2.2 array binding with mixing JSON should throw an error
|
||||
4.3 insert with DATE column and DML returning
|
||||
4.3.1 passes in object syntax without returning into
|
||||
4.3.2 passes in object syntax with returning into
|
||||
4.3.3 passes in array syntax without returning into
|
||||
4.3.4 should pass but fail in array syntax with returning into
|
||||
4.4 test maxSize option
|
||||
4.4.1 outBind & maxSize restriction
|
||||
- 4.4.2 default value is 200
|
||||
- 4.4.3 maximum value is 32767
|
||||
|
||||
5. externalAuthentication.js
|
||||
5.1 connection should succeed when setting externalAuth to be false and providing user/password
|
||||
5.2 error should be thrown when setting externalAuth to be true and providing user/password
|
||||
5.3 can get connection from oracledb
|
||||
5.4 can create pool
|
||||
|
||||
6. dmlReturning.js
|
||||
6.1 NUMBER & STRING driver data type
|
||||
6.1.1 INSERT statement with Object binding
|
||||
6.1.2 INSERT statement with Array binding
|
||||
6.1.3 INSERT statement with small maxSize restriction
|
||||
6.1.4 UPDATE statement with single row matched
|
||||
6.1.5 UPDATE statement with single row matched & Array binding
|
||||
6.1.6 UPDATE statements with multiple rows matched
|
||||
6.1.7 UPDATE statements with multiple rows matched & Array binding
|
||||
6.1.8 DELETE statement with Object binding
|
||||
6.1.9 DELETE statement with Array binding
|
||||
6.1.10 Stress test - support 4k varchars
|
||||
6.1.11 Negative test - throws correct error message
|
||||
|
||||
7. autoCommit.js
|
||||
7.1 autoCommit takes effect when setting oracledb.autoCommit before connecting
|
||||
7.2 autoCommit takes effect when setting oracledb.autoCommit after connecting
|
||||
7.3 autoCommit setting does not affect previous SQL result
|
||||
|
||||
8. autoCommitForSelect.js
|
||||
8.1 should return previous value when autoCommit is false
|
||||
8.2 can use explicit commit() to keep data consistent
|
||||
8.3 can also use the autoCommit for SELECTs feature
|
||||
|
||||
9. columnMetadata.js
|
||||
9.1 shows metaData correctly when retrieving 1 column from a 4-column table
|
||||
9.2 shows metaData when retrieving 2 columns. MetaData is correct in content and sequence
|
||||
9.3 shows metaData correctly when retrieve 3 columns
|
||||
9.4 shows metaData correctly when retrieving all columns with [SELECT * FROM table] statement
|
||||
9.5 works for SELECT count(*)
|
||||
9.6 works when a query returns no rows
|
||||
9.7 works for tables whose column names were created case sensitively
|
||||
9.8 only works for SELECT statement, does not work for INSERT
|
||||
9.9 only works for SELECT statement, does not work for UPDATE
|
||||
9.10 works with a large number of columns
|
||||
9.11 works with column names consisting of single characters
|
||||
9.12 works with a SQL WITH statement
|
||||
|
||||
10. nullColumnValues.js
|
||||
10.1 a simple query for null value
|
||||
10.2 in-bind for null column value
|
||||
10.3 out-bind for null column value
|
||||
10.4 DML Returning for null column value
|
||||
10.5 resultSet for null value
|
||||
|
||||
11. poolTimeout.js
|
||||
pool terminates idle connections after specify time
|
||||
|
||||
12. resultSet1.js
|
||||
12.1 Testing resultSet option
|
||||
12.1.1 when resultSet option = false, content of result is correct
|
||||
12.1.2 when resultSet option = true, content of result is correct
|
||||
12.1.3 when resultSet option = 0, it behaves like false
|
||||
12.1.4 when resultSet option = null, it behaves like false
|
||||
12.1.5 when resultSet option = undefined, it behaves like false
|
||||
12.1.6 when resultSet option = NaN, it behaves like false
|
||||
12.1.7 when resultSet option = 1, it behaves like true
|
||||
12.1.8 when resultSet option = -1, it behaves like true
|
||||
12.1.9 when resultSet option is a random string, it behaves like true
|
||||
12.2 Testing prefetchRows option
|
||||
12.2.1 cannot set prefetchRows to be a negative value
|
||||
12.2.2 cannot set prefetchRows to be a random string
|
||||
12.2.3 cannot set prefetchRows to be NaN
|
||||
12.2.4 cannot set prefetchRows to be null
|
||||
12.2.5 prefetchRows can be set to 0
|
||||
12.3 Testing function getRows()
|
||||
12.3.1 retrieved set is exactly the size of result
|
||||
12.3.2 retrieved set is greater than the size of result
|
||||
12.3.3 retrieved set is half of the size of result
|
||||
12.3.4 retrieved set is one tenth of the size of the result
|
||||
12.3.5 data in resultSet is array when setting outFormat ARRAY
|
||||
12.3.6 data in resultSet is object when setting outFormat OBJECT
|
||||
12.3.7 the size of retrieved set can be set to 1
|
||||
12.3.8 query 0 row
|
||||
12.3.9 Negative - To omit the first parameter
|
||||
12.3.10 Negative - set the 1st parameter of getRows() to be 0
|
||||
12.3.11 Negative - set the 1st parameter of getRows() to be -5
|
||||
12.3.12 Negative - set the 1st parameter of getRows() to be null
|
||||
12.4 Testing function getRow()
|
||||
12.4.1 works well with all correct setting
|
||||
12.4.2 data in resultSet is array when setting outFormat ARRAY
|
||||
12.4.3 data in resultSet is object when setting outFormat OBJECT
|
||||
12.4.4 query 0 row
|
||||
12.4.5 Negative - set the first parameter like getRows()
|
||||
12.5 Testing function close()
|
||||
12.5.1 does not call close()
|
||||
12.5.2 invokes close() twice
|
||||
12.5.3 uses getRows after calling close()
|
||||
12.5.4 closes one resultSet and then open another resultSet
|
||||
12.6 Testing metaData
|
||||
12.6.1 the amount and value of metaData should be correct
|
||||
12.6.2 can distinguish lower case and upper case
|
||||
12.6.3 can contain quotes
|
||||
12.6.4 can contain underscore
|
||||
12.7 Testing maxRows
|
||||
12.7.1 maxRows option is ignored when resultSet option is true
|
||||
12.7.2 maxRows option is ignored with REF Cursor
|
||||
|
||||
21. datatypeAssist.js
|
||||
|
||||
22. dataTypeChar.js
|
||||
22.1 supports CHAR data
|
||||
22.2 resultSet stores CHAR data correctly
|
||||
22.3 stores null value correctly
|
||||
|
||||
23. dataTypeNchar.js
|
||||
23.1 supports NCHAR data type
|
||||
23.2 resultSet supports NCHAR data type
|
||||
23.3 stores null value correctly
|
||||
|
||||
24. dataTypeVarchar2.js
|
||||
24.1 supports VARCHAR2 data in various lengths
|
||||
24.2 resultSet stores VARCHAR2 data correctly
|
||||
24.3 stores null value correctly
|
||||
|
||||
25. dataTypeNvarchar2.js
|
||||
25.1 supports NVARCHAR2 data in various lengths
|
||||
25.2 resultSet stores NVARCHAR2 data correctly
|
||||
25.3 stores null value correctly
|
||||
|
||||
26. dataTypeNumber.js
|
||||
26.1 supports NUMBER data type
|
||||
26.2 resultSet stores NUMBER data correctly
|
||||
26.3 stores null value correctly
|
||||
|
||||
27. dataTypeNumber2.js
|
||||
27.1 supports NUMBER(p, s) data type
|
||||
27.2 resultSet stores NUMBER(p, s) data correctly
|
||||
27.3 stores null value correctly
|
||||
|
||||
28. dataTypeFloat.js
|
||||
28.1 supports FLOAT data type
|
||||
28.2 resultSet stores FLOAT data correctly
|
||||
28.3 stores null value correctly
|
||||
|
||||
29. dataTypeFloat2.js
|
||||
29.1 supports FLOAT(p) data type
|
||||
29.2 resultSet stores FLOAT(p) data correctly
|
||||
29.3 stores null value correctly
|
||||
|
||||
30. dataTypeBinaryFloat.js
|
||||
- supports BINARY_FLOAT data type
|
||||
|
||||
31. dataTypeBinaryDouble.js
|
||||
- supports BINARY_DOUBLE data type
|
||||
|
||||
32. dataTypeDate.js
|
||||
32.1 supports DATE data type
|
||||
32.2 resultSet stores DATE data correctly
|
||||
32.3 stores null value correctly
|
||||
|
||||
33. dataTypeTimestamp1.js
|
||||
33.1 supports TIMESTAMP data type
|
||||
33.2 resultSet stores TIMESTAMP data correctly
|
||||
33.3 stores null value correctly
|
||||
|
||||
34. dataTypeTimestamp2.js
|
||||
34.1 supports TIMESTAMP(p) data type
|
||||
34.2 resultSet stores TIMESTAMP data correctly
|
||||
34.3 stores null value correctly
|
||||
|
||||
35. dataTypeTimestamp3.js
|
||||
supports TIMESTAMP WITH TIME ZONE data type
|
||||
|
||||
36. dataTypeTimestamp4.js
|
||||
supports TIMESTAMP WITH TIME ZONE data type
|
||||
|
||||
37. dataTypeTimestamp5.js
|
||||
37.1 supports TIMESTAMP WITH LOCAL TIME ZONE data type
|
||||
37.2 resultSet stores TIMESTAMP WITH LOCAL TIME ZONE data correctly
|
||||
37.3 stores null value correctly
|
||||
|
||||
38. dataTypeTimestamp6.js
|
||||
38.1 supports TIMESTAMP(9) WITH LOCAL TIME ZONE data type
|
||||
38.2 resultSet stores TIMESTAMP(9) WITH LOCAL TIME ZONE data correctly
|
||||
38.3 stores null value correctly
|
||||
|
||||
39. dataTypeRowid.js
|
||||
39.1 supports ROWID data type
|
||||
|
||||
40. dataTypeClob.js
|
||||
40.1 processes null value correctly
|
||||
40.2 stores CLOB value correctly
|
||||
|
||||
41. dataTypeBlob
|
||||
41.1 processes null value correctly
|
||||
41.2 stores BLOB value correctly
|
||||
|
||||
51. accessTerminatedPoolAttributes.js
|
||||
can not access attributes of terminated pool
|
||||
|
||||
52. getConnAfterPoolTerminate.js
|
||||
can not get connections from pool after pool is terminated
|
||||
|
||||
53. poolValidityAfterFailingTernimate.js
|
||||
pool should be available after failing terminate
|
||||
|
||||
54. releaseAfterFailingTerminate.js
|
||||
can still release connections after failing pool termination
|
||||
|
||||
55. resultSet2.js
|
||||
55.1 query a RDBMS function
|
||||
55.1.1 LPAD function
|
||||
55.2 binding variables
|
||||
55.2.1 query with one binding variable
|
||||
55.3 alternating getRow() & getRows() function
|
||||
55.3.1 result set
|
||||
55.3.2 REF Cursor
|
||||
55.4 release connection before close resultSet
|
||||
55.4.1 result set
|
||||
55.4.2 REF Cursor
|
||||
55.5 the content of resultSet should be consistent
|
||||
55.5.1 (1) get RS (2) modify data in that table and commit (3) check RS
|
||||
55.6 access resultSet simultaneously
|
||||
55.6.1 concurrent operations on resultSet are not allowed
|
||||
55.6.2 concurrent operation on REF Cursor are not allowed
|
||||
55.7 getting multiple resultSets
|
||||
55.7.1 can access multiple resultSet on one connection
|
||||
55.7.2 can access multiple REF Cursor
|
||||
55.8 Negative - resultSet is only for query statement
|
||||
55.8.1 resultSet cannot be returned for non-query statements
|
||||
55.9 test querying a PL/SQL function
|
||||
55.9.1
|
||||
55.10 calls getRows() once and then close RS before getting more rows
|
||||
55.10.1
|
||||
|
||||
56. fetchAs.js
|
||||
56.1 FetchAs - DATE type as STRING
|
||||
56.2 FetchAs NUMBER & DATE type as STRING
|
||||
56.3 FetchAs Oracledb property by-type
|
||||
56.4 FetchAs override oracledb by-type (for DATE) at execute time
|
||||
|
||||
57. nestedCursor.js
|
||||
57.1 testing nested cursor support - result set
|
||||
57.2 testing nested cursor support - REF Cursor
|
|
@ -0,0 +1,303 @@
|
|||
/* Copyright (c) 2015, 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
|
||||
* 57. nestedCursor.js
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Testing nested cursor.
|
||||
*
|
||||
* NUMBERING RULE
|
||||
* Test numbers follow this numbering rule:
|
||||
* 1 - 20 are reserved for basic functional tests
|
||||
* 21 - 50 are reserved for data type supporting tests
|
||||
* 51 onwards are for other tests
|
||||
*
|
||||
*****************************************************************************/
|
||||
"use strict";
|
||||
|
||||
var oracledb = require('oracledb');
|
||||
var should = require('should');
|
||||
var async = require('async');
|
||||
var dbConfig = require('./dbConfig.js');
|
||||
|
||||
describe('57. nestedCursor.js', function() {
|
||||
|
||||
if(dbConfig.externalAuth){
|
||||
var credential = { externalAuth: true, connectString: dbConfig.connectString };
|
||||
} else {
|
||||
var credential = dbConfig;
|
||||
}
|
||||
|
||||
var createParentTable =
|
||||
"BEGIN \
|
||||
DECLARE \
|
||||
e_table_exists EXCEPTION; \
|
||||
PRAGMA EXCEPTION_INIT(e_table_exists, -00942); \
|
||||
BEGIN \
|
||||
EXECUTE IMMEDIATE ('DROP TABLE test_parent_tab'); \
|
||||
EXCEPTION \
|
||||
WHEN e_table_exists \
|
||||
THEN NULL; \
|
||||
END; \
|
||||
EXECUTE IMMEDIATE (' \
|
||||
CREATE TABLE test_parent_tab ( \
|
||||
id NUMBER, \
|
||||
description VARCHAR2(32), \
|
||||
CONSTRAINT parent_tab_pk PRIMARY KEY (id) \
|
||||
) \
|
||||
'); \
|
||||
EXECUTE IMMEDIATE (' \
|
||||
INSERT INTO test_parent_tab (id, description) \
|
||||
VALUES \
|
||||
(1,''Parent 1'') \
|
||||
'); \
|
||||
EXECUTE IMMEDIATE (' \
|
||||
INSERT INTO test_parent_tab (id, description) \
|
||||
VALUES \
|
||||
(2,''Parent 2'') \
|
||||
'); \
|
||||
EXECUTE IMMEDIATE (' \
|
||||
INSERT INTO test_parent_tab (id, description) \
|
||||
VALUES \
|
||||
(3,''Parent 3'') \
|
||||
'); \
|
||||
END; ";
|
||||
|
||||
var createChildTable =
|
||||
"BEGIN \
|
||||
DECLARE \
|
||||
e_table_exists EXCEPTION; \
|
||||
PRAGMA EXCEPTION_INIT(e_table_exists, -00942); \
|
||||
BEGIN \
|
||||
EXECUTE IMMEDIATE ('DROP TABLE test_child_tab'); \
|
||||
EXCEPTION \
|
||||
WHEN e_table_exists \
|
||||
THEN NULL; \
|
||||
END; \
|
||||
EXECUTE IMMEDIATE (' \
|
||||
CREATE TABLE test_child_tab ( \
|
||||
id NUMBER, \
|
||||
parent_id NUMBER, \
|
||||
description VARCHAR2(32), \
|
||||
CONSTRAINT child_tab_pk PRIMARY KEY (id), \
|
||||
CONSTRAINT child_parent_fk FOREIGN KEY (parent_id) REFERENCES test_parent_tab(id) \
|
||||
) \
|
||||
'); \
|
||||
EXECUTE IMMEDIATE (' \
|
||||
INSERT INTO test_child_tab (id, parent_id, description) \
|
||||
VALUES \
|
||||
(1, 1, ''Child 1'') \
|
||||
'); \
|
||||
EXECUTE IMMEDIATE (' \
|
||||
INSERT INTO test_child_tab (id, parent_id, description) \
|
||||
VALUES \
|
||||
(2, 1, ''Child 2'') \
|
||||
'); \
|
||||
EXECUTE IMMEDIATE (' \
|
||||
INSERT INTO test_child_tab (id, parent_id, description) \
|
||||
VALUES \
|
||||
(3, 2, ''Child 3'') \
|
||||
'); \
|
||||
EXECUTE IMMEDIATE (' \
|
||||
INSERT INTO test_child_tab (id, parent_id, description) \
|
||||
VALUES \
|
||||
(4, 2, ''Child 4'') \
|
||||
'); \
|
||||
EXECUTE IMMEDIATE (' \
|
||||
INSERT INTO test_child_tab (id, parent_id, description) \
|
||||
VALUES \
|
||||
(5, 2, ''Child 5'') \
|
||||
'); \
|
||||
EXECUTE IMMEDIATE (' \
|
||||
INSERT INTO test_child_tab (id, parent_id, description) \
|
||||
VALUES \
|
||||
(6, 3, ''Child 6'') \
|
||||
'); \
|
||||
END; ";
|
||||
|
||||
var cursorExpr =
|
||||
"CREATE OR REPLACE PROCEDURE cursor_parent_child (p_out OUT SYS_REFCURSOR) \
|
||||
AS \
|
||||
BEGIN \
|
||||
OPEN p_out FOR \
|
||||
SELECT p ";
|
||||
|
||||
var connection = false;
|
||||
before(function(done) {
|
||||
async.series([
|
||||
function(callback) {
|
||||
oracledb.getConnection(
|
||||
credential,
|
||||
function(err, conn) {
|
||||
connection = conn;
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.should.be.ok;
|
||||
connection.execute(
|
||||
createParentTable,
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.should.be.ok;
|
||||
connection.execute(
|
||||
createChildTable,
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
}
|
||||
], done);
|
||||
|
||||
})
|
||||
|
||||
after(function(done) {
|
||||
async.series([
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"DROP TABLE test_child_tab",
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"DROP TABLE test_parent_tab",
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.release( function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
], done);
|
||||
})
|
||||
|
||||
function fetchOneRowFromRS(rs, cb) {
|
||||
rs.getRow(function(err, row) {
|
||||
if(err) {
|
||||
// console.error("Error at accessing RS: " + err.message);
|
||||
// NJS-010: unsupported data type in select list
|
||||
(err.message).should.startWith('NJS-010');
|
||||
rs.close(function(err) {
|
||||
should.not.exist(err);
|
||||
cb();
|
||||
});
|
||||
} else if(row) {
|
||||
console.log(row);
|
||||
fetchOneRowFromRS(rs, cb);
|
||||
} else {
|
||||
rs.close(function(err) {
|
||||
should.not.exist(err);
|
||||
cb();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
it('57.1 testing nested cursor support - result set', function(done) {
|
||||
connection.should.be.ok;
|
||||
|
||||
var sql =
|
||||
"SELECT p.description, \
|
||||
CURSOR( \
|
||||
SELECT c.description \
|
||||
FROM test_child_tab c \
|
||||
WHERE c.parent_id = p.id \
|
||||
) children \
|
||||
FROM test_parent_tab p";
|
||||
|
||||
connection.execute(
|
||||
sql,
|
||||
[],
|
||||
{ resultSet: true },
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
should.exist(result.resultSet);
|
||||
fetchOneRowFromRS(result.resultSet, done);
|
||||
}
|
||||
);
|
||||
|
||||
})
|
||||
|
||||
it('57.2 testing nested cursor support - REF Cursor', function(done) {
|
||||
var testproc =
|
||||
"CREATE OR REPLACE PROCEDURE get_family_tree(p_out OUT SYS_REFCURSOR) \
|
||||
AS \
|
||||
BEGIN \
|
||||
OPEN p_out FOR \
|
||||
SELECT p.description, \
|
||||
CURSOR( \
|
||||
SELECT c.description \
|
||||
FROM test_child_tab c \
|
||||
WHERE c.parent_id = p.id \
|
||||
) children \
|
||||
FROM test_parent_tab p; \
|
||||
END; ";
|
||||
|
||||
async.series([
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
testproc,
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback){
|
||||
connection.execute(
|
||||
"BEGIN get_family_tree(:out); END;",
|
||||
{
|
||||
out: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||
},
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
fetchOneRowFromRS(result.outBinds.out, callback);
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"DROP PROCEDURE get_family_tree",
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
}
|
||||
], done);
|
||||
})
|
||||
})
|
|
@ -346,7 +346,7 @@ describe('12. resultSet1.js', function() {
|
|||
})
|
||||
|
||||
describe('12.3 Testing function getRows()', function() {
|
||||
it('12.3.1 retrived set is exactly the size of result', function(done) {
|
||||
it('12.3.1 retrieved set is exactly the size of result', function(done) {
|
||||
connection.should.be.ok;
|
||||
var nRows = rowsAmount;
|
||||
var accessCount = 0;
|
||||
|
@ -379,7 +379,7 @@ describe('12. resultSet1.js', function() {
|
|||
}
|
||||
})
|
||||
|
||||
it('12.3.2 retrived set is greater than the size of result', function(done) {
|
||||
it('12.3.2 retrieved set is greater than the size of result', function(done) {
|
||||
connection.should.be.ok;
|
||||
var nRows = rowsAmount * 2;
|
||||
var accessCount = 0;
|
||||
|
@ -412,7 +412,7 @@ describe('12. resultSet1.js', function() {
|
|||
}
|
||||
})
|
||||
|
||||
it('12.3.3 retrived set is half of the size of result', function(done) {
|
||||
it('12.3.3 retrieved set is half of the size of result', function(done) {
|
||||
connection.should.be.ok;
|
||||
var nRows = Math.ceil(rowsAmount/2);
|
||||
var accessCount = 0;
|
||||
|
@ -445,7 +445,7 @@ describe('12. resultSet1.js', function() {
|
|||
}
|
||||
})
|
||||
|
||||
it('12.3.4 retrived set is one tenth of the size of the result', function(done) {
|
||||
it('12.3.4 retrieved set is one tenth of the size of the result', function(done) {
|
||||
connection.should.be.ok;
|
||||
var nRows = Math.ceil(rowsAmount/10);
|
||||
var accessCount = 0;
|
||||
|
@ -550,7 +550,7 @@ describe('12. resultSet1.js', function() {
|
|||
}
|
||||
})
|
||||
|
||||
it('12.3.7 the size of retrived set can be set to 1', function(done) {
|
||||
it('12.3.7 the size of retrieved set can be set to 1', function(done) {
|
||||
connection.should.be.ok;
|
||||
var nRows = 1;
|
||||
var accessCount = 0;
|
||||
|
@ -1318,6 +1318,71 @@ describe('12. resultSet1.js', function() {
|
|||
});
|
||||
}
|
||||
})
|
||||
|
||||
it('12.7.2 maxRows option is ignored with REF Cursor', function(done) {
|
||||
connection.should.be.ok;
|
||||
var rowCount = 0;
|
||||
var queryAmount = 100;
|
||||
var proc =
|
||||
"CREATE OR REPLACE PROCEDURE get_emp_rs (p_in IN NUMBER, p_out OUT SYS_REFCURSOR) \
|
||||
AS \
|
||||
BEGIN \
|
||||
OPEN p_out FOR \
|
||||
SELECT * FROM oracledb_employees \
|
||||
WHERE employees_id <= p_in; \
|
||||
END; ";
|
||||
|
||||
async.series([
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
proc,
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"BEGIN get_emp_rs(:in, :out); END;",
|
||||
{
|
||||
in: queryAmount,
|
||||
out: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||
},
|
||||
{ maxRows: 10 },
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
fetchRowFromRS(result.outBinds.out, callback);
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"DROP PROCEDURE get_emp_rs",
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
}
|
||||
], done);
|
||||
|
||||
function fetchRowFromRS(rs, cb) {
|
||||
rs.getRow(function(err, row) {
|
||||
should.not.exist(err);
|
||||
if(row) {
|
||||
rowCount++;
|
||||
return fetchRowFromRS(rs, cb);
|
||||
} else {
|
||||
rs.close( function(err) {
|
||||
should.not.exist(err);
|
||||
rowCount.should.eql(queryAmount);
|
||||
cb();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
|
|
|
@ -31,13 +31,14 @@
|
|||
* 51 onwards are for other tests
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
"use strict";
|
||||
|
||||
var oracledb = require('oracledb');
|
||||
var should = require('should');
|
||||
var async = require('async');
|
||||
var dbConfig = require('./dbConfig.js');
|
||||
|
||||
describe('55 resultSet2.js', function() {
|
||||
describe('55. resultSet2.js', function() {
|
||||
|
||||
if(dbConfig.externalAuth){
|
||||
var credential = { externalAuth: true, connectString: dbConfig.connectString };
|
||||
|
@ -65,6 +66,7 @@ describe('55 resultSet2.js', function() {
|
|||
'); \
|
||||
END; ";
|
||||
|
||||
var rowsAmount = 300;
|
||||
var insertRows =
|
||||
"DECLARE \
|
||||
x NUMBER := 0; \
|
||||
|
@ -76,37 +78,89 @@ describe('55 resultSet2.js', function() {
|
|||
INSERT INTO oracledb_employees VALUES (x, n); \
|
||||
END LOOP; \
|
||||
END; ";
|
||||
var rowsAmount = 300;
|
||||
|
||||
|
||||
var proc =
|
||||
"CREATE OR REPLACE PROCEDURE get_emp_rs (p_in IN NUMBER, p_out OUT SYS_REFCURSOR) \
|
||||
AS \
|
||||
BEGIN \
|
||||
OPEN p_out FOR \
|
||||
SELECT * FROM oracledb_employees \
|
||||
WHERE employees_id > p_in; \
|
||||
END; ";
|
||||
|
||||
beforeEach(function(done) {
|
||||
oracledb.getConnection(credential, function(err, conn) {
|
||||
if(err) { console.error(err.message); return; }
|
||||
connection = conn;
|
||||
connection.execute(createTable, function(err) {
|
||||
if(err) { console.error(err.message); return; }
|
||||
async.series([
|
||||
function(callback) {
|
||||
oracledb.getConnection(
|
||||
credential,
|
||||
function(err, conn) {
|
||||
connection = conn;
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.should.be.ok;
|
||||
connection.execute(
|
||||
insertRows,
|
||||
createTable,
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
insertRows,
|
||||
[],
|
||||
{ autoCommit: true },
|
||||
function(err) {
|
||||
if(err) { console.error(err.message); return; }
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
proc,
|
||||
[],
|
||||
{ autoCommit: true },
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
}
|
||||
], done);
|
||||
})
|
||||
|
||||
afterEach(function(done) {
|
||||
connection.execute(
|
||||
'DROP TABLE oracledb_employees',
|
||||
function(err) {
|
||||
if(err) { console.error(err.message); return; }
|
||||
connection.release(function(err) {
|
||||
if(err) { console.error(err.message); return; }
|
||||
done();
|
||||
async.series([
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
'DROP TABLE oracledb_employees',
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
'DROP PROCEDURE get_emp_rs',
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.release( function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
);
|
||||
], done);
|
||||
})
|
||||
|
||||
describe('55.1 query a RDBMS function', function() {
|
||||
|
@ -174,8 +228,8 @@ describe('55 resultSet2.js', function() {
|
|||
|
||||
})
|
||||
|
||||
describe('55.3 alternating getRow() & getRows() function', function(done) {
|
||||
it('55.3.1', function(done) {
|
||||
describe('55.3 alternating getRow() & getRows() function', function() {
|
||||
it('55.3.1 result set', function(done) {
|
||||
connection.should.be.ok;
|
||||
var accessCount = 0;
|
||||
var numRows = 4;
|
||||
|
@ -229,11 +283,85 @@ describe('55 resultSet2.js', function() {
|
|||
}
|
||||
}
|
||||
})
|
||||
|
||||
it('55.3.2 REF Cursor', function(done) {
|
||||
connection.should.be.ok;
|
||||
var accessCount = 0;
|
||||
var numRows = 4;
|
||||
var flag = 1; // 1 - getRow(); 2 - getRows(); 3 - to close resultSet.
|
||||
|
||||
connection.execute(
|
||||
"BEGIN get_emp_rs(:in, :out); END;",
|
||||
{
|
||||
in: 200,
|
||||
out: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||
},
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
fetchRowFromRS(result.outBinds.out, done);
|
||||
}
|
||||
);
|
||||
|
||||
function fetchRowFromRS(rs, cb) {
|
||||
if(flag === 1) {
|
||||
rs.getRow(function(err, row) {
|
||||
should.not.exist(err);
|
||||
if(row) {
|
||||
flag = 2;
|
||||
accessCount++;
|
||||
return fetchRowFromRS(rs, cb);
|
||||
} else {
|
||||
flag = 3;
|
||||
return fetchRowFromRS(rs, cb);
|
||||
}
|
||||
});
|
||||
}
|
||||
else if(flag === 2) {
|
||||
rs.getRows(numRows, function(err, rows) {
|
||||
should.not.exist(err);
|
||||
if(rows.length > 0) {
|
||||
flag = 1;
|
||||
accessCount++;
|
||||
return fetchRowFromRS(rs, cb);
|
||||
} else {
|
||||
flag = 3;
|
||||
return fetchRowFromRS(rs, cb);
|
||||
}
|
||||
});
|
||||
}
|
||||
else if(flag === 3) {
|
||||
// console.log("resultSet is empty!");
|
||||
rs.close(function(err) {
|
||||
should.not.exist(err);
|
||||
// console.log("Total access count is " + accessCount);
|
||||
accessCount.should.be.exactly((100/(numRows + 1)) * 2);
|
||||
cb();
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('55.4 release connetion before close resultSet', function() {
|
||||
describe('55.4 release connection before close resultSet', function() {
|
||||
var conn2 = false;
|
||||
before(function(done) {
|
||||
function fetchRowFromRS(rs, cb) {
|
||||
rs.getRow(function(err, row) {
|
||||
if(row) {
|
||||
return fetchRowFromRS(rs, cb);
|
||||
} else {
|
||||
conn2.release(function(err) {
|
||||
should.not.exist(err);
|
||||
rs.close(function(err) {
|
||||
should.exist(err);
|
||||
err.message.should.startWith('NJS-003'); // invalid connection
|
||||
cb();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
beforeEach(function(done) {
|
||||
oracledb.getConnection(
|
||||
credential,
|
||||
function(err, conn) {
|
||||
|
@ -244,7 +372,7 @@ describe('55 resultSet2.js', function() {
|
|||
);
|
||||
})
|
||||
|
||||
it('55.4.1 ', function(done) {
|
||||
it('55.4.1 result set', function(done) {
|
||||
conn2.should.be.ok;
|
||||
conn2.execute(
|
||||
"SELECT * FROM oracledb_employees",
|
||||
|
@ -252,28 +380,25 @@ describe('55 resultSet2.js', function() {
|
|||
{ resultSet: true },
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
fetchRowFromRS(result.resultSet);
|
||||
fetchRowFromRS(result.resultSet, done);
|
||||
}
|
||||
);
|
||||
})
|
||||
|
||||
it('55.4.2 REF Cursor', function(done) {
|
||||
conn2.should.be.ok;
|
||||
|
||||
function fetchRowFromRS(rs) {
|
||||
rs.getRow(function(err, row) {
|
||||
conn2.execute(
|
||||
"BEGIN get_emp_rs(:in, :out); END;",
|
||||
{
|
||||
in: 200,
|
||||
out: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||
},
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
if(row) {
|
||||
return fetchRowFromRS(rs);
|
||||
} else {
|
||||
conn2.release(function(err) {
|
||||
should.not.exist(err);
|
||||
rs.close(function(err) {
|
||||
should.exist(err);
|
||||
err.message.should.startWith('NJS-003');
|
||||
done();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
fetchRowFromRS(result.outBinds.out, done);
|
||||
}
|
||||
);
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -312,13 +437,13 @@ describe('55 resultSet2.js', function() {
|
|||
], done);
|
||||
|
||||
function fetchRowFromRS(rset, cb) {
|
||||
rs.getRow(function(err, row) {
|
||||
rset.getRow(function(err, row) {
|
||||
should.not.exist(err);
|
||||
if(row) {
|
||||
rowsCount++;
|
||||
return fetchRowFromRS(rset, cb);
|
||||
} else {
|
||||
rs.close(function(err) {
|
||||
rset.close(function(err) {
|
||||
should.not.exist(err);
|
||||
rowsCount.should.eql(rowsAmount);
|
||||
cb();
|
||||
|
@ -328,14 +453,45 @@ describe('55 resultSet2.js', function() {
|
|||
}
|
||||
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe('55.6 access resultSet simultaneously', function() {
|
||||
var numRows = 10; // number of rows to return from each call to getRows()
|
||||
|
||||
function fetchRowFromRS(rs, cb) {
|
||||
rs.getRow(function(err, row) {
|
||||
if(err) {
|
||||
cb(err);
|
||||
return;
|
||||
} else {
|
||||
if(row) {
|
||||
return fetchRowFromRS(rs, cb);
|
||||
} else {
|
||||
cb();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function fetchRowsFromRS(rs, cb) {
|
||||
rs.getRows(numRows, function(err, rows) {
|
||||
if(err) {
|
||||
cb(err);
|
||||
return;
|
||||
} else {
|
||||
if(rows.length > 0) {
|
||||
return fetchRowsFromRS(rs, cb);
|
||||
} else {
|
||||
cb();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
it('55.6.1 concurrent operations on resultSet are not allowed', function(done) {
|
||||
connection.should.be.ok;
|
||||
var rowCount1 = 0;
|
||||
var rowCount2 = 0;
|
||||
var numRows = 10; // number of rows to return from each call to getRows()
|
||||
|
||||
connection.execute(
|
||||
"SELECT * FROM oracledb_employees",
|
||||
[],
|
||||
|
@ -364,49 +520,80 @@ describe('55 resultSet2.js', function() {
|
|||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
function fetchRowFromRS(rs, cb) {
|
||||
rs.getRow(function(err, row) {
|
||||
if(err) {
|
||||
cb(err);
|
||||
return;
|
||||
} else {
|
||||
if(row) {
|
||||
rowCount1++;
|
||||
return fetchRowFromRS(rs, cb);
|
||||
} else {
|
||||
cb();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function fetchRowsFromRS(rs, cb) {
|
||||
rs.getRows(numRows, function(err, rows) {
|
||||
//should.not.exist(err);
|
||||
if(err) {
|
||||
cb(err);
|
||||
return;
|
||||
} else {
|
||||
if(rows.length > 0) {
|
||||
rowCount2 += 10;
|
||||
return fetchRowsFromRS(rs, cb);
|
||||
} else {
|
||||
cb();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
})
|
||||
|
||||
it('55.6.2 concurrent operation on REF Cursor are not allowed', function(done) {
|
||||
connection.should.be.ok;
|
||||
|
||||
connection.execute(
|
||||
"BEGIN get_emp_rs(:in, :out); END;",
|
||||
{
|
||||
in: 0,
|
||||
out: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||
},
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
async.parallel([
|
||||
function(callback) {
|
||||
fetchRowFromRS(result.outBinds.out, callback);
|
||||
},
|
||||
function(callback) {
|
||||
fetchRowsFromRS(result.outBinds.out, callback);
|
||||
}
|
||||
], function(err) {
|
||||
if(err) {
|
||||
// console.log(err);
|
||||
err.message.should.startWith('NJS-017');
|
||||
result.outBinds.out.close(function(err) {
|
||||
done();
|
||||
});
|
||||
} else {
|
||||
result.outBinds.out.close(function(error) {
|
||||
should.not.exist(error);
|
||||
done();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe('55.7 getting multiple resultSets', function() {
|
||||
var numRows = 10; // number of rows to return from each call to getRows()
|
||||
|
||||
function fetchRowFromRS(rs, cb) {
|
||||
rs.getRow(function(err, row) {
|
||||
should.not.exist(err);
|
||||
if(row) {
|
||||
return fetchRowFromRS(rs, cb);
|
||||
} else {
|
||||
rs.close(function(err) {
|
||||
should.not.exist(err);
|
||||
cb();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function fetchRowsFromRS(rs, cb) {
|
||||
rs.getRows(numRows, function(err, rows) {
|
||||
should.not.exist(err);
|
||||
if(rows.length > 0) {
|
||||
return fetchRowsFromRS(rs, cb);
|
||||
} else {
|
||||
rs.close(function(err) {
|
||||
should.not.exist(err);
|
||||
cb();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
it('55.7.1 can access multiple resultSet on one connection', function(done) {
|
||||
connection.should.be.ok;
|
||||
var rowCount1 = 0;
|
||||
var rowCount2 = 0;
|
||||
var numRows = 10; // number of rows to return from each call to getRows()
|
||||
async.parallel([
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
|
@ -434,37 +621,42 @@ describe('55 resultSet2.js', function() {
|
|||
should.not.exist(err);
|
||||
done();
|
||||
});
|
||||
})
|
||||
|
||||
it('55.7.2 can access multiple REF Cursor', function(done) {
|
||||
connection.should.be.ok;
|
||||
|
||||
function fetchRowFromRS(rs, cb) {
|
||||
rs.getRow(function(err, row) {
|
||||
should.not.exist(err);
|
||||
if(row) {
|
||||
rowCount1++;
|
||||
return fetchRowFromRS(rs, cb);
|
||||
} else {
|
||||
rs.close(function(err) {
|
||||
async.parallel([
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"BEGIN get_emp_rs(:in, :out); END;",
|
||||
{
|
||||
in: 200,
|
||||
out: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||
},
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
cb();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function fetchRowsFromRS(rs, cb) {
|
||||
rs.getRows(numRows, function(err, rows) {
|
||||
should.not.exist(err);
|
||||
if(rows.length > 0) {
|
||||
rowCount2 += numRows;
|
||||
return fetchRowsFromRS(rs, cb);
|
||||
} else {
|
||||
rs.close(function(err) {
|
||||
fetchRowFromRS(result.outBinds.out, callback);
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"BEGIN get_emp_rs(:in, :out); END;",
|
||||
{
|
||||
in: 100,
|
||||
out: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||
},
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
cb();
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
fetchRowsFromRS(result.outBinds.out, callback);
|
||||
}
|
||||
);
|
||||
}
|
||||
], function(err) {
|
||||
should.not.exist(err);
|
||||
done();
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -486,23 +678,155 @@ describe('55 resultSet2.js', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('55.9 test querying a PL/SQL function', function() {
|
||||
it('55.9.1 ', function(done) {
|
||||
var proc =
|
||||
"CREATE OR REPLACE FUNCTION testfunc RETURN VARCHAR2 \
|
||||
IS \
|
||||
emp_name VARCHAR2(20); \
|
||||
BEGIN \
|
||||
SELECT 'Clark Kent' INTO emp_name FROM dual; \
|
||||
RETURN emp_name; \
|
||||
END; ";
|
||||
|
||||
async.series([
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
proc,
|
||||
function(err) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"SELECT testfunc FROM dual",
|
||||
[],
|
||||
{ resultSet: true },
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
(result.resultSet.metaData[0].name).should.eql('TESTFUNC');
|
||||
fetchRowFromRS(result.resultSet, callback);
|
||||
}
|
||||
);
|
||||
},
|
||||
function(callback) {
|
||||
connection.execute(
|
||||
"DROP FUNCTION testfunc",
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
}
|
||||
], done);
|
||||
|
||||
function fetchRowFromRS(rs, cb) {
|
||||
rs.getRow(function(err, row) {
|
||||
should.not.exist(err);
|
||||
if(row) {
|
||||
row[0].should.eql('Clark Kent');
|
||||
return fetchRowFromRS(rs, cb);
|
||||
} else {
|
||||
rs.close(function(err) {
|
||||
should.not.exist(err);
|
||||
cb();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('55.10 calls getRows() once and then close RS before getting more rows', function() {
|
||||
it('55.10.1 ', function(done) {
|
||||
connection.should.be.ok;
|
||||
var numRows = 10;
|
||||
var closeRS = true;
|
||||
connection.execute(
|
||||
"SELECT * FROM oracledb_employees",
|
||||
[],
|
||||
{ resultSet: true },
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
result.resultSet.getRows(
|
||||
numRows,
|
||||
function(err, rows) {
|
||||
should.not.exist(err);
|
||||
result.resultSet.close(function(err) {
|
||||
should.not.exist(err);
|
||||
fetchRowsFromRS(result.resultSet, numRows, done);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
function fetchRowsFromRS(rs, numRows, done) {
|
||||
rs.getRows(numRows, function(err, rows) {
|
||||
should.exist(err);
|
||||
err.message.should.startWith('NJS-018:'); // invalid result set
|
||||
done();
|
||||
});
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('55.11 deals with unsupported database with result set', function() {
|
||||
var sql1 = "select dummy, HEXTORAW('0123456789ABCDEF0123456789ABCDEF') from dual";
|
||||
var sql2 = "SELECT dummy, rowid FROM dual";
|
||||
|
||||
function fetchOneRowFromRS(rs, cb) {
|
||||
rs.getRow(function(err, row) {
|
||||
/* Currently, even if the driver doesn't support certain data type
|
||||
* the result set can still be created.
|
||||
*/
|
||||
// Error at accessing RS
|
||||
if(err) {
|
||||
// console.error("Error at accessing RS: " + err.message);
|
||||
// NJS-010: unsupported data type in select list
|
||||
(err.message).should.startWith('NJS-010');
|
||||
rs.close( function(err) {
|
||||
should.not.exist(err);
|
||||
cb();
|
||||
});
|
||||
} else if(row) {
|
||||
console.log(row);
|
||||
fetchOneRowFromRS(rs, cb);
|
||||
} else {
|
||||
rs.close( function(err) {
|
||||
should.not.exist(err);
|
||||
cb();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
it('55.11.1 RAW data type', function(done) {
|
||||
connection.should.be.ok;
|
||||
connection.execute(
|
||||
sql1,
|
||||
[],
|
||||
{ resultSet: true },
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
fetchOneRowFromRS(result.resultSet, done);
|
||||
}
|
||||
);
|
||||
})
|
||||
|
||||
it('55.11.2 ROWID date type', function(done) {
|
||||
connection.execute(
|
||||
sql2,
|
||||
[],
|
||||
{ resultSet: true },
|
||||
function(err, result) {
|
||||
should.not.exist(err);
|
||||
fetchOneRowFromRS(result.resultSet, done);
|
||||
}
|
||||
);
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue