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
|
install` will install them when executed inside a node-oracledb
|
||||||
package directory.
|
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
|
vi <some-directory>/node_modules/oracledb/test/dbConfig.js
|
||||||
```
|
```
|
||||||
|
|
||||||
Change the credentials to a user who has privileges to connect and create tables:
|
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
module.exports = {
|
module.exports = {
|
||||||
user : "hr",
|
user : process.env.NODE_ORACLEDB_USER || "hr",
|
||||||
password : "welcome",
|
password : process.env.NODE_ORACLEDB_PASSWORD || "welcome",
|
||||||
connectString : "localhost/orcl",
|
connectString : process.env.NODE_ORACLEDB_CONNECTIONSTRING || "localhost/orcl",
|
||||||
externalAuth : false
|
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
|
- 1 - 20 are reserved for basic functional tests
|
||||||
- 21 - 50 are reserved for data type supporting tests
|
- 21 - 50 are reserved for data type supporting tests
|
||||||
- 51 onwards are for other 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
|
* 51 - are for other tests
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
"use strict";
|
||||||
|
|
||||||
var oracledb = require('oracledb');
|
var oracledb = require('oracledb');
|
||||||
var should = require('should');
|
var should = require('should');
|
||||||
var async = require('async');
|
var async = require('async');
|
||||||
var dbConfig = require('./dbConfig.js');
|
var dbConfig = require('./dbConfig.js');
|
||||||
|
|
||||||
describe('7. autoCommit.js', function(){
|
describe('7. autoCommit.js', function() {
|
||||||
|
|
||||||
if(dbConfig.externalAuth){
|
if(dbConfig.externalAuth){
|
||||||
var credential = { externalAuth: true, connectString: dbConfig.connectString };
|
var credential = { externalAuth: true, connectString: dbConfig.connectString };
|
||||||
} else {
|
} else {
|
||||||
var credential = dbConfig;
|
var credential = dbConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
var connection = false;
|
var pool = null;
|
||||||
var anotherConnection = false;
|
var connection = null;
|
||||||
var script =
|
|
||||||
"BEGIN \
|
before('create pool, get one connection, create table', function(done) {
|
||||||
DECLARE \
|
var script =
|
||||||
e_table_exists EXCEPTION; \
|
"BEGIN \
|
||||||
PRAGMA EXCEPTION_INIT(e_table_exists, -00942); \
|
DECLARE \
|
||||||
BEGIN \
|
e_table_exists EXCEPTION; \
|
||||||
EXECUTE IMMEDIATE ('DROP TABLE oracledb_departments'); \
|
PRAGMA EXCEPTION_INIT(e_table_exists, -00942); \
|
||||||
EXCEPTION \
|
BEGIN \
|
||||||
WHEN e_table_exists \
|
EXECUTE IMMEDIATE ('DROP TABLE oracledb_departments'); \
|
||||||
THEN NULL; \
|
EXCEPTION \
|
||||||
END; \
|
WHEN e_table_exists \
|
||||||
EXECUTE IMMEDIATE (' \
|
THEN NULL; \
|
||||||
CREATE TABLE oracledb_departments ( \
|
END; \
|
||||||
department_id NUMBER, \
|
EXECUTE IMMEDIATE (' \
|
||||||
department_name VARCHAR2(20) \
|
CREATE TABLE oracledb_departments ( \
|
||||||
) \
|
department_id NUMBER, \
|
||||||
'); \
|
department_name VARCHAR2(20) \
|
||||||
END; ";
|
) \
|
||||||
|
'); \
|
||||||
beforeEach(function(done){
|
END; ";
|
||||||
oracledb.outFormat = oracledb.OBJECT;
|
|
||||||
oracledb.autoCommit = true;
|
|
||||||
|
|
||||||
async.series([
|
async.series([
|
||||||
function(callback){
|
function(callback) {
|
||||||
oracledb.getConnection(credential, function(err, conn){
|
oracledb.createPool(
|
||||||
if(err) { console.error(err.message); return; }
|
{
|
||||||
connection = conn;
|
externalAuth : credential.externalAuth,
|
||||||
callback();
|
user : credential.user,
|
||||||
});
|
password : credential.password,
|
||||||
},
|
connectString : credential.connectString,
|
||||||
function(callback){
|
poolMin : 3,
|
||||||
oracledb.getConnection(credential, function(err, conn){
|
poolMax : 7,
|
||||||
if(err) { console.error(err.message); return; }
|
poolIncrement : 1
|
||||||
anotherConnection = conn;
|
},
|
||||||
callback();
|
function(err, connectionPool) {
|
||||||
});
|
should.not.exist(err);
|
||||||
},
|
pool = connectionPool;
|
||||||
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; }
|
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
function(callback){
|
function(callback) {
|
||||||
connection.release( function(err){
|
pool.getConnection( function(err, conn) {
|
||||||
if(err) { console.error(err.message); return; }
|
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();
|
callback();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function(callback){
|
function(callback) {
|
||||||
anotherConnection.release( function(err){
|
pool.terminate(function(err) {
|
||||||
if(err) { console.error(err.message); return; }
|
should.not.exist(err);
|
||||||
callback();
|
callback();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
], done);
|
], 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([
|
async.series([
|
||||||
function(callback){
|
function(callback) {
|
||||||
connection.execute(
|
pool.getConnection(
|
||||||
|
function(err, conn) {
|
||||||
|
should.not.exist(err);
|
||||||
|
conn1 = conn;
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
function(callback) {
|
||||||
|
conn1.execute(
|
||||||
"INSERT INTO oracledb_departments VALUES (82, 'Security')",
|
"INSERT INTO oracledb_departments VALUES (82, 'Security')",
|
||||||
function(err){
|
function(err) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
function(callback){
|
function(callback) { // get another connection
|
||||||
anotherConnection.execute(
|
pool.getConnection(
|
||||||
"SELECT department_id FROM oracledb_departments WHERE department_name = 'Security'",
|
function(err, conn) {
|
||||||
function(err, result){
|
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.not.exist(err);
|
||||||
should.exist(result);
|
|
||||||
// console.log(result);
|
|
||||||
result.rows[0].DEPARTMENT_ID.should.eql(82).and.be.a.Number;
|
result.rows[0].DEPARTMENT_ID.should.eql(82).and.be.a.Number;
|
||||||
callback();
|
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){
|
function(callback) {
|
||||||
connection.execute(
|
conn1.execute(
|
||||||
"UPDATE oracledb_departments SET department_id = 101 WHERE department_name = 'Security'",
|
"UPDATE oracledb_departments SET department_id = 101 WHERE department_name = 'Security'",
|
||||||
function(err){
|
function(err){
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
|
@ -174,18 +200,206 @@ describe('7. autoCommit.js', function(){
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
function(callback){
|
function(callback) {
|
||||||
anotherConnection.execute(
|
conn2.execute(
|
||||||
"SELECT department_id FROM oracledb_departments WHERE department_name = 'Security'",
|
"SELECT department_id FROM oracledb_departments WHERE department_name = 'Security'",
|
||||||
function(err, result){
|
[],
|
||||||
|
{ outFormat: oracledb.OBJECT },
|
||||||
|
function(err, result) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
should.exist(result);
|
|
||||||
// console.log(result);
|
|
||||||
result.rows[0].DEPARTMENT_ID.should.eql(101).and.be.a.Number;
|
result.rows[0].DEPARTMENT_ID.should.eql(101).and.be.a.Number;
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
},
|
||||||
|
function(callback) {
|
||||||
|
conn1.release(function(err) {
|
||||||
|
should.not.exist(err);
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function(callback) {
|
||||||
|
conn2.release(function(err) {
|
||||||
|
should.not.exist(err);
|
||||||
|
callback();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
], done);
|
], 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 credential = dbConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
var connection = false;
|
describe('4.1 test STRING, NUMBER, ARRAY & JSON format', function() {
|
||||||
beforeEach(function(done) {
|
var connection = null;
|
||||||
oracledb.getConnection(credential, function(err, conn) {
|
before(function(done) {
|
||||||
if(err) { console.error(err.message); return; }
|
oracledb.getConnection(credential, function(err, conn) {
|
||||||
connection = conn;
|
if(err) { console.error(err.message); return; }
|
||||||
done();
|
connection = conn;
|
||||||
});
|
done();
|
||||||
})
|
});
|
||||||
|
})
|
||||||
|
|
||||||
afterEach(function(done) {
|
after(function(done) {
|
||||||
connection.release( function(err) {
|
connection.release( function(err) {
|
||||||
if(err) { console.error(err.message); return; }
|
if(err) { console.error(err.message); return; }
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('4.1.1 VARCHAR2 binding, Object & Array formats', function(done) {
|
||||||
it('4.1 VARCHAR2 binding, Object & Array formats', function(done) {
|
async.series([
|
||||||
async.series([
|
function(callback) {
|
||||||
function(callback) {
|
var proc = "CREATE OR REPLACE PROCEDURE oracledb_testproc (p_out OUT VARCHAR2) \
|
||||||
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) \
|
|
||||||
AS \
|
AS \
|
||||||
BEGIN \
|
BEGIN \
|
||||||
p_inout := p_in || ' ' || p_inout; \
|
p_out := 'abcdef'; \
|
||||||
p_out := 101; \
|
END;";
|
||||||
END; ";
|
connection.should.be.ok;
|
||||||
connection.should.be.ok;
|
connection.execute(
|
||||||
connection.execute(
|
proc,
|
||||||
proc,
|
function(err) {
|
||||||
function(err) {
|
should.not.exist(err);
|
||||||
should.not.exist(err);
|
callback();
|
||||||
callback();
|
}
|
||||||
}
|
);
|
||||||
);
|
},
|
||||||
},
|
function(callback) {
|
||||||
function(callback) {
|
connection.execute(
|
||||||
connection.execute(
|
"BEGIN oracledb_testproc(:o); END;",
|
||||||
"BEGIN oracledb_testproc(:i, :io, :o); END;",
|
{
|
||||||
{
|
o: { type: oracledb.STRING, dir: oracledb.BIND_OUT }
|
||||||
i: 'Alan', // bind type is determined from the data type
|
},
|
||||||
io: { val: 'Turing', dir : oracledb.BIND_INOUT },
|
function(err, result) {
|
||||||
o: { type: oracledb.NUMBER, dir : oracledb.BIND_OUT }
|
should.not.exist(err);
|
||||||
},
|
// console.log(result);
|
||||||
function(err, result) {
|
result.outBinds.o.should.be.exactly('abcdef');
|
||||||
should.not.exist(err);
|
callback();
|
||||||
// console.log(result);
|
}
|
||||||
result.outBinds.io.should.be.exactly('Alan Turing');
|
);
|
||||||
callback();
|
},
|
||||||
}
|
function(callback) {
|
||||||
);
|
connection.execute(
|
||||||
},
|
"BEGIN oracledb_testproc(:o); END;",
|
||||||
function(callback) {
|
[
|
||||||
connection.execute(
|
{ type: oracledb.STRING, dir: oracledb.BIND_OUT }
|
||||||
"BEGIN oracledb_testproc(:i, :io, :o); END;",
|
],
|
||||||
[
|
function(err, result) {
|
||||||
'Alan', // bind type is determined from the data type
|
should.not.exist(err);
|
||||||
{ val: 'Turing', dir : oracledb.BIND_INOUT },
|
// console.log(result);
|
||||||
{ type: oracledb.NUMBER, dir : oracledb.BIND_OUT }
|
result.outBinds.should.be.eql(['abcdef']);
|
||||||
],
|
callback();
|
||||||
function(err, result) {
|
}
|
||||||
should.not.exist(err);
|
);
|
||||||
// console.log(result);
|
},
|
||||||
result.outBinds.should.be.eql([ 'Alan Turing', 101 ]);
|
function(callback) {
|
||||||
callback();
|
connection.execute(
|
||||||
}
|
"DROP PROCEDURE oracledb_testproc",
|
||||||
);
|
function(err) {
|
||||||
},
|
should.not.exist(err);
|
||||||
function(callback) {
|
callback();
|
||||||
connection.execute(
|
}
|
||||||
"DROP PROCEDURE oracledb_testproc",
|
);
|
||||||
function(err) {
|
}
|
||||||
should.not.exist(err);
|
], done);
|
||||||
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);
|
|
||||||
})
|
|
||||||
|
|
||||||
|
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);
|
], 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.should.be.ok;
|
||||||
connection.execute(
|
connection.execute(
|
||||||
"INSERT INTO oracledb_departments VALUES (99, 'FACILITY', 456, 1700)",
|
"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.should.be.ok;
|
||||||
connection.execute(
|
connection.execute(
|
||||||
query, {id: 20}, {outFormat:0 },
|
query, {id: 20}, {outFormat:0 },
|
||||||
|
@ -186,6 +186,7 @@ describe('1. connection.js', function(){
|
||||||
INSERT INTO oracledb_employees VALUES (x, n); \
|
INSERT INTO oracledb_employees VALUES (x, n); \
|
||||||
END LOOP; \
|
END LOOP; \
|
||||||
END; ";
|
END; ";
|
||||||
|
var rowsAmount = 107;
|
||||||
|
|
||||||
before(function(done){
|
before(function(done){
|
||||||
oracledb.getConnection(credential, function(err, conn) {
|
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(){
|
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 = {
|
var bindValues = {
|
||||||
i: 'Alan', // default is type STRING and direction Infinity
|
i: 'Alan', // default is type STRING and direction Infinity
|
||||||
io: { val: 'Turing', type: oracledb.STRING, dir: oracledb.BIND_INOUT },
|
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() {
|
describe('1.4 statementCacheSize controls statement caching', function() {
|
||||||
var connection = false;
|
|
||||||
|
|
||||||
var makeTable =
|
var makeTable =
|
||||||
"BEGIN \
|
"BEGIN \
|
||||||
DECLARE \
|
DECLARE \
|
||||||
|
@ -364,12 +376,12 @@ describe('1. connection.js', function(){
|
||||||
VALUES \
|
VALUES \
|
||||||
(2001, ''Karen Morton'') \
|
(2001, ''Karen Morton'') \
|
||||||
'); \
|
'); \
|
||||||
END; ";
|
END; ";
|
||||||
|
|
||||||
|
var connection = false;
|
||||||
var defaultStmtCache = oracledb.stmtCacheSize; // 30
|
var defaultStmtCache = oracledb.stmtCacheSize; // 30
|
||||||
|
|
||||||
before('get connection and prepare table', function(done) {
|
beforeEach('get connection and prepare table', function(done) {
|
||||||
oracledb.stmtCacheSize = 0;
|
|
||||||
oracledb.getConnection(credential, function(err, conn) {
|
oracledb.getConnection(credential, function(err, conn) {
|
||||||
if(err) { console.error(err.message); return; }
|
if(err) { console.error(err.message); return; }
|
||||||
connection = conn;
|
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;
|
oracledb.stmtCacheSize = defaultStmtCache;
|
||||||
connection.execute(
|
connection.execute(
|
||||||
"DROP TABLE oracledb_employees",
|
"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;
|
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([
|
async.series([
|
||||||
function(callback) {
|
function(callback) {
|
||||||
|
@ -437,11 +490,10 @@ describe('1. connection.js', function(){
|
||||||
}
|
}
|
||||||
], done);
|
], done);
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('1.5 stmtCacheSize > 0', function() {
|
describe('1.5 Testing commit() & rollback() functions', function() {
|
||||||
var connection = false;
|
|
||||||
|
|
||||||
var makeTable =
|
var makeTable =
|
||||||
"BEGIN \
|
"BEGIN \
|
||||||
DECLARE \
|
DECLARE \
|
||||||
|
@ -462,83 +514,39 @@ describe('1. connection.js', function(){
|
||||||
EXECUTE IMMEDIATE (' \
|
EXECUTE IMMEDIATE (' \
|
||||||
INSERT INTO oracledb_employees \
|
INSERT INTO oracledb_employees \
|
||||||
VALUES \
|
VALUES \
|
||||||
(1001,''Chris Jones'') \
|
(1001,''Tom Kyte'') \
|
||||||
'); \
|
'); \
|
||||||
EXECUTE IMMEDIATE (' \
|
EXECUTE IMMEDIATE (' \
|
||||||
INSERT INTO oracledb_employees \
|
INSERT INTO oracledb_employees \
|
||||||
VALUES \
|
VALUES \
|
||||||
(1002,''Tom Kyte'') \
|
(1002, ''Karen Morton'') \
|
||||||
'); \
|
'); \
|
||||||
EXECUTE IMMEDIATE (' \
|
END; ";
|
||||||
INSERT INTO oracledb_employees \
|
|
||||||
VALUES \
|
|
||||||
(2001, ''Karen Morton'') \
|
|
||||||
'); \
|
|
||||||
END; ";
|
|
||||||
|
|
||||||
var defaultStmtCache = oracledb.stmtCacheSize; // 30
|
var conn1 = false;
|
||||||
|
var conn2 = false;
|
||||||
before('get connection and prepare table', function(done) {
|
beforeEach('get 2 connections and create the 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);
|
|
||||||
|
|
||||||
async.series([
|
async.series([
|
||||||
function(callback) {
|
function(callback) {
|
||||||
connection.execute(
|
oracledb.getConnection(credential, function(err, conn) {
|
||||||
"INSERT INTO oracledb_employees VALUES (:num, :str)",
|
should.not.exist(err);
|
||||||
{ num: 1003, str: 'Robyn Sands' },
|
conn1 = conn;
|
||||||
{ autoCommit: true },
|
callback();
|
||||||
function(err) {
|
});
|
||||||
should.not.exist(err);
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
function(callback) {
|
function(callback) {
|
||||||
connection.execute(
|
oracledb.getConnection(credential, function(err, conn) {
|
||||||
"INSERT INTO oracledb_employees VALUES (:num, :str)",
|
should.not.exist(err);
|
||||||
{ num: 1004, str: 'Bryant Lin' },
|
conn2 = conn;
|
||||||
{ autoCommit: true },
|
callback();
|
||||||
function(err) {
|
});
|
||||||
should.not.exist(err);
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
function(callback) {
|
function(callback) {
|
||||||
connection.execute(
|
conn1.should.be.ok;
|
||||||
"INSERT INTO oracledb_employees VALUES (:num, :str)",
|
conn1.execute(
|
||||||
{ num: 1005, str: 'Patrick Engebresson' },
|
makeTable,
|
||||||
{ autoCommit: true },
|
[],
|
||||||
|
{ autoCommit: true },
|
||||||
function(err) {
|
function(err) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
callback();
|
callback();
|
||||||
|
@ -547,6 +555,138 @@ describe('1. connection.js', function(){
|
||||||
}
|
}
|
||||||
], done);
|
], 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;
|
connection.should.be.ok;
|
||||||
|
|
||||||
var timestamps = [
|
var timestamps = [
|
||||||
|
@ -126,12 +126,14 @@ describe('35. dataTypeTimestamp3.js', function() {
|
||||||
[],
|
[],
|
||||||
{ outFormat: oracledb.OBJECT },
|
{ outFormat: oracledb.OBJECT },
|
||||||
function(err, result) {
|
function(err, result) {
|
||||||
should.not.exist(err);
|
should.exist(err);
|
||||||
// console.log(result);
|
err.message.should.startWith('NJS-010:'); // unsupported data type in select list
|
||||||
|
/*
|
||||||
|
console.log(result);
|
||||||
for(var j = 0; j < timestamps.length; j++)
|
for(var j = 0; j < timestamps.length; j++)
|
||||||
result.rows[j].CONTENT.toUTCString().should.eql(timestamps[result.rows[j].NUM].toUTCString());
|
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;
|
connection.should.be.ok;
|
||||||
|
|
||||||
var timestamps = [
|
var timestamps = [
|
||||||
|
@ -126,12 +126,14 @@ describe('36. dataTypeTimestamp4.js', function() {
|
||||||
[],
|
[],
|
||||||
{ outFormat: oracledb.OBJECT },
|
{ outFormat: oracledb.OBJECT },
|
||||||
function(err, result) {
|
function(err, result) {
|
||||||
should.not.exist(err);
|
should.exist(err);
|
||||||
// console.log(result);
|
err.message.should.startWith('NJS-010:'); // unsupported data type in select list
|
||||||
|
/*
|
||||||
|
console.log(result);
|
||||||
for(var j = 0; j < timestamps.length; j++)
|
for(var j = 0; j < timestamps.length; j++)
|
||||||
result.rows[j].CONTENT.toUTCString().should.eql(timestamps[result.rows[j].NUM].toUTCString());
|
result.rows[j].CONTENT.toUTCString().should.eql(timestamps[result.rows[j].NUM].toUTCString());
|
||||||
|
*/
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
@ -31,8 +31,8 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
user : "hr",
|
user : process.env.NODE_ORACLEDB_USER || "hr",
|
||||||
password : "welcome",
|
password : process.env.NODE_ORACLEDB_PASSWORD || "welcome",
|
||||||
connectString : "localhost/orcl",
|
connectString : process.env.NODE_ORACLEDB_CONNECTIONSTRING || "localhost/orcl",
|
||||||
externalAuth : false
|
externalAuth : process.env.NODE_ORACLEDB_EXTERNALAUTH ? true : false
|
||||||
};
|
};
|
||||||
|
|
|
@ -157,7 +157,7 @@ describe('6. dmlReturning.js', function(){
|
||||||
{ autoCommit: true },
|
{ autoCommit: true },
|
||||||
function(err, result) {
|
function(err, result) {
|
||||||
should.exist(err);
|
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);
|
//console.log(result);
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
|
|
221
test/examples.js
221
test/examples.js
|
@ -510,17 +510,7 @@ describe('3. examples.js', function(){
|
||||||
|
|
||||||
describe('3.7 plsql.js', function(){
|
describe('3.7 plsql.js', function(){
|
||||||
var connection = false;
|
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){
|
before(function(done){
|
||||||
oracledb.getConnection(credential, function(err, conn){
|
oracledb.getConnection(credential, function(err, conn){
|
||||||
if(err) { console.error(err.message); return; }
|
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){
|
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([
|
async.series([
|
||||||
function(callback){
|
function(callback){
|
||||||
connection.execute(
|
connection.execute(
|
||||||
|
@ -570,6 +573,53 @@ describe('3. examples.js', function(){
|
||||||
}
|
}
|
||||||
], done);
|
], 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() {
|
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;
|
connection.should.be.ok;
|
||||||
var nRows = rowsAmount;
|
var nRows = rowsAmount;
|
||||||
var accessCount = 0;
|
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;
|
connection.should.be.ok;
|
||||||
var nRows = rowsAmount * 2;
|
var nRows = rowsAmount * 2;
|
||||||
var accessCount = 0;
|
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;
|
connection.should.be.ok;
|
||||||
var nRows = Math.ceil(rowsAmount/2);
|
var nRows = Math.ceil(rowsAmount/2);
|
||||||
var accessCount = 0;
|
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;
|
connection.should.be.ok;
|
||||||
var nRows = Math.ceil(rowsAmount/10);
|
var nRows = Math.ceil(rowsAmount/10);
|
||||||
var accessCount = 0;
|
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;
|
connection.should.be.ok;
|
||||||
var nRows = 1;
|
var nRows = 1;
|
||||||
var accessCount = 0;
|
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
|
* 51 onwards are for other tests
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
"use strict";
|
||||||
|
|
||||||
var oracledb = require('oracledb');
|
var oracledb = require('oracledb');
|
||||||
var should = require('should');
|
var should = require('should');
|
||||||
var async = require('async');
|
var async = require('async');
|
||||||
var dbConfig = require('./dbConfig.js');
|
var dbConfig = require('./dbConfig.js');
|
||||||
|
|
||||||
describe('55 resultSet2.js', function() {
|
describe('55. resultSet2.js', function() {
|
||||||
|
|
||||||
if(dbConfig.externalAuth){
|
if(dbConfig.externalAuth){
|
||||||
var credential = { externalAuth: true, connectString: dbConfig.connectString };
|
var credential = { externalAuth: true, connectString: dbConfig.connectString };
|
||||||
|
@ -65,6 +66,7 @@ describe('55 resultSet2.js', function() {
|
||||||
'); \
|
'); \
|
||||||
END; ";
|
END; ";
|
||||||
|
|
||||||
|
var rowsAmount = 300;
|
||||||
var insertRows =
|
var insertRows =
|
||||||
"DECLARE \
|
"DECLARE \
|
||||||
x NUMBER := 0; \
|
x NUMBER := 0; \
|
||||||
|
@ -76,37 +78,89 @@ describe('55 resultSet2.js', function() {
|
||||||
INSERT INTO oracledb_employees VALUES (x, n); \
|
INSERT INTO oracledb_employees VALUES (x, n); \
|
||||||
END LOOP; \
|
END LOOP; \
|
||||||
END; ";
|
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) {
|
beforeEach(function(done) {
|
||||||
oracledb.getConnection(credential, function(err, conn) {
|
async.series([
|
||||||
if(err) { console.error(err.message); return; }
|
function(callback) {
|
||||||
connection = conn;
|
oracledb.getConnection(
|
||||||
connection.execute(createTable, function(err) {
|
credential,
|
||||||
if(err) { console.error(err.message); return; }
|
function(err, conn) {
|
||||||
|
connection = conn;
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
function(callback) {
|
||||||
|
connection.should.be.ok;
|
||||||
connection.execute(
|
connection.execute(
|
||||||
insertRows,
|
createTable,
|
||||||
|
function(err) {
|
||||||
|
should.not.exist(err);
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
function(callback) {
|
||||||
|
connection.execute(
|
||||||
|
insertRows,
|
||||||
[],
|
[],
|
||||||
{ autoCommit: true },
|
{ autoCommit: true },
|
||||||
function(err) {
|
function(err) {
|
||||||
if(err) { console.error(err.message); return; }
|
should.not.exist(err);
|
||||||
done();
|
callback();
|
||||||
});
|
}
|
||||||
});
|
);
|
||||||
});
|
},
|
||||||
|
function(callback) {
|
||||||
|
connection.execute(
|
||||||
|
proc,
|
||||||
|
[],
|
||||||
|
{ autoCommit: true },
|
||||||
|
function(err) {
|
||||||
|
should.not.exist(err);
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
], done);
|
||||||
})
|
})
|
||||||
|
|
||||||
afterEach(function(done) {
|
afterEach(function(done) {
|
||||||
connection.execute(
|
async.series([
|
||||||
'DROP TABLE oracledb_employees',
|
function(callback) {
|
||||||
function(err) {
|
connection.execute(
|
||||||
if(err) { console.error(err.message); return; }
|
'DROP TABLE oracledb_employees',
|
||||||
connection.release(function(err) {
|
function(err) {
|
||||||
if(err) { console.error(err.message); return; }
|
should.not.exist(err);
|
||||||
done();
|
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() {
|
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) {
|
describe('55.3 alternating getRow() & getRows() function', function() {
|
||||||
it('55.3.1', function(done) {
|
it('55.3.1 result set', function(done) {
|
||||||
connection.should.be.ok;
|
connection.should.be.ok;
|
||||||
var accessCount = 0;
|
var accessCount = 0;
|
||||||
var numRows = 4;
|
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;
|
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(
|
oracledb.getConnection(
|
||||||
credential,
|
credential,
|
||||||
function(err, conn) {
|
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.should.be.ok;
|
||||||
conn2.execute(
|
conn2.execute(
|
||||||
"SELECT * FROM oracledb_employees",
|
"SELECT * FROM oracledb_employees",
|
||||||
|
@ -252,28 +380,25 @@ describe('55 resultSet2.js', function() {
|
||||||
{ resultSet: true },
|
{ resultSet: true },
|
||||||
function(err, result) {
|
function(err, result) {
|
||||||
should.not.exist(err);
|
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) {
|
conn2.execute(
|
||||||
rs.getRow(function(err, row) {
|
"BEGIN get_emp_rs(:in, :out); END;",
|
||||||
|
{
|
||||||
|
in: 200,
|
||||||
|
out: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||||
|
},
|
||||||
|
function(err, result) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
if(row) {
|
fetchRowFromRS(result.outBinds.out, done);
|
||||||
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();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -312,13 +437,13 @@ describe('55 resultSet2.js', function() {
|
||||||
], done);
|
], done);
|
||||||
|
|
||||||
function fetchRowFromRS(rset, cb) {
|
function fetchRowFromRS(rset, cb) {
|
||||||
rs.getRow(function(err, row) {
|
rset.getRow(function(err, row) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
if(row) {
|
if(row) {
|
||||||
rowsCount++;
|
rowsCount++;
|
||||||
return fetchRowFromRS(rset, cb);
|
return fetchRowFromRS(rset, cb);
|
||||||
} else {
|
} else {
|
||||||
rs.close(function(err) {
|
rset.close(function(err) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
rowsCount.should.eql(rowsAmount);
|
rowsCount.should.eql(rowsAmount);
|
||||||
cb();
|
cb();
|
||||||
|
@ -328,14 +453,45 @@ describe('55 resultSet2.js', function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('55.6 access resultSet simultaneously', 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) {
|
it('55.6.1 concurrent operations on resultSet are not allowed', function(done) {
|
||||||
connection.should.be.ok;
|
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(
|
connection.execute(
|
||||||
"SELECT * FROM oracledb_employees",
|
"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() {
|
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) {
|
it('55.7.1 can access multiple resultSet on one connection', function(done) {
|
||||||
connection.should.be.ok;
|
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([
|
async.parallel([
|
||||||
function(callback) {
|
function(callback) {
|
||||||
connection.execute(
|
connection.execute(
|
||||||
|
@ -434,37 +621,42 @@ describe('55 resultSet2.js', function() {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
it('55.7.2 can access multiple REF Cursor', function(done) {
|
||||||
|
connection.should.be.ok;
|
||||||
|
|
||||||
function fetchRowFromRS(rs, cb) {
|
async.parallel([
|
||||||
rs.getRow(function(err, row) {
|
function(callback) {
|
||||||
should.not.exist(err);
|
connection.execute(
|
||||||
if(row) {
|
"BEGIN get_emp_rs(:in, :out); END;",
|
||||||
rowCount1++;
|
{
|
||||||
return fetchRowFromRS(rs, cb);
|
in: 200,
|
||||||
} else {
|
out: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||||
rs.close(function(err) {
|
},
|
||||||
|
function(err, result) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
cb();
|
fetchRowFromRS(result.outBinds.out, callback);
|
||||||
});
|
}
|
||||||
}
|
);
|
||||||
});
|
},
|
||||||
}
|
function(callback) {
|
||||||
|
connection.execute(
|
||||||
function fetchRowsFromRS(rs, cb) {
|
"BEGIN get_emp_rs(:in, :out); END;",
|
||||||
rs.getRows(numRows, function(err, rows) {
|
{
|
||||||
should.not.exist(err);
|
in: 100,
|
||||||
if(rows.length > 0) {
|
out: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||||
rowCount2 += numRows;
|
},
|
||||||
return fetchRowsFromRS(rs, cb);
|
function(err, result) {
|
||||||
} else {
|
|
||||||
rs.close(function(err) {
|
|
||||||
should.not.exist(err);
|
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