From 12041c4bae2e12f1f23f8878eb101ebb9b1f8655 Mon Sep 17 00:00:00 2001 From: Christopher Jones Date: Mon, 20 Jul 2015 17:56:29 +1000 Subject: [PATCH] Tidy up tests --- test/README.md | 23 +- test/binding.js | 6 +- test/dataTypeAssist.js | 192 ++- test/dataTypeChar.js | 179 +-- test/dataTypeDate.js | 74 +- test/dataTypeFloat.js | 95 +- test/dataTypeFloat2.js | 95 +- test/dataTypeNchar.js | 94 +- test/dataTypeNumber.js | 96 +- test/dataTypeNumber2.js | 147 ++- test/dataTypeNvarchar2.js | 77 +- test/dataTypeTimestamp1.js | 71 +- test/dataTypeTimestamp2.js | 73 +- test/dataTypeTimestamp5.js | 72 +- test/dataTypeTimestamp6.js | 73 +- test/dataTypeVarchar2.js | 75 +- test/dmlReturning.js | 4 +- test/examples.js | 138 ++- test/nullColumnValues.js | 50 + test/pool.js | 12 +- test/poolValidityAfterFailingTerminate.js | 2 +- test/releaseAfterFailingTerminate.js | 2 +- test/resultSet.js | 652 ---------- test/resultSet1.js | 1325 +++++++++++++++++++++ test/resultSet2.js | 508 ++++++++ 25 files changed, 2624 insertions(+), 1511 deletions(-) delete mode 100644 test/resultSet.js create mode 100644 test/resultSet1.js create mode 100644 test/resultSet2.js diff --git a/test/README.md b/test/README.md index d6f0304c..7c7ac313 100644 --- a/test/README.md +++ b/test/README.md @@ -15,6 +15,9 @@ 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. + ## Running the complete test suite ### 1. Create a working directory @@ -27,6 +30,7 @@ cd ### 2. Install node-oracledb See [INSTALL](https://github.com/oracle/node-oracledb/blob/master/INSTALL.md) +for installation requirements and more details. Install with: @@ -50,7 +54,7 @@ cd /node_modules/oracledb npm install mocha should async ``` -Note: these are listed in `devDependencies` and `package.json` so `npm +Note: these are listed in `devDependencies` in `package.json` so `npm install` will install them when executed inside a node-oracledb package directory. @@ -60,9 +64,22 @@ package directory. vi /node_modules/oracledb/test/dbConfig.js ``` -The user requires privileges to connect and create tables. +Change the credentials to a user who has privileges to connect and create tables: -If you use external authentication, make sure Oracle Database and the authentication service have been appropriately configured. Also set the `externalAuth` property to `true` in `test/dbConfig.js`. See [Documentation for External Authentication](https://github.com/oracle/node-oracledb/blob/master/doc/api.md#extauth) for more details. +```javascript +module.exports = { + user : "hr", + password : "welcome", + connectString : "localhost/orcl", + externalAuth : false +}; +``` + +To use external authentication, set the `externalAuth` property to +`true`. Also make sure Oracle Database and the authentication service +have been appropriately configured. See +[Documentation for External Authentication](https://github.com/oracle/node-oracledb/blob/master/doc/api.md#extauth) +for more details. ### 5. Run test suite diff --git a/test/binding.js b/test/binding.js index 19186b1a..87ae90f4 100644 --- a/test/binding.js +++ b/test/binding.js @@ -308,7 +308,7 @@ describe('4. binding.js', function() { var proc = "CREATE OR REPLACE PROCEDURE oracledb_testproc (p_out OUT VARCHAR2) \ AS \ BEGIN \ - p_out := 'ABCDEF'; \ + p_out := 'ABCDEF GHIJK LMNOP QRSTU'; \ END;"; connection.should.be.ok; connection.execute( @@ -328,7 +328,7 @@ describe('4. binding.js', function() { function(err, result) { should.exist(err); // console.log(err.message); - err.message.should.startWith('ORA-06502: PL/SQL: numeric or value error: character string buffer too small'); + err.message.should.startWith('ORA-06502:'); // console.log(result); callback(); } @@ -343,7 +343,7 @@ describe('4. binding.js', function() { function(err, result) { should.exist(err); // console.log(err.message); - err.message.should.startWith('ORA-06502: PL/SQL: numeric or value error: character string buffer too small'); + err.message.should.startWith('ORA-06502:'); // console.log(result); callback(); } diff --git a/test/dataTypeAssist.js b/test/dataTypeAssist.js index e4fd7255..2d39fb96 100644 --- a/test/dataTypeAssist.js +++ b/test/dataTypeAssist.js @@ -15,6 +15,9 @@ * 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 * 21. datatypeAssist.js * @@ -28,7 +31,11 @@ * 51 - are for other tests * *****************************************************************************/ - + +var oracledb = require('oracledb'); +var should = require('should'); +var async = require('async'); + var assist = exports; assist.data = { specialChars: [ @@ -93,16 +100,16 @@ assist.data = { ], alphabet: [ 'A', 'B', 'C', 'D', 'E', - 'F', 'G', 'H', 'I', 'J', - 'K', 'L', 'M', 'N', 'O', - 'P', 'Q', 'R', 'S', 'T', - 'U', 'V', 'W', 'X', 'Y', - 'Z', 'a', 'b', 'c', 'd', - 'e', 'f', 'g', 'h', 'i', - 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', - 't', 'u', 'v', 'w', 'x', - 'y', 'z' + 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'Y', + 'Z', 'a', 'b', 'c', 'd', + 'e', 'f', 'g', 'h', 'i', + 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', + 't', 'u', 'v', 'w', 'x', + 'y', 'z' ] }; @@ -113,14 +120,14 @@ var StringBuffer = function() { StringBuffer.prototype = { append: function(s) { - this.buffer[this.index] = s; - this.index += 1; - return this; - }, - - toString: function() { - return this.buffer.join(""); - } + this.buffer[this.index] = s; + this.index += 1; + return this; + }, + + toString: function() { + return this.buffer.join(""); + } }; assist.createCharString = function(size) { @@ -130,13 +137,146 @@ assist.createCharString = function(size) { var cIndex = 0; for(var i = 0; i < size; i++) { if(i % 10 == 0) { - buffer.append(assist.data.specialChars[scIndex]); - scIndex = (scIndex + 1) % scSize; - } else { - cIndex = Math.floor(Math.random() * 52); // generate a random integer among 0-51 - buffer.append(assist.data.alphabet[cIndex]); - } + buffer.append(assist.data.specialChars[scIndex]); + scIndex = (scIndex + 1) % scSize; + } else { + cIndex = Math.floor(Math.random() * 52); // generate a random integer among 0-51 + buffer.append(assist.data.alphabet[cIndex]); + } } return buffer.toString(); } -module.exports = assist; \ No newline at end of file + +assist.setup = function(connection, tableName, sqlCreate, array, done) { + async.series([ + function(callback) { + connection.execute( + sqlCreate, + function(err) { + should.not.exist(err); + callback(); + } + ); + }, + function(callback) { + async.forEach(array, function(element, cb) { + connection.execute( + "INSERT INTO " + tableName + " VALUES(:no, :bindValue)", + { no: array.indexOf(element), bindValue: element }, + function(err) { + should.not.exist(err); + cb(); + } + ); + }, function(err) { + should.not.exist(err); + callback(); + }); + } + ], done); +} + +assist.dataTypeSupport = function(connection, tableName, array, done) { + connection.should.be.ok; + connection.execute( + "SELECT * FROM " + tableName, + [], + { outFormat: oracledb.OBJECT }, + function(err, result) { + should.not.exist(err); + // console.log(result); + for(var i = 0; i < array.length; i++) { + if( (typeof result.rows[i].CONTENT) === 'string' ) + result.rows[i].CONTENT.trim().should.eql(array[result.rows[i].NUM]); + else if( (typeof result.rows[i].CONTENT) === 'number' ) + result.rows[i].CONTENT.should.eql(array[result.rows[i].NUM]); + else + result.rows[i].CONTENT.toUTCString().should.eql(array[result.rows[i].NUM].toUTCString()); + } + done(); + } + ); +} + +assist.resultSetSupport = function(connection, tableName, array, done) { + connection.should.be.ok; + var numRows = 3; // number of rows to return from each call to getRows() + connection.execute( + "SELECT * FROM " + tableName, + [], + { resultSet: true, outFormat: oracledb.OBJECT }, + function(err, result) { + should.not.exist(err); + (result.resultSet.metaData[0]).name.should.eql('NUM'); + (result.resultSet.metaData[1]).name.should.eql('CONTENT'); + fetchRowsFromRS(result.resultSet); + } + ); + + function fetchRowsFromRS(rs) { + rs.getRows(numRows, function(err, rows) { + should.not.exist(err); + if(rows.length > 0) { + for(var i = 0; i < rows.length; i++) { + if( (typeof rows[i].CONTENT) === 'string' ) + rows[i].CONTENT.trim().should.eql(array[rows[i].NUM]); + else if( (typeof rows[i].CONTENT) === 'number' ) + rows[i].CONTENT.should.eql(array[rows[i].NUM]); + else + rows[i].CONTENT.toUTCString().should.eql(array[rows[i].NUM].toUTCString()); + } + return fetchRowsFromRS(rs); + } else if(rows.length == 0) { + rs.close(function(err) { + should.not.exist(err); + done(); + }); + } else { + var lengthLessThanZero = true; + should.not.exist(lengthLessThanZero); + done(); + } + }); + } +} + +assist.nullValueSupport = function(connection, tableName, done) { + connection.should.be.ok; + var sqlInsert = "INSERT INTO " + tableName + " VALUES(:no, :bindValue)"; + async.series([ + function(callback) { + connection.execute( + sqlInsert, + { no: 998, bindValue: '' }, + function(err) { + should.not.exist(err); + callback(); + } + ); + }, + function(callback) { + connection.execute( + sqlInsert, + { no: 999, bindValue: null }, + function(err) { + should.not.exist(err); + callback(); + } + ); + }, + function(callback) { + connection.execute( + "SELECT * FROM " + tableName + " WHERE num > :1 ORDER BY num", + [990], + function(err, result) { + should.not.exist(err); + // console.log(result); + result.rows.should.eql([ [998, null], [999, null] ]); + callback(); + } + ); + } + ], done); +} + +module.exports = assist; diff --git a/test/dataTypeChar.js b/test/dataTypeChar.js index ddd91163..89e59d2b 100644 --- a/test/dataTypeChar.js +++ b/test/dataTypeChar.js @@ -33,143 +33,74 @@ *****************************************************************************/ var oracledb = require('oracledb'); -var should = require('should'); -var async = require('async'); var assist = require('./dataTypeAssist.js'); var dbConfig = require('./dbConfig.js'); describe('22. dataTypeChar.js', function(){ - + var connection = false; 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('supports CHAR data type', function(done){ - connection.should.be.ok; - - // The capacity of Oracle CHAR is 2000 - var strLen = [100, 1000, 2000]; // char string length - var strs = [ + var tableName = "oracledb_datatype_char"; + 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 CHAR(2000) " + + " )" + + " '); " + + "END; "; + + var strLen = [100, 1000, 2000]; // char string length + var strs = [ assist.createCharString(strLen[0]), assist.createCharString(strLen[1]), assist.createCharString(strLen[2]), ]; - var tableName = "oracledb_datatype_char"; - 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 CHAR(2000) " + - " )" + - " '); " + - "END; "; - var sqlDrop = "DROP table " + tableName; - var sqlInsert = "INSERT INTO " + tableName + " VALUES(:no, :bindValue)"; - - async.series([ - function(callback){ - connection.execute( - sqlCreate, - function(err){ - should.not.exist(err); - callback(); - } - ); - }, - function(callback){ - connection.execute( - sqlInsert, - {no: 0, bindValue: strs[0]}, - function(err, result) { - should.not.exist(err); - //console.log(result); - result.rowsAffected.should.be.exactly(1); - callback(); - } - ); - }, - function(callback){ - connection.execute( - sqlInsert, - {no: 1, bindValue: strs[1]}, - function(err) { - should.not.exist(err); - callback(); - } - ); - }, - function(callback){ - connection.execute( - sqlInsert, - {no: 2, bindValue: strs[2]}, - function(err) { - should.not.exist(err); - callback(); - } - ); - }, - function(callback) { - connection.execute( - "SELECT * FROM " + tableName, - [], - {outFormat: oracledb.OBJECT}, - function(err, result) { - should.not.exist(err); - //console.log(result); - result.rows[0].NUM.should.be.exactly(0); - result.rows[0].CONTENT.trim().should.eql(strs[0]); - result.rows[0].CONTENT.trim().length.should.be.exactly(strLen[0]); - - result.rows[1].NUM.should.be.exactly(1); - result.rows[1].CONTENT.trim().should.eql(strs[1]); - result.rows[1].CONTENT.trim().length.should.be.exactly(strLen[1]); - - result.rows[2].NUM.should.be.exactly(2); - result.rows[2].CONTENT.trim().should.eql(strs[2]); - result.rows[2].CONTENT.trim().length.should.be.exactly(strLen[2]); - callback(); - } - ); - }, - - function(callback){ - connection.execute( - sqlDrop, - function(err) { - should.not.exist(err); - callback(); - } - ); - } - ], done); - + + before(function(done) { + oracledb.getConnection(credential, function(err, conn) { + if(err) { console.error(err.message); return; } + connection = conn; + assist.setup(connection, tableName, sqlCreate, strs, 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('22.1 supports CHAR data', function(done) { + assist.dataTypeSupport(connection, tableName, strs, done); + }) + + it('22.2 resultSet stores CHAR data correctly', function(done) { + assist.resultSetSupport(connection, tableName, strs, done); + }) + + it('22.3 stores null value correctly', function(done) { + assist.nullValueSupport(connection, tableName, done); + }) }) diff --git a/test/dataTypeDate.js b/test/dataTypeDate.js index c1af6f8f..68e00d6e 100644 --- a/test/dataTypeDate.js +++ b/test/dataTypeDate.js @@ -33,8 +33,6 @@ *****************************************************************************/ var oracledb = require('oracledb'); -var should = require('should'); -var async = require('async'); var assist = require('./dataTypeAssist.js'); var dbConfig = require('./dbConfig.js'); @@ -47,7 +45,6 @@ describe('32. dataTypeDate.js', function() { } var connection = false; - var tableName = "oracledb_datatype_date"; var sqlCreate = "BEGIN " + @@ -67,24 +64,25 @@ describe('32. dataTypeDate.js', function() { " )" + " '); " + "END; "; - var sqlDrop = "DROP table " + tableName; - before( function(done){ - oracledb.getConnection(credential, function(err, conn){ + + var dates = [ + new Date(-100000000), + new Date(0), + new Date(10000000000), + new Date(100000000000) + ]; + + before(function(done) { + oracledb.getConnection(credential, function(err, conn) { if(err) { console.error(err.message); return; } connection = conn; - connection.execute( - sqlCreate, - function(err) { - if(err) { console.error(err.message); return; } - done(); - } - ); + assist.setup(connection, tableName, sqlCreate, dates, done); }); }) after( function(done){ connection.execute( - sqlDrop, + "DROP table " + tableName, function(err) { if(err) { console.error(err.message); return; } connection.release( function(err) { @@ -94,44 +92,16 @@ describe('32. dataTypeDate.js', function() { } ); }) - - it('supports DATE data type', function(done) { - connection.should.be.ok; - - var dates = [ - new Date(-100000000), - new Date(0), - new Date(10000000000), - new Date(100000000000) - ]; - - var sqlInsert = "INSERT INTO " + tableName + " VALUES(:no, :bindValue)"; - - async.forEach(dates, function(date, callback) { - connection.execute( - sqlInsert, - { no: dates.indexOf(date), bindValue: date }, - function(err) { - should.not.exist(err); - callback(); - } - ); - }, function(err) { - should.not.exist(err); - connection.execute( - "SELECT * FROM " + tableName, - [], - { outFormat: oracledb.OBJECT }, - function(err, result) { - should.not.exist(err); - // console.log(result); - for(var j = 0; j < dates.length; j++) - result.rows[j].CONTENT.toUTCString().should.eql(dates[result.rows[j].NUM].toUTCString()); - - done(); - } - ); - }); + + it('32.1 supports DATE data type', function(done) { + assist.dataTypeSupport(connection, tableName, dates, done); }) + it('32.2 resultSet stores DATE data correctly', function(done) { + assist.resultSetSupport(connection, tableName, dates, done); + }) + + it('32.3 stores null value correctly', function(done) { + assist.nullValueSupport(connection, tableName, done); + }) }) diff --git a/test/dataTypeFloat.js b/test/dataTypeFloat.js index f5b90b2e..9e74ec93 100644 --- a/test/dataTypeFloat.js +++ b/test/dataTypeFloat.js @@ -33,8 +33,6 @@ *****************************************************************************/ var oracledb = require('oracledb'); -var should = require('should'); -var async = require('async'); var assist = require('./dataTypeAssist.js'); var dbConfig = require('./dbConfig.js'); @@ -47,7 +45,6 @@ describe('28. dataTypeFloat.js', function() { } var connection = false; - var tableName = "oracledb_datatype_float"; var sqlCreate = "BEGIN " + @@ -67,38 +64,7 @@ describe('28. dataTypeFloat.js', function() { " )" + " '); " + "END; "; - var sqlDrop = "DROP table " + tableName; - before( function(done){ - oracledb.getConnection(credential, function(err, conn){ - if(err) { console.error(err.message); return; } - connection = conn; - connection.execute( - sqlCreate, - function(err) { - if(err) { console.error(err.message); return; } - done(); - } - ); - }); - }) - - after( function(done){ - connection.execute( - sqlDrop, - function(err) { - if(err) { console.error(err.message); return; } - connection.release( function(err) { - if(err) { console.error(err.message); return; } - done(); - }); - } - ); - }) - - it('supports FLOAT data type', function(done) { - connection.should.be.ok; - - var numbers = [ + var numbers = [ 1, 0, 8, @@ -111,35 +77,38 @@ describe('28. dataTypeFloat.js', function() { -0.01234, 123456789.0123, -123456789.0123 - ]; - - var sqlInsert = "INSERT INTO " + tableName + " VALUES(:no, :bindValue)"; - - async.forEach(numbers, function(num, callback) { - connection.execute( - sqlInsert, - { no: numbers.indexOf(num), bindValue: num }, - function(err) { - should.not.exist(err); - callback(); - } - ); - }, function(err) { - should.not.exist(err); - connection.execute( - "SELECT * FROM " + tableName, - [], - { outFormat: oracledb.OBJECT }, - function(err, result) { - should.not.exist(err); - // console.log(result); - for(var j = 0; j < numbers.length; j++) - result.rows[j].CONTENT.should.be.exactly(numbers[result.rows[j].NUM]); - - done(); - } - ); + ]; + + before(function(done) { + oracledb.getConnection(credential, function(err, conn) { + if(err) { console.error(err.message); return; } + connection = conn; + assist.setup(connection, tableName, sqlCreate, numbers, 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('28.1 supports FLOAT data type', function(done) { + assist.dataTypeSupport(connection, tableName, numbers, done); + }) + + it('28.2 resultSet stores FLOAT data correctly', function(done) { + assist.resultSetSupport(connection, tableName, numbers, done); + }) + + it('28.3 stores null value correctly', function(done) { + assist.nullValueSupport(connection, tableName, done); + }) }) diff --git a/test/dataTypeFloat2.js b/test/dataTypeFloat2.js index 378633ee..51eb22bf 100644 --- a/test/dataTypeFloat2.js +++ b/test/dataTypeFloat2.js @@ -33,8 +33,6 @@ *****************************************************************************/ var oracledb = require('oracledb'); -var should = require('should'); -var async = require('async'); var assist = require('./dataTypeAssist.js'); var dbConfig = require('./dbConfig.js'); @@ -47,7 +45,6 @@ describe('29. dataTypeFloat2.js', function() { } var connection = false; - var tableName = "oracledb_datatype_float"; var sqlCreate = "BEGIN " + @@ -67,38 +64,7 @@ describe('29. dataTypeFloat2.js', function() { " )" + " '); " + "END; "; - var sqlDrop = "DROP table " + tableName; - before( function(done){ - oracledb.getConnection(credential, function(err, conn){ - if(err) { console.error(err.message); return; } - connection = conn; - connection.execute( - sqlCreate, - function(err) { - if(err) { console.error(err.message); return; } - done(); - } - ); - }); - }) - - after( function(done){ - connection.execute( - sqlDrop, - function(err) { - if(err) { console.error(err.message); return; } - connection.release( function(err) { - if(err) { console.error(err.message); return; } - done(); - }); - } - ); - }) - - it('supports FLOAT(p) data type', function(done) { - connection.should.be.ok; - - var numbers = [ + var numbers = [ 1, 0, 8, @@ -111,35 +77,38 @@ describe('29. dataTypeFloat2.js', function() { -0.01234, 123456789.0123, -123456789.0123 - ]; - - var sqlInsert = "INSERT INTO " + tableName + " VALUES(:no, :bindValue)"; - - async.forEach(numbers, function(num, callback) { - connection.execute( - sqlInsert, - { no: numbers.indexOf(num), bindValue: num }, - function(err) { - should.not.exist(err); - callback(); - } - ); - }, function(err) { - should.not.exist(err); - connection.execute( - "SELECT * FROM " + tableName, - [], - { outFormat: oracledb.OBJECT }, - function(err, result) { - should.not.exist(err); - // console.log(result); - for(var j = 0; j < numbers.length; j++) - result.rows[j].CONTENT.should.be.exactly(numbers[result.rows[j].NUM]); - - done(); - } - ); + ]; + + before(function(done) { + oracledb.getConnection(credential, function(err, conn) { + if(err) { console.error(err.message); return; } + connection = conn; + assist.setup(connection, tableName, sqlCreate, numbers, 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('29.1 supports FLOAT(p) data type', function(done) { + assist.dataTypeSupport(connection, tableName, numbers, done); + }) + + it('29.2 resultSet stores FLOAT(p) data correctly', function(done) { + assist.resultSetSupport(connection, tableName, numbers, done); + }) + + it('29.3 stores null value correctly', function(done) { + assist.nullValueSupport(connection, tableName, done); + }) }) diff --git a/test/dataTypeNchar.js b/test/dataTypeNchar.js index d59d3528..5f2f3400 100644 --- a/test/dataTypeNchar.js +++ b/test/dataTypeNchar.js @@ -33,8 +33,6 @@ *****************************************************************************/ var oracledb = require('oracledb'); -var should = require('should'); -var async = require('async'); var assist = require('./dataTypeAssist.js'); var dbConfig = require('./dbConfig.js'); @@ -66,24 +64,23 @@ describe('23. dataTypeNchar.js', function(){ " )" + " '); " + "END; "; - var sqlDrop = "DROP table " + tableName; - before( function(done){ - oracledb.getConnection(credential, function(err, conn){ + + var strLen = [10, 100, 500, 1000]; + var strs = []; + for(var i = 0; i < strLen.length; i++) + strs[i] = assist.createCharString(strLen[i]); + + before(function(done) { + oracledb.getConnection(credential, function(err, conn) { if(err) { console.error(err.message); return; } connection = conn; - connection.execute( - sqlCreate, - function(err) { - if(err) { console.error(err.message); return; } - done(); - } - ); + assist.setup(connection, tableName, sqlCreate, strs, done); }); }) - after( function(done){ + after(function(done) { connection.execute( - sqlDrop, + "DROP table " + tableName, function(err) { if(err) { console.error(err.message); return; } connection.release( function(err) { @@ -94,64 +91,15 @@ describe('23. dataTypeNchar.js', function(){ ); }) - it('supports NCHAR data type', function(done){ - connection.should.be.ok; - - var strLen = [10, 100, 500, 1000]; - var strs = []; - for(var i = 0; i < strLen.length; i++) - strs[i] = assist.createCharString(strLen[i]); - - var sqlInsert = "INSERT INTO " + tableName + " VALUES(:no, :bindValue)"; - async.forEach(strs, function(str, callback) { - connection.execute( - sqlInsert, - { no: strs.indexOf(str), bindValue: str}, - function(err) { - should.not.exist(err); - callback(); - } - ); - }, function(err) { - should.not.exist(err); - connection.execute( - "SELECT * FROM " + tableName, - [], - { outFormat: oracledb.OBJECT }, - function(err, result) { - should.not.exist(err); - - for(var j = 0; j < strLen.length; j++) { - result.rows[j].CONTENT.trim().should.eql(strs[result.rows[j].NUM]); - result.rows[j].CONTENT.trim().length.should.be.exactly(strLen[result.rows[j].NUM]); - } - done(); - } - ); - }); + it('23.1 supports NCHAR data type', function(done) { + assist.dataTypeSupport(connection, tableName, strs, done); }) + + it('23.2 resultSet supports NCHAR data type', function(done) { + assist.resultSetSupport(connection, tableName, strs, done); + }) + + it('23.3 stores null value correctly', function(done) { + assist.nullValueSupport(connection, tableName, done); + }) }) - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/test/dataTypeNumber.js b/test/dataTypeNumber.js index 8aa842b1..87b09222 100644 --- a/test/dataTypeNumber.js +++ b/test/dataTypeNumber.js @@ -33,8 +33,6 @@ *****************************************************************************/ var oracledb = require('oracledb'); -var should = require('should'); -var async = require('async'); var assist = require('./dataTypeAssist.js'); var dbConfig = require('./dbConfig.js'); @@ -47,7 +45,6 @@ describe('26. dataTypeNumber.js', function() { } var connection = false; - var tableName = "oracledb_datatype_number"; var sqlCreate = "BEGIN " + @@ -67,38 +64,8 @@ describe('26. dataTypeNumber.js', function() { " )" + " '); " + "END; "; - var sqlDrop = "DROP table " + tableName; - before( function(done){ - oracledb.getConnection(credential, function(err, conn){ - if(err) { console.error(err.message); return; } - connection = conn; - connection.execute( - sqlCreate, - function(err) { - if(err) { console.error(err.message); return; } - done(); - } - ); - }); - }) - - after( function(done){ - connection.execute( - sqlDrop, - function(err) { - if(err) { console.error(err.message); return; } - connection.release( function(err) { - if(err) { console.error(err.message); return; } - done(); - }); - } - ); - }) - - it('supports NUMBER data type', function(done) { - connection.should.be.ok; - - var numbers = [ + + var numbers = [ 1, 0, 8, @@ -111,35 +78,38 @@ describe('26. dataTypeNumber.js', function() { -0.01234, 0.00000123, -0.00000123 - ]; - - var sqlInsert = "INSERT INTO " + tableName + " VALUES(:no, :bindValue)"; - - async.forEach(numbers, function(num, callback) { - connection.execute( - sqlInsert, - { no: numbers.indexOf(num), bindValue: num }, - function(err) { - should.not.exist(err); - callback(); - } - ); - }, function(err) { - should.not.exist(err); - connection.execute( - "SELECT * FROM " + tableName, - [], - { outFormat: oracledb.OBJECT }, - function(err, result) { - should.not.exist(err); - // console.log(result); - for(var j = 0; j < numbers.length; j++) - result.rows[j].CONTENT.should.be.exactly(numbers[result.rows[j].NUM]); - - done(); - } - ); + ]; + + before(function(done) { + oracledb.getConnection(credential, function(err, conn) { + if(err) { console.error(err.message); return; } + connection = conn; + assist.setup(connection, tableName, sqlCreate, numbers, 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('26.1 supports NUMBER data type', function(done) { + assist.dataTypeSupport(connection, tableName, numbers, done); + }) + + it('26.2 resultSet stores NUMBER data correctly', function(done) { + assist.resultSetSupport(connection, tableName, numbers, done); + }) + + it('26.3 stores null value correctly', function(done) { + assist.nullValueSupport(connection, tableName, done); + }) }) diff --git a/test/dataTypeNumber2.js b/test/dataTypeNumber2.js index a2602f57..842a89e7 100644 --- a/test/dataTypeNumber2.js +++ b/test/dataTypeNumber2.js @@ -47,7 +47,6 @@ describe('27. dataTypeNumber2.js', function() { } var connection = false; - var tableName = "oracledb_datatype_number2"; var sqlCreate = "BEGIN " + @@ -67,38 +66,7 @@ describe('27. dataTypeNumber2.js', function() { " )" + " '); " + "END; "; - var sqlDrop = "DROP table " + tableName; - before( function(done){ - oracledb.getConnection(credential, function(err, conn){ - if(err) { console.error(err.message); return; } - connection = conn; - connection.execute( - sqlCreate, - function(err) { - if(err) { console.error(err.message); return; } - done(); - } - ); - }); - }) - - after( function(done){ - connection.execute( - sqlDrop, - function(err) { - if(err) { console.error(err.message); return; } - connection.release( function(err) { - if(err) { console.error(err.message); return; } - done(); - }); - } - ); - }) - - it('supports NUMBER(p, s) data type', function(done) { - connection.should.be.ok; - - var numbers = [ + var numbers = [ 1, 0, 8, @@ -110,38 +78,89 @@ describe('27. dataTypeNumber2.js', function() { 0.01234, -0.01234, 0.00000123 - ]; - - var sqlInsert = "INSERT INTO " + tableName + " VALUES(:no, :bindValue)"; - - async.forEach(numbers, function(num, callback) { - connection.execute( - sqlInsert, - { no: numbers.indexOf(num), bindValue: num }, - function(err) { - should.not.exist(err); - callback(); - } - ); - }, function(err) { - should.not.exist(err); - connection.execute( - "SELECT * FROM " + tableName, - [], - { outFormat: oracledb.OBJECT }, - function(err, result) { - should.not.exist(err); - // console.log(result); - for(var j = 0; j < numbers.length; j++) { - if(numbers[result.rows[j].NUM] == 0.00000123) - result.rows[j].CONTENT.should.be.exactly(0); - else - result.rows[j].CONTENT.should.be.exactly(numbers[result.rows[j].NUM]); - } - done(); - } - ); + ]; + before(function(done) { + oracledb.getConnection(credential, function(err, conn) { + if(err) { console.error(err.message); return; } + connection = conn; + assist.setup(connection, tableName, sqlCreate, numbers, 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('27.1 supports NUMBER(p, s) data type', function(done) { + connection.should.be.ok; + connection.execute( + "SELECT * FROM " + tableName, + [], + { outFormat: oracledb.OBJECT }, + function(err, result) { + should.not.exist(err); + // console.log(result); + for(var j = 0; j < numbers.length; j++) { + if(numbers[result.rows[j].NUM] == 0.00000123) + result.rows[j].CONTENT.should.be.exactly(0); + else + result.rows[j].CONTENT.should.be.exactly(numbers[result.rows[j].NUM]); + } + done(); + } + ); + }) + + it('27.2 resultSet stores NUMBER(p, s) data correctly', function(done) { + connection.should.be.ok; + var numRows = 3; // number of rows to return from each call to getRows() + connection.execute( + "SELECT * FROM " + tableName, + [], + { resultSet: true, outFormat: oracledb.OBJECT }, + function(err, result) { + should.not.exist(err); + (result.resultSet.metaData[0]).name.should.eql('NUM'); + (result.resultSet.metaData[1]).name.should.eql('CONTENT'); + fetchRowsFromRS(result.resultSet); + } + ); + + function fetchRowsFromRS(rs) { + rs.getRows(numRows, function(err, rows) { + should.not.exist(err); + if(rows.length > 0) { + for(var i = 0; i < rows.length; i++) { + if(numbers[rows[i].NUM] == 0.00000123) + rows[i].CONTENT.should.be.exactly(0); + else + rows[i].CONTENT.should.be.exactly(numbers[rows[i].NUM]); + } + return fetchRowsFromRS(rs); + } else if(rows.length == 0) { + rs.close(function(err) { + should.not.exist(err); + done(); + }); + } else { + var lengthLessThanZero = true; + should.not.exist(lengthLessThanZero); + done(); + } + }); + } + }) + + it('27.3 stores null value correctly', function(done) { + assist.nullValueSupport(connection, tableName, done); + }) }) diff --git a/test/dataTypeNvarchar2.js b/test/dataTypeNvarchar2.js index 1965d9b4..abe368bd 100644 --- a/test/dataTypeNvarchar2.js +++ b/test/dataTypeNvarchar2.js @@ -33,21 +33,18 @@ *****************************************************************************/ var oracledb = require('oracledb'); -var should = require('should'); -var async = require('async'); var assist = require('./dataTypeAssist.js'); var dbConfig = require('./dbConfig.js'); describe('25. dataTypeNvarchar2.js', function() { - + if(dbConfig.externalAuth){ var credential = { externalAuth: true, connectString: dbConfig.connectString }; } else { var credential = dbConfig; } - + var connection = false; - var tableName = "oracledb_datatype_nvarchar2"; var sqlCreate = "BEGIN " + @@ -67,24 +64,23 @@ describe('25. dataTypeNvarchar2.js', function() { " )" + " '); " + "END; "; - var sqlDrop = "DROP table " + tableName; - before( function(done){ - oracledb.getConnection(credential, function(err, conn){ + + var strLen = [10 ,100, 1000, 2000]; // char string length + var strs = []; + for(var i = 0; i < strLen.length; i++) + strs[i] = assist.createCharString(strLen[i]); + + before(function(done) { + oracledb.getConnection(credential, function(err, conn) { if(err) { console.error(err.message); return; } connection = conn; - connection.execute( - sqlCreate, - function(err) { - if(err) { console.error(err.message); return; } - done(); - } - ); + assist.setup(connection, tableName, sqlCreate, strs, done); }); }) - after( function(done){ + after(function(done) { connection.execute( - sqlDrop, + "DROP table " + tableName, function(err) { if(err) { console.error(err.message); return; } connection.release( function(err) { @@ -95,42 +91,15 @@ describe('25. dataTypeNvarchar2.js', function() { ); }) - it('supports NVARCHAR2 data type', function(done) { - connection.should.be.ok; - - var strLen = [10 ,100, 1000, 2000]; // char string length - var strs = []; - for(var i = 0; i < strLen.length; i++) - strs[i] = assist.createCharString(strLen[i]); - - var sqlInsert = "INSERT INTO " + tableName + " VALUES(:no, :bindValue)"; - - async.forEach(strs, function(str, callback) { - connection.execute( - sqlInsert, - { no: strs.indexOf(str), bindValue: str }, - function(err) { - should.not.exist(err); - callback(); - } - ); - }, function(err) { - should.not.exist(err); - connection.execute( - "SELECT * FROM " + tableName, - [], - { outFormat: oracledb.OBJECT }, - function(err, result) { - should.not.exist(err); - //console.log(result); - - for(var j = 0; j < strLen.length; j++) { - result.rows[j].CONTENT.trim().should.eql(strs[result.rows[j].NUM]); - result.rows[j].CONTENT.trim().length.should.be.exactly(strLen[result.rows[j].NUM]); - } - done(); - } - ); - }); + it('25.1 supports NVARCHAR2 data in various lengths', function(done) { + assist.dataTypeSupport(connection, tableName, strs, done); + }) + + it('25.2 resultSet stores NVARCHAR2 data correctly', function(done) { + assist.resultSetSupport(connection, tableName, strs, done); + }) + + it('25.3 stores null value correctly', function(done) { + assist.nullValueSupport(connection, tableName, done); }) }) diff --git a/test/dataTypeTimestamp1.js b/test/dataTypeTimestamp1.js index f2401c88..7279bf8a 100644 --- a/test/dataTypeTimestamp1.js +++ b/test/dataTypeTimestamp1.js @@ -47,7 +47,6 @@ describe('33. dataTypeTimestamp1.js', function() { } var connection = false; - var tableName = "oracledb_datatype_timestamp"; var sqlCreate = "BEGIN " + @@ -67,24 +66,24 @@ describe('33. dataTypeTimestamp1.js', function() { " )" + " '); " + "END; "; - var sqlDrop = "DROP table " + tableName; - before( function(done){ - oracledb.getConnection(credential, function(err, conn){ + var timestamps = [ + new Date(-100000000), + new Date(0), + new Date(10000000000), + new Date(100000000000) + ]; + + before(function(done) { + oracledb.getConnection(credential, function(err, conn) { if(err) { console.error(err.message); return; } connection = conn; - connection.execute( - sqlCreate, - function(err) { - if(err) { console.error(err.message); return; } - done(); - } - ); + assist.setup(connection, tableName, sqlCreate, timestamps, done); }); }) after( function(done){ connection.execute( - sqlDrop, + "DROP table " + tableName, function(err) { if(err) { console.error(err.message); return; } connection.release( function(err) { @@ -94,44 +93,16 @@ describe('33. dataTypeTimestamp1.js', function() { } ); }) - - it('supports TIMESTAMP data type', function(done) { - connection.should.be.ok; - - var timestamps = [ - new Date(-100000000), - new Date(0), - new Date(10000000000), - new Date(100000000000) - ]; - - var sqlInsert = "INSERT INTO " + tableName + " VALUES(:no, :bindValue)"; - - async.forEach(timestamps, function(timestamp, callback) { - connection.execute( - sqlInsert, - { no: timestamps.indexOf(timestamp), bindValue: timestamp }, - function(err) { - should.not.exist(err); - callback(); - } - ); - }, function(err) { - should.not.exist(err); - connection.execute( - "SELECT * FROM " + tableName, - [], - { outFormat: oracledb.OBJECT }, - function(err, result) { - should.not.exist(err); - // console.log(result); - for(var j = 0; j < timestamps.length; j++) - result.rows[j].CONTENT.toUTCString().should.eql(timestamps[result.rows[j].NUM].toUTCString()); - - done(); - } - ); - }); + + it('33.1 supports TIMESTAMP data type', function(done) { + assist.dataTypeSupport(connection, tableName, timestamps, done); }) + it('33.2 resultSet stores TIMESTAMP data correctly', function(done) { + assist.resultSetSupport(connection, tableName, timestamps, done); + }) + + it('33.3 stores null value correctly', function(done) { + assist.nullValueSupport(connection, tableName, done); + }) }) diff --git a/test/dataTypeTimestamp2.js b/test/dataTypeTimestamp2.js index 8a278b6e..48e9b6ee 100644 --- a/test/dataTypeTimestamp2.js +++ b/test/dataTypeTimestamp2.js @@ -33,8 +33,6 @@ *****************************************************************************/ var oracledb = require('oracledb'); -var should = require('should'); -var async = require('async'); var assist = require('./dataTypeAssist.js'); var dbConfig = require('./dbConfig.js'); @@ -47,7 +45,6 @@ describe('34. dataTypeTimestamp2.js', function() { } var connection = false; - var tableName = "oracledb_datatype_timestamp"; var sqlCreate = "BEGIN " + @@ -67,24 +64,24 @@ describe('34. dataTypeTimestamp2.js', function() { " )" + " '); " + "END; "; - var sqlDrop = "DROP table " + tableName; - before( function(done){ - oracledb.getConnection(credential, function(err, conn){ + var timestamps = [ + new Date(-100000000), + new Date(0), + new Date(10000000000), + new Date(100000000000) + ]; + + before(function(done) { + oracledb.getConnection(credential, function(err, conn) { if(err) { console.error(err.message); return; } connection = conn; - connection.execute( - sqlCreate, - function(err) { - if(err) { console.error(err.message); return; } - done(); - } - ); + assist.setup(connection, tableName, sqlCreate, timestamps, done); }); }) after( function(done){ connection.execute( - sqlDrop, + "DROP table " + tableName, function(err) { if(err) { console.error(err.message); return; } connection.release( function(err) { @@ -94,44 +91,16 @@ describe('34. dataTypeTimestamp2.js', function() { } ); }) - - it('supports TIMESTAMP data type', function(done) { - connection.should.be.ok; - - var timestamps = [ - new Date(-100000000), - new Date(0), - new Date(10000000000), - new Date(100000000000) - ]; - - var sqlInsert = "INSERT INTO " + tableName + " VALUES(:no, :bindValue)"; - - async.forEach(timestamps, function(timestamp, callback) { - connection.execute( - sqlInsert, - { no: timestamps.indexOf(timestamp), bindValue: timestamp }, - function(err) { - should.not.exist(err); - callback(); - } - ); - }, function(err) { - should.not.exist(err); - connection.execute( - "SELECT * FROM " + tableName, - [], - { outFormat: oracledb.OBJECT }, - function(err, result) { - should.not.exist(err); - // console.log(result); - for(var j = 0; j < timestamps.length; j++) - result.rows[j].CONTENT.toUTCString().should.eql(timestamps[result.rows[j].NUM].toUTCString()); - - done(); - } - ); - }); + + it('34.1 supports TIMESTAMP(p) data type', function(done) { + assist.dataTypeSupport(connection, tableName, timestamps, done); }) + it('34.2 resultSet stores TIMESTAMP data correctly', function(done) { + assist.resultSetSupport(connection, tableName, timestamps, done); + }) + + it('34.3 stores null value correctly', function(done) { + assist.nullValueSupport(connection, tableName, done); + }) }) diff --git a/test/dataTypeTimestamp5.js b/test/dataTypeTimestamp5.js index 903a532d..a773bcf0 100644 --- a/test/dataTypeTimestamp5.js +++ b/test/dataTypeTimestamp5.js @@ -33,8 +33,6 @@ *****************************************************************************/ var oracledb = require('oracledb'); -var should = require('should'); -var async = require('async'); var assist = require('./dataTypeAssist.js'); var dbConfig = require('./dbConfig.js'); @@ -47,7 +45,6 @@ describe('37. dataTypeTimestamp5.js', function() { } var connection = false; - var tableName = "oracledb_datatype_timestamp"; var sqlCreate = "BEGIN " + @@ -67,24 +64,24 @@ describe('37. dataTypeTimestamp5.js', function() { " )" + " '); " + "END; "; - var sqlDrop = "DROP table " + tableName; - before( function(done){ - oracledb.getConnection(credential, function(err, conn){ + var timestamps = [ + new Date(-100000000), + new Date(0), + new Date(10000000000), + new Date(100000000000) + ]; + + before(function(done) { + oracledb.getConnection(credential, function(err, conn) { if(err) { console.error(err.message); return; } connection = conn; - connection.execute( - sqlCreate, - function(err) { - if(err) { console.error(err.message); return; } - done(); - } - ); + assist.setup(connection, tableName, sqlCreate, timestamps, done); }); }) after( function(done){ connection.execute( - sqlDrop, + "DROP table " + tableName, function(err) { if(err) { console.error(err.message); return; } connection.release( function(err) { @@ -94,44 +91,15 @@ describe('37. dataTypeTimestamp5.js', function() { } ); }) - - it('supports TIMESTAMP WITH LOCAL TIME ZONE data type', function(done) { - connection.should.be.ok; - - var timestamps = [ - new Date(-100000000), - new Date(0), - new Date(10000000000), - new Date(100000000000) - ]; - - var sqlInsert = "INSERT INTO " + tableName + " VALUES(:no, :bindValue)"; - - async.forEach(timestamps, function(timestamp, callback) { - connection.execute( - sqlInsert, - { no: timestamps.indexOf(timestamp), bindValue: timestamp }, - function(err) { - should.not.exist(err); - callback(); - } - ); - }, function(err) { - should.not.exist(err); - connection.execute( - "SELECT * FROM " + tableName, - [], - { outFormat: oracledb.OBJECT }, - function(err, result) { - should.not.exist(err); - // console.log(result); - for(var j = 0; j < timestamps.length; j++) - result.rows[j].CONTENT.toUTCString().should.eql(timestamps[result.rows[j].NUM].toUTCString()); - - done(); - } - ); - }); + it('37.1 supports TIMESTAMP WITH LOCAL TIME ZONE data type', function(done) { + assist.dataTypeSupport(connection, tableName, timestamps, done); }) + it('37.2 resultSet stores TIMESTAMP WITH LOCAL TIME ZONE data correctly', function(done) { + assist.resultSetSupport(connection, tableName, timestamps, done); + }) + + it('37.3 stores null value correctly', function(done) { + assist.nullValueSupport(connection, tableName, done); + }) }) diff --git a/test/dataTypeTimestamp6.js b/test/dataTypeTimestamp6.js index 184cf377..d7a934d9 100644 --- a/test/dataTypeTimestamp6.js +++ b/test/dataTypeTimestamp6.js @@ -36,8 +36,6 @@ *****************************************************************************/ var oracledb = require('oracledb'); -var should = require('should'); -var async = require('async'); var assist = require('./dataTypeAssist.js'); var dbConfig = require('./dbConfig.js'); @@ -50,7 +48,6 @@ describe('38. dataTypeTimestamp6.js', function() { } var connection = false; - var tableName = "oracledb_datatype_timestamp"; var sqlCreate = "BEGIN " + @@ -70,24 +67,24 @@ describe('38. dataTypeTimestamp6.js', function() { " )" + " '); " + "END; "; - var sqlDrop = "DROP table " + tableName; - before( function(done){ - oracledb.getConnection(credential, function(err, conn){ + var timestamps = [ + new Date(-100000000), + new Date(0), + new Date(10000000000), + new Date(100000000000) + ]; + + before(function(done) { + oracledb.getConnection(credential, function(err, conn) { if(err) { console.error(err.message); return; } connection = conn; - connection.execute( - sqlCreate, - function(err) { - if(err) { console.error(err.message); return; } - done(); - } - ); + assist.setup(connection, tableName, sqlCreate, timestamps, done); }); }) after( function(done){ connection.execute( - sqlDrop, + "DROP table " + tableName, function(err) { if(err) { console.error(err.message); return; } connection.release( function(err) { @@ -97,44 +94,16 @@ describe('38. dataTypeTimestamp6.js', function() { } ); }) - - it('supports TIMESTAMP (9) WITH LOCAL TIME ZONE data type', function(done) { - connection.should.be.ok; - - var timestamps = [ - new Date(-100000000), - new Date(0), - new Date(10000000000), - new Date(100000000000) - ]; - - var sqlInsert = "INSERT INTO " + tableName + " VALUES(:no, :bindValue)"; - - async.forEach(timestamps, function(timestamp, callback) { - connection.execute( - sqlInsert, - { no: timestamps.indexOf(timestamp), bindValue: timestamp }, - function(err) { - should.not.exist(err); - callback(); - } - ); - }, function(err) { - should.not.exist(err); - connection.execute( - "SELECT * FROM " + tableName, - [], - { outFormat: oracledb.OBJECT }, - function(err, result) { - should.not.exist(err); - // console.log(result); - for(var j = 0; j < timestamps.length; j++) - result.rows[j].CONTENT.toUTCString().should.eql(timestamps[result.rows[j].NUM].toUTCString()); - - done(); - } - ); - }); + + it('38.1 supports TIMESTAMP(9) WITH LOCAL TIME ZONE data type', function(done) { + assist.dataTypeSupport(connection, tableName, timestamps, done); }) + it('38.2 resultSet stores TIMESTAMP(9) WITH LOCAL TIME ZONE data correctly', function(done) { + assist.resultSetSupport(connection, tableName, timestamps, done); + }) + + it('38.3 stores null value correctly', function(done) { + assist.nullValueSupport(connection, tableName, done); + }) }) diff --git a/test/dataTypeVarchar2.js b/test/dataTypeVarchar2.js index 0a100e75..df5bd78e 100644 --- a/test/dataTypeVarchar2.js +++ b/test/dataTypeVarchar2.js @@ -33,8 +33,6 @@ *****************************************************************************/ var oracledb = require('oracledb'); -var should = require('should'); -var async = require('async'); var assist = require('./dataTypeAssist.js'); var dbConfig = require('./dbConfig.js'); @@ -47,7 +45,6 @@ describe('24. dataTypeVarchar2.js', function() { } var connection = false; - var tableName = "oracledb_datatype_varchar2"; var sqlCreate = "BEGIN " + @@ -67,24 +64,23 @@ describe('24. dataTypeVarchar2.js', function() { " )" + " '); " + "END; "; - var sqlDrop = "DROP table " + tableName; - before( function(done){ - oracledb.getConnection(credential, function(err, conn){ + + var strLen = [10 ,100, 1000, 2000, 3000, 4000]; // char string length + var strs = []; + for(var i = 0; i < strLen.length; i++) + strs[i] = assist.createCharString(strLen[i]); + + before(function(done) { + oracledb.getConnection(credential, function(err, conn) { if(err) { console.error(err.message); return; } connection = conn; - connection.execute( - sqlCreate, - function(err) { - if(err) { console.error(err.message); return; } - done(); - } - ); + assist.setup(connection, tableName, sqlCreate, strs, done); }); }) - after( function(done){ + after(function(done) { connection.execute( - sqlDrop, + "DROP table " + tableName, function(err) { if(err) { console.error(err.message); return; } connection.release( function(err) { @@ -95,42 +91,15 @@ describe('24. dataTypeVarchar2.js', function() { ); }) - it('supports VARCHAR2 data type', function(done) { - connection.should.be.ok; - - var strLen = [10 ,100, 1000, 2000, 3000, 4000]; // char string length - var strs = []; - for(var i = 0; i < strLen.length; i++) - strs[i] = assist.createCharString(strLen[i]); - - var sqlInsert = "INSERT INTO " + tableName + " VALUES(:no, :bindValue)"; - - async.forEach(strs, function(str, callback) { - connection.execute( - sqlInsert, - { no: strs.indexOf(str), bindValue: str }, - function(err) { - should.not.exist(err); - callback(); - } - ); - }, function(err) { - should.not.exist(err); - connection.execute( - "SELECT * FROM " + tableName, - [], - { outFormat: oracledb.OBJECT }, - function(err, result) { - should.not.exist(err); - //console.log(result); - - for(var j = 0; j < strLen.length; j++) { - result.rows[j].CONTENT.trim().should.eql(strs[result.rows[j].NUM]); - result.rows[j].CONTENT.trim().length.should.be.exactly(strLen[result.rows[j].NUM]); - } - done(); - } - ); - }); + it('24.1 supports VARCHAR2 data in various lengths', function(done) { + assist.dataTypeSupport(connection, tableName, strs, done); }) -}) + + it('24.2 resultSet stores VARCHAR2 data correctly', function(done) { + assist.resultSetSupport(connection, tableName, strs, done); + }) + + it('24.3 stores null value correctly', function(done) { + assist.nullValueSupport(connection, tableName, done); + }) +}) \ No newline at end of file diff --git a/test/dmlReturning.js b/test/dmlReturning.js index 3aca11ca..4f52f0d5 100644 --- a/test/dmlReturning.js +++ b/test/dmlReturning.js @@ -149,10 +149,10 @@ describe('6. dmlReturning.js', function(){ it('6.1.3 INSERT statement with small maxSize restriction', function(done) { connection.should.be.ok; connection.execute( - "INSERT INTO oracledb_dmlreturn VALUES (1003, 'Robyn Sands') RETURNING id, name INTO :rid, :rname", + "INSERT INTO oracledb_dmlreturn VALUES (1003, 'Robyn Sands Delaware') RETURNING id, name INTO :rid, :rname", { rid: { type: oracledb.NUMBER, dir: oracledb.BIND_OUT }, - rname: { type: oracledb.STRING, dir: oracledb.BIND_OUT, maxSize: 10 } + rname: { type: oracledb.STRING, dir: oracledb.BIND_OUT, maxSize: 2 } }, { autoCommit: true }, function(err, result) { diff --git a/test/examples.js b/test/examples.js index 4effef91..b30cc0fb 100644 --- a/test/examples.js +++ b/test/examples.js @@ -28,7 +28,7 @@ * 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 + * 51 onwards are for other tests * *****************************************************************************/ @@ -60,7 +60,8 @@ describe('3. examples.js', function(){ describe('3.2 version.js', function(){ it('3.2.1 shows the oracledb version attribute', function(){ - (oracledb.version).should.be.a.Number.and.above(0); + (oracledb.version).should.be.a.Number; + (oracledb.version).should.be.greaterThan(0); // console.log("Driver version number is " + oracledb.version); major = Math.floor(oracledb.version/10000); @@ -770,4 +771,137 @@ describe('3. examples.js', function(){ }) }) + describe('3.10 resultset.js', function() { + var connection = false; + + var createTable = + "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 ( \ + employees_id NUMBER, \ + employees_name VARCHAR2(20) \ + ) \ + '); \ + END; "; + + var insertRows = + "DECLARE \ + x NUMBER := 0; \ + n VARCHAR2(20); \ + BEGIN \ + FOR i IN 1..207 LOOP \ + x := x + 1; \ + n := 'staff ' || x; \ + INSERT INTO oracledb_employees VALUES (x, n); \ + END LOOP; \ + END; "; + + before(function(done){ + oracledb.getConnection(credential, function(err, conn){ + if(err) { console.error(err.message); return; } + connection = conn; + connection.execute(createTable, function(err){ + if(err) { console.error(err.message); return; } + connection.execute(insertRows, function(err){ + if(err) { console.error(err.message); return; } + 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.10.1 resultset1.js - getRow() function', function(done) { + connection.should.be.ok; + var rowCount = 1; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: true, prefetchRows: 50 }, + function(err, result) { + should.not.exist(err); + (result.resultSet.metaData[0]).name.should.eql('EMPLOYEES_NAME'); + fetchRowFromRS(connection, result.resultSet); + } + ); + + function fetchRowFromRS(connection, rs) { + rs.getRow(function(err, row) { + should.not.exist(err); + + if(row) { + // console.log(row); + row[0].should.be.exactly('staff ' + rowCount); + rowCount++; + return fetchRowFromRS(connection, rs); + } else { + rs.close(function(err) { + should.not.exist(err); + done(); + }); + } + }); + } + }) + + it('3.10.2 resultset2.js - getRows() function', function(done) { + connection.should.be.ok; + var numRows = 10; // number of rows to return from each call to getRows() + + connection.execute( + "SELECT * FROM oracledb_employees", + [], + { resultSet: true, prefetchRows: 110 }, + function(err, result) { + should.not.exist(err); + (result.resultSet.metaData[0]).name.should.eql('EMPLOYEES_ID'); + (result.resultSet.metaData[1]).name.should.eql('EMPLOYEES_NAME'); + fetchRowsFromRS(connection, result.resultSet); + } + ); + + function fetchRowsFromRS(conn, rs) { + rs.getRows(numRows, function(err, rows) { + should.not.exist(err); + if(rows.length > 0) { + //console.log("length of rows " + rows.length); + //for(var i = 0; i < rows.length; i++) + // console.log(rows[i]); + + return fetchRowsFromRS(conn, rs); + } else { + rs.close(function(err) { + should.not.exist(err); + done(); + }); + } + }); + } + }) + + + }) + }) diff --git a/test/nullColumnValues.js b/test/nullColumnValues.js index 62238b8c..054f1c3f 100644 --- a/test/nullColumnValues.js +++ b/test/nullColumnValues.js @@ -233,4 +233,54 @@ describe('10. nullColumnValues.js', function() { ); }) + it('10.5 resultSet for null value', function(done) { + connection.should.be.ok; + + async.series([ + function(callback) { + connection.execute( + "UPDATE oracledb_departments SET department_name = :dname, \ + manager_id = :mid WHERE department_id = :did ", + { + dname: '', + mid: null, + did: 50 + }, + { autoCommit: true }, + function(err) { + should.not.exist(err); + callback(); + } + ); + }, + function(callback) { + connection.execute( + "SELECT * FROM oracledb_departments WHERE department_id = :1", + [50], + { resultSet: true }, + function(err, result) { + should.not.exist(err); + fetchRowFromRS(result.resultSet); + } + ); + + function fetchRowFromRS(rs) { + rs.getRow(function(err, row) { + should.not.exist(err); + if(row) { + // console.log(row); + row.should.eql([50, null, null, 1500]); + return fetchRowFromRS(rs); + } else { + rs.close(function(err) { + should.not.exist(err); + callback(); + }); + } + }); + } + } + ], done); + }) + }) diff --git a/test/pool.js b/test/pool.js index 2b960eb6..7f4fdb2e 100644 --- a/test/pool.js +++ b/test/pool.js @@ -132,7 +132,7 @@ describe('2. pool.js', function(){ function(err, pool){ if(!credential.externalAuth){ should.exist(err); - (err.message).should.equal('ORA-24413: Invalid number of sessions specified'); + (err.message).should.startWith('ORA-24413:'); } done(); } @@ -155,7 +155,7 @@ describe('2. pool.js', function(){ function(err, pool){ if(!credential.externalAuth){ should.exist(err); - (err.message).should.equal('ORA-24413: Invalid number of sessions specified'); + (err.message).should.startWith('ORA-24413:'); } done(); } @@ -178,7 +178,7 @@ describe('2. pool.js', function(){ function(err, pool){ if(!credential.externalAuth){ should.exist(err); - (err.message).should.equal('ORA-24413: Invalid number of sessions specified'); + (err.message).should.startWith('ORA-24413:'); } done(); } @@ -257,7 +257,7 @@ describe('2. pool.js', function(){ }, function(err, pool){ should.exist(err); - (err.message).should.equal('ORA-24413: Invalid number of sessions specified'); + (err.message).should.startWith('ORA-24413:'); done(); } ); @@ -322,7 +322,7 @@ describe('2. pool.js', function(){ // Error occurs pool.getConnection( function(err, conn3){ should.exist(err); - (err.message).should.equal('ORA-24418: Cannot open further sessions.'); + (err.message).should.startWith('ORA-24418:'); conn2.release( function(err){ should.not.exist(err); @@ -381,7 +381,7 @@ describe('2. pool.js', function(){ }, function(err, pool){ should.exist(err); // Bug 20774464 - Occurs on External Authentication - (err.message).should.equal('ORA-24413: Invalid number of sessions specified'); + (err.message).should.startWith('ORA-24413:'); done(); } ); diff --git a/test/poolValidityAfterFailingTerminate.js b/test/poolValidityAfterFailingTerminate.js index 4bc50548..d3e11d6b 100644 --- a/test/poolValidityAfterFailingTerminate.js +++ b/test/poolValidityAfterFailingTerminate.js @@ -54,7 +54,7 @@ describe('53. poolValidityAfterFailingTernimate.js', function(){ pool.terminate( function(err){ should.exist(err); - (err.message).should.eql('ORA-24422: error occurred while trying to destroy the Session Pool'); + (err.message).should.startWith('ORA-24422:'); // console.log("Before release, Open connections: " + pool.connectionsOpen); connection.release( function(err){ diff --git a/test/releaseAfterFailingTerminate.js b/test/releaseAfterFailingTerminate.js index c583c87e..0dafd4da 100644 --- a/test/releaseAfterFailingTerminate.js +++ b/test/releaseAfterFailingTerminate.js @@ -54,7 +54,7 @@ describe('54. releaseAfterFailingTerminate.js', function(){ pool.terminate( function(err){ should.exist(err); - (err.message).should.eql('ORA-24422: error occurred while trying to destroy the Session Pool'); + (err.message).should.startWith('ORA-24422:'); connection.release( function(err){ should.not.exist(err); diff --git a/test/resultSet.js b/test/resultSet.js deleted file mode 100644 index d5395526..00000000 --- a/test/resultSet.js +++ /dev/null @@ -1,652 +0,0 @@ -/* 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. - * - * NAME - * 12. resultSet.js - * - * DESCRIPTION - * Testing driver resultSet 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('12. resultSet.js', function() { - var connection = false; - - if(dbConfig.externalAuth){ - var credential = { externalAuth: true, connectString: dbConfig.connectString }; - } else { - var credential = dbConfig; - } - - var createTable = - "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 ( \ - employees_id NUMBER, \ - employees_name VARCHAR2(20) \ - ) \ - '); \ - END; "; - - var insertRows = - "DECLARE \ - x NUMBER := 0; \ - n VARCHAR2(20); \ - BEGIN \ - FOR i IN 1..217 LOOP \ - x := x + 1; \ - n := 'staff ' || x; \ - INSERT INTO oracledb_employees VALUES (x, n); \ - END LOOP; \ - END; "; - var rowsAmount = 217; - - before(function(done) { - oracledb.getConnection(credential, function(err, conn) { - if(err) { console.error(err.message); return; } - connection = conn; - connection.execute(createTable, function(err) { - if(err) { console.error(err.message); return; } - connection.execute(insertRows, function(err) { - if(err) { console.error(err.message); return; } - 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(); - }); - } - ); - }) - - describe('12.1 Testing resultSet option', function() { - it('12.1.1 when resultSet option = false, content of result is correct', function(done) { - connection.should.be.ok; - - connection.execute( - "SELECT employees_name FROM oracledb_employees", - [], - { resultSet: false, prefetchRows: 100, maxRows: 1000 }, - function(err, result) { - should.not.exist(err); - - should.exist(result.rows); - result.rows.length.should.be.exactly(rowsAmount); - // console.log(result.rows); - should.not.exist(result.resultSet); - done(); - } - ); - }) - - it('12.1.2 when resultSet option = true, content of result is correct', function(done) { - connection.should.be.ok; - - connection.execute( - "SELECT employees_name FROM oracledb_employees", - [], - { resultSet: true, prefetchRows: 100, maxRows: 1000 }, - function(err, result) { - should.not.exist(err); - - should.not.exist(result.rows); - should.exist(result.resultSet); - done(); - } - ); - }) - - it('12.1.3 when resultSet option = 0, it behaves like false', function(done) { - connection.should.be.ok; - - connection.execute( - "SELECT employees_name FROM oracledb_employees", - [], - { resultSet: 0, prefetchRows: 100, maxRows: 1000 }, - function(err, result) { - should.not.exist(err); - - should.exist(result.rows); - result.rows.length.should.be.exactly(rowsAmount); - // console.log(result.rows); - should.not.exist(result.resultSet); - done(); - } - ); - }) - - it('12.1.4 when resultSet option = null, it behaves like false',function(done) { - connection.should.be.ok; - - connection.execute( - "SELECT employees_name FROM oracledb_employees", - [], - { resultSet: null, prefetchRows: 100, maxRows: 1000 }, - function(err, result) { - should.not.exist(err); - - should.exist(result.rows); - result.rows.length.should.be.exactly(rowsAmount); - should.not.exist(result.resultSet); - done(); - } - ); - }) - - it('12.1.5 when resultSet option = undefined, it behaves like false', function(done) { - connection.should.be.ok; - - connection.execute( - "SELECT employees_name FROM oracledb_employees", - [], - { resultSet: undefined, prefetchRows: 100, maxRows: 1000 }, - function(err, result) { - should.not.exist(err); - - should.exist(result.rows); - result.rows.length.should.be.exactly(rowsAmount); - should.not.exist(result.resultSet); - done(); - } - ); - }) - - it('12.1.6 when resultSet option = NaN, it behaves like false', function(done) { - connection.should.be.ok; - - connection.execute( - "SELECT employees_name FROM oracledb_employees", - [], - { resultSet: NaN, prefetchRows: 100, maxRows: 1000 }, - function(err, result) { - should.not.exist(err); - - should.exist(result.rows); - result.rows.length.should.be.exactly(rowsAmount); - should.not.exist(result.resultSet); - done(); - } - ); - }) - - it('12.1.7 when resultSet option = 1, it behaves like true', function(done) { - connection.should.be.ok; - - connection.execute( - "SELECT employees_name FROM oracledb_employees", - [], - { resultSet: 1, prefetchRows: 100, maxRows: 1000 }, - function(err, result) { - should.not.exist(err); - - should.not.exist(result.rows); - should.exist(result.resultSet); - done(); - } - ); - }) - - it('12.1.8 when resultSet option = -1, it behaves like true', function(done) { - connection.should.be.ok; - - connection.execute( - "SELECT employees_name FROM oracledb_employees", - [], - { resultSet: -1, prefetchRows: 100, maxRows: 1000 }, - function(err, result) { - should.not.exist(err); - - should.not.exist(result.rows); - should.exist(result.resultSet); - done(); - } - ); - }) - - it('12.1.9 when resultSet option is a random string, it behaves like true', function(done) { - connection.should.be.ok; - - connection.execute( - "SELECT employees_name FROM oracledb_employees", - [], - { resultSet: 'foo', prefetchRows: 100, maxRows: 1000 }, - function(err, result) { - should.not.exist(err); - - should.not.exist(result.rows); - should.exist(result.resultSet); - done(); - } - ); - }) - - }) - - describe('12.2 Testing prefetchRows option', function(done) { - it('12.2.1 cannot set prefetchRows to be a negative value', function(done) { - connection.should.be.ok; - - connection.execute( - "SELECT employees_name FROM oracledb_employees", - [], - { resultSet: true, prefetchRows: -10, maxRows: 1000 }, - function(err, result) { - should.exist(err); - err.message.should.startWith('NJS-007: invalid value for "prefetchRows"'); - done(); - } - ); - }) - - it('12.2.2 cannot set prefetchRows to be a random string', function(done) { - connection.should.be.ok; - - connection.execute( - "SELECT employees_name FROM oracledb_employees", - [], - { resultSet: true, prefetchRows: 'bar', maxRows: 1000 }, - function(err, result) { - should.exist(err); - err.message.should.startWith('NJS-008: invalid type for "prefetchRows"'); - done(); - } - ); - }) - - it('12.2.3 cannot set prefetchRows to be NaN', function(done) { - connection.should.be.ok; - - connection.execute( - "SELECT employees_name FROM oracledb_employees", - [], - { resultSet: true, prefetchRows: NaN, maxRows: 1000 }, - function(err, result) { - should.exist(err); - err.message.should.startWith('NJS-007: invalid value for "prefetchRows"'); - done(); - } - ); - }) - - it.skip('12.2.* cannot set prefetchRows to be null', function(done) { - connection.should.be.ok; - - connection.execute( - "SELECT employees_name FROM oracledb_employees", - [], - { resultSet: true, prefetchRows: undefined, maxRows: 1000 }, - function(err, result) { - should.not.exist(err); - console.log(result); - done(); - } - ); - }) - - it.skip('12.* set prefetchRows to be 0', function(done) { - connection.should.be.ok; - - connection.execute( - "SELECT employees_name FROM oracledb_employees", - [], - { resultSet: true, prefetchRows: 0, maxRows: 1000 }, - function(err, result) { - should.not.exist(err); - - console.log(result); - - done(); - } - ); - }) - - }) - - describe('12.3 getRows() function', function() { - it('12.3.1 retrived set is exactly the size of result', function(done) { - connection.should.be.ok; - var nRows = rowsAmount; - var accessRS = 0; - - connection.execute( - "SELECT employees_name FROM oracledb_employees", - [], - { resultSet: true, prefetchRows: 100 }, - function(err, result) { - should.not.exist(err); - processEmp(result.resultSet, nRows); - } - ); - - function processEmp(rs, numRows) { - rs.getRows(numRows, function(err, rows) { - should.not.exist(err); - - if(rows.length > 0) { - accessRS++; - return processEmp(rs, numRows); - } else { - rs.close(function(err) { - should.not.exist(err); - accessRS.should.be.exactly(1); - done(); - }); - } - }); - } - }) - - it('12.3.2 retrived set is greater than the size of result', function(done) { - connection.should.be.ok; - var nRows = rowsAmount * 2; - var accessRS = 0; - - connection.execute( - "SELECT employees_name FROM oracledb_employees", - [], - { resultSet: true, prefetchRows: 100 }, - function(err, result) { - should.not.exist(err); - processEmp(result.resultSet, nRows); - } - ); - - function processEmp(rs, numRows) { - rs.getRows(numRows, function(err, rows) { - should.not.exist(err); - - if(rows.length > 0) { - accessRS++; - return processEmp(rs, numRows); - } else { - rs.close(function(err) { - should.not.exist(err); - accessRS.should.be.exactly(1); - done(); - }); - } - }); - } - }) - - it('12.3.3 retrived set is half of the size of result', function(done) { - connection.should.be.ok; - var nRows = Math.ceil(rowsAmount/2); - var accessRS = 0; - - connection.execute( - "SELECT employees_name FROM oracledb_employees", - [], - { resultSet: true, prefetchRows: 100 }, - function(err, result) { - should.not.exist(err); - processEmp(result.resultSet, nRows); - } - ); - - function processEmp(rs, numRows) { - rs.getRows(numRows, function(err, rows) { - should.not.exist(err); - - if(rows.length > 0) { - accessRS++; - return processEmp(rs, numRows); - } else { - rs.close(function(err) { - should.not.exist(err); - accessRS.should.be.exactly(2); - done(); - }); - } - }); - } - }) - - it('12.3.4 retrived set is one tenth of the size of the result', function(done) { - connection.should.be.ok; - var nRows = Math.ceil(rowsAmount/10); - var accessRS = 0; - - connection.execute( - "SELECT employees_name FROM oracledb_employees", - [], - { resultSet: true, prefetchRows: 100 }, - function(err, result) { - should.not.exist(err); - processEmp(result.resultSet, nRows); - } - ); - - function processEmp(rs, numRows) { - rs.getRows(numRows, function(err, rows) { - should.not.exist(err); - - if(rows.length > 0) { - accessRS++; - return processEmp(rs, numRows); - } else { - rs.close(function(err) { - should.not.exist(err); - accessRS.should.be.exactly(10); - done(); - }); - } - }); - } - }) - - it.skip('12.3.5 Negative - the size of retrived set is 1', function(done) { - connection.should.be.ok; - var nRows = 1; - - connection.execute( - "SELECT employees_name FROM oracledb_employees", - [], - { resultSet: true, prefetchRows: 100 }, - function(err, result) { - should.not.exist(err); - processEmp(result.resultSet, nRows); - } - ); - - function processEmp(rs, numRows) { - rs.getRows(numRows, function(err, rows) { - should.not.exist(err); - - if(rows.length > 0) { - return processEmp(rs, numRows); - } else { - rs.close(function(err) { - should.not.exist(err); - done(); - }); - } - }); - } - }) - - it.skip('12.3.6 Negative - To omit the first parameter', function(done) { - connection.should.be.ok; - - connection.execute( - "SELECT employees_name FROM oracledb_employees", - [], - { resultSet: true, prefetchRows: 100 }, - function(err, result) { - should.not.exist(err); - - /* result.resultSet.getRows(function(err, rows) { - //should.exist(err); - console.log(err); - console.log(rows); - done(); - }); */ - - processEmp(result.resultSet); - } - ); - - function processEmp(rs) { - rs.getRows(function(err, rows) { - should.not.exist(err); - - if(rows.length > 0) { - console.log("length of rows " + rows.length); - for(var i = 0; i < rows.length; i++) - console.log(rows[i]); - - return processEmp(rs); - } else { - rs.close(function(err) { - should.not.exist(err); - done(); - }); - } - }); - } - }) - - it('12.3.7 Negative - set the 1st parameter of getRows() to be 0', function(done) { - connection.should.be.ok; - var nRows = 0; - - connection.execute( - "SELECT employees_name FROM oracledb_employees", - [], - { resultSet: true, prefetchRows: 100 }, - function(err, result) { - should.not.exist(err); - processEmp(result.resultSet, nRows); - } - ); - - function processEmp(rs, numRows) { - rs.getRows(numRows, function(err, rows) { - should.not.exist(err); - - if(rows.length > 0) { - return processEmp(rs, numRows); - } else { - rs.close(function(err) { - should.not.exist(err); - done(); - }); - } - }); - } - }) - - it.skip('12.3.8 Negative - set the 1st parameter of getRows() to be -5', function(done) { - connection.should.be.ok; - var nRows = -5; - - connection.execute( - "SELECT employees_name FROM oracledb_employees", - [], - { resultSet: true, prefetchRows: 100 }, - function(err, result) { - should.not.exist(err); - processEmp(result.resultSet, nRows); - } - ); - - function processEmp(rs, numRows) { - rs.getRows(numRows, function(err, rows) { - should.exist(err); - err.message.should.startWith('NJS-006: invalid type for parameter 1'); - rs.close(function(err) { - should.not.exist(err); - done(); - }); - }); - } - }) - - it.skip('12.3.9 Negative - set the 1st parameter of getRows() to be null', function(done) { - connection.should.be.ok; - var nRows = null; // setting to 'undefined' is the same - - connection.execute( - "SELECT employees_name FROM oracledb_employees", - [], - { resultSet: true, prefetchRows: 100 }, - function(err, result) { - should.not.exist(err); - processEmp(result.resultSet, nRows); - } - ); - - function processEmp(rs, numRows) { - rs.getRows(numRows, function(err, rows) { - should.exist(err); - err.message.should.startWith('NJS-006: invalid type for parameter 1'); - rs.close(function(err) { - should.not.exist(err); - done(); - }); - }); - } - }) - }) - - - - - - - - - - - - - - - - -}) - - diff --git a/test/resultSet1.js b/test/resultSet1.js new file mode 100644 index 00000000..89863379 --- /dev/null +++ b/test/resultSet1.js @@ -0,0 +1,1325 @@ +/* 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 + * 12. resultSet1.js + * + * DESCRIPTION + * Testing driver resultSet 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('12. resultSet1.js', function() { + var connection = false; + + if(dbConfig.externalAuth){ + var credential = { externalAuth: true, connectString: dbConfig.connectString }; + } else { + var credential = dbConfig; + } + + var createTable = + "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 ( \ + employees_id NUMBER, \ + employees_name VARCHAR2(20) \ + ) \ + '); \ + END; "; + + var insertRows = + "DECLARE \ + x NUMBER := 0; \ + n VARCHAR2(20); \ + BEGIN \ + FOR i IN 1..217 LOOP \ + x := x + 1; \ + n := 'staff ' || x; \ + INSERT INTO oracledb_employees VALUES (x, n); \ + END LOOP; \ + END; "; + var rowsAmount = 217; + + before(function(done) { + oracledb.getConnection(credential, function(err, conn) { + if(err) { console.error(err.message); return; } + connection = conn; + connection.execute(createTable, function(err) { + if(err) { console.error(err.message); return; } + connection.execute(insertRows, function(err) { + if(err) { console.error(err.message); return; } + 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(); + }); + } + ); + }) + + describe('12.1 Testing resultSet option', function() { + it('12.1.1 when resultSet option = false, content of result is correct', function(done) { + connection.should.be.ok; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: false, prefetchRows: 100, maxRows: 1000 }, + function(err, result) { + should.not.exist(err); + + should.exist(result.rows); + result.rows.length.should.be.exactly(rowsAmount); + // console.log(result.rows); + should.not.exist(result.resultSet); + done(); + } + ); + }) + + it('12.1.2 when resultSet option = true, content of result is correct', function(done) { + connection.should.be.ok; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: true, prefetchRows: 100, maxRows: 1000 }, + function(err, result) { + should.not.exist(err); + + should.not.exist(result.rows); + should.exist(result.resultSet); + done(); + } + ); + }) + + it('12.1.3 when resultSet option = 0, it behaves like false', function(done) { + connection.should.be.ok; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: 0, prefetchRows: 100, maxRows: 1000 }, + function(err, result) { + should.not.exist(err); + + should.exist(result.rows); + result.rows.length.should.be.exactly(rowsAmount); + // console.log(result.rows); + should.not.exist(result.resultSet); + done(); + } + ); + }) + + it('12.1.4 when resultSet option = null, it behaves like false',function(done) { + connection.should.be.ok; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: null, prefetchRows: 100, maxRows: 1000 }, + function(err, result) { + should.not.exist(err); + + should.exist(result.rows); + result.rows.length.should.be.exactly(rowsAmount); + should.not.exist(result.resultSet); + done(); + } + ); + }) + + it('12.1.5 when resultSet option = undefined, it behaves like false', function(done) { + connection.should.be.ok; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: undefined, prefetchRows: 100, maxRows: 1000 }, + function(err, result) { + should.not.exist(err); + + should.exist(result.rows); + result.rows.length.should.be.exactly(rowsAmount); + should.not.exist(result.resultSet); + done(); + } + ); + }) + + it('12.1.6 when resultSet option = NaN, it behaves like false', function(done) { + connection.should.be.ok; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: NaN, prefetchRows: 100, maxRows: 1000 }, + function(err, result) { + should.not.exist(err); + + should.exist(result.rows); + result.rows.length.should.be.exactly(rowsAmount); + should.not.exist(result.resultSet); + done(); + } + ); + }) + + it('12.1.7 when resultSet option = 1, it behaves like true', function(done) { + connection.should.be.ok; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: 1, prefetchRows: 100, maxRows: 1000 }, + function(err, result) { + should.not.exist(err); + + should.not.exist(result.rows); + should.exist(result.resultSet); + done(); + } + ); + }) + + it('12.1.8 when resultSet option = -1, it behaves like true', function(done) { + connection.should.be.ok; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: -1, prefetchRows: 100, maxRows: 1000 }, + function(err, result) { + should.not.exist(err); + + should.not.exist(result.rows); + should.exist(result.resultSet); + done(); + } + ); + }) + + it('12.1.9 when resultSet option is a random string, it behaves like true', function(done) { + connection.should.be.ok; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: 'foo', prefetchRows: 100, maxRows: 1000 }, + function(err, result) { + should.not.exist(err); + + should.not.exist(result.rows); + should.exist(result.resultSet); + done(); + } + ); + }) + + }) + + describe('12.2 Testing prefetchRows option', function(done) { + it('12.2.1 cannot set prefetchRows to be a negative value', function(done) { + connection.should.be.ok; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: true, prefetchRows: -10, maxRows: 1000 }, + function(err, result) { + should.exist(err); + err.message.should.startWith('NJS-007: invalid value for "prefetchRows"'); + done(); + } + ); + }) + + it('12.2.2 cannot set prefetchRows to be a random string', function(done) { + connection.should.be.ok; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: true, prefetchRows: 'bar', maxRows: 1000 }, + function(err, result) { + should.exist(err); + err.message.should.startWith('NJS-008: invalid type for "prefetchRows"'); + done(); + } + ); + }) + + it('12.2.3 cannot set prefetchRows to be NaN', function(done) { + connection.should.be.ok; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: true, prefetchRows: NaN, maxRows: 1000 }, + function(err, result) { + should.exist(err); + err.message.should.startWith('NJS-007: invalid value for "prefetchRows"'); + done(); + } + ); + }) + + it('12.2.4 cannot set prefetchRows to be null', function(done) { + connection.should.be.ok; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: true, prefetchRows: null, maxRows: 1000 }, + function(err, result) { + should.exist(err); + // console.log(result); + done(); + } + ); + }) + + it('12.2.5 prefetchRows can be set to 0', function(done) { + connection.should.be.ok; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: true, prefetchRows: 0, maxRows: 1000 }, + function(err, result) { + should.not.exist(err); + done(); + } + ); + }) + + }) + + describe('12.3 Testing function getRows()', function() { + it('12.3.1 retrived set is exactly the size of result', function(done) { + connection.should.be.ok; + var nRows = rowsAmount; + var accessCount = 0; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: true, prefetchRows: 100 }, + function(err, result) { + should.not.exist(err); + fetchRowFromRS(result.resultSet, nRows); + } + ); + + function fetchRowFromRS(rs, numRows) { + rs.getRows(numRows, function(err, rows) { + should.not.exist(err); + + if(rows.length > 0) { + accessCount++; + return fetchRowFromRS(rs, numRows); + } else { + rs.close(function(err) { + should.not.exist(err); + accessCount.should.be.exactly(1); + done(); + }); + } + }); + } + }) + + it('12.3.2 retrived set is greater than the size of result', function(done) { + connection.should.be.ok; + var nRows = rowsAmount * 2; + var accessCount = 0; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: true, prefetchRows: 100 }, + function(err, result) { + should.not.exist(err); + fetchRowFromRS(result.resultSet, nRows); + } + ); + + function fetchRowFromRS(rs, numRows) { + rs.getRows(numRows, function(err, rows) { + should.not.exist(err); + + if(rows.length > 0) { + accessCount++; + return fetchRowFromRS(rs, numRows); + } else { + rs.close(function(err) { + should.not.exist(err); + accessCount.should.be.exactly(1); + done(); + }); + } + }); + } + }) + + it('12.3.3 retrived set is half of the size of result', function(done) { + connection.should.be.ok; + var nRows = Math.ceil(rowsAmount/2); + var accessCount = 0; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: true, prefetchRows: 100 }, + function(err, result) { + should.not.exist(err); + fetchRowFromRS(result.resultSet, nRows); + } + ); + + function fetchRowFromRS(rs, numRows) { + rs.getRows(numRows, function(err, rows) { + should.not.exist(err); + + if(rows.length > 0) { + accessCount++; + return fetchRowFromRS(rs, numRows); + } else { + rs.close(function(err) { + should.not.exist(err); + accessCount.should.be.exactly(2); + done(); + }); + } + }); + } + }) + + it('12.3.4 retrived set is one tenth of the size of the result', function(done) { + connection.should.be.ok; + var nRows = Math.ceil(rowsAmount/10); + var accessCount = 0; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: true, prefetchRows: 100 }, + function(err, result) { + should.not.exist(err); + fetchRowFromRS(result.resultSet, nRows); + } + ); + + function fetchRowFromRS(rs, numRows) { + rs.getRows(numRows, function(err, rows) { + should.not.exist(err); + + if(rows.length > 0) { + accessCount++; + return fetchRowFromRS(rs, numRows); + } else { + rs.close(function(err) { + should.not.exist(err); + accessCount.should.be.exactly(10); + done(); + }); + } + }); + } + }) + + it('12.3.5 data in resultSet is array when setting outFormat ARRAY', function(done) { + connection.should.be.ok; + var nRows = Math.ceil(rowsAmount/10); + var accessCount = 0; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: true, prefetchRows: 100, outFormat: oracledb.ARRAY }, + function(err, result) { + should.not.exist(err); + fetchRowFromRS(result.resultSet, nRows); + } + ); + + function fetchRowFromRS(rs, numRows) { + rs.getRows(numRows, function(err, rows) { + should.not.exist(err); + + if(rows.length > 0) { + accessCount++; + for(var i = 0; i < rows.length; i++) + (rows[i]).should.be.an.Array; + + return fetchRowFromRS(rs, numRows); + } else { + rs.close(function(err) { + should.not.exist(err); + accessCount.should.be.exactly(10); + done(); + }); + } + }); + } + }) + + it('12.3.6 data in resultSet is object when setting outFormat OBJECT', function(done) { + connection.should.be.ok; + var nRows = Math.ceil(rowsAmount/10); + var accessCount = 0; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: true, prefetchRows: 100, outFormat: oracledb.OBJECT }, + function(err, result) { + should.not.exist(err); + fetchRowFromRS(result.resultSet, nRows); + } + ); + + function fetchRowFromRS(rs, numRows) { + rs.getRows(numRows, function(err, rows) { + should.not.exist(err); + + if(rows.length > 0) { + accessCount++; + for(var i = 0; i < rows.length; i++) + (rows[i]).should.be.an.Object; + + return fetchRowFromRS(rs, numRows); + } else { + rs.close(function(err) { + should.not.exist(err); + accessCount.should.be.exactly(10); + done(); + }); + } + }); + } + }) + + it('12.3.7 the size of retrived set can be set to 1', function(done) { + connection.should.be.ok; + var nRows = 1; + var accessCount = 0; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: true, prefetchRows: 100 }, + function(err, result) { + should.not.exist(err); + fetchRowFromRS(result.resultSet, nRows); + } + ); + + function fetchRowFromRS(rs, numRows) { + rs.getRows(numRows, function(err, rows) { + should.not.exist(err); + + if(rows.length > 0) { + accessCount++; + return fetchRowFromRS(rs, numRows); + } else { + rs.close(function(err) { + should.not.exist(err); + accessCount.should.be.exactly(rowsAmount); + done(); + }); + } + }); + } + }) + + it('12.3.8 query 0 row', function(done) { + connection.should.be.ok; + var nRows = 5; + var accessCount = 0; + connection.execute( + "SELECT employees_name FROM oracledb_employees WHERE employees_id > 300", + [], + { resultSet: true }, + function(err, result) { + should.not.exist(err); + fetchRowsFromRS(result.resultSet); + } + ); + + function fetchRowsFromRS(rs, numRows) { + rs.getRow(function(err, rows) { + should.not.exist(err); + if(rows) { + accessCount++; + row[0].should.eql('staff ' + accessCount); + row.should.be.an.Array; + return fetchRowsFromRS(rs, numRows); + } else { + rs.close(function(err) { + should.not.exist(err); + accessCount.should.be.exactly(0); + done(); + }); + } + }); + } + }) + + it('12.3.9 Negative - To omit the first parameter', function(done) { + connection.should.be.ok; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: true, prefetchRows: 100 }, + function(err, result) { + should.not.exist(err); + fetchRowFromRS(result.resultSet); + } + ); + + function fetchRowFromRS(rs) { + rs.getRows(function(err, rows) { + should.exist(err); + err.message.should.eql('NJS-009: invalid number of parameters'); + should.not.exist(rows); + rs.close(function(err) { + should.not.exist(err); + done(); + }); + }); + } + }) + + it('12.3.10 Negative - set the 1st parameter of getRows() to be 0', function(done) { + connection.should.be.ok; + var nRows = 0; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: true, prefetchRows: 100 }, + function(err, result) { + should.not.exist(err); + fetchRowFromRS(result.resultSet, nRows); + } + ); + + function fetchRowFromRS(rs, numRows) { + rs.getRows(numRows, function(err, rows) { + should.exist(err); + err.message.should.eql('NJS-005: invalid value for parameter 1'); + rs.close(function(err) { + should.not.exist(err); + done(); + }); + }); + } + }) + + it('12.3.11 Negative - set the 1st parameter of getRows() to be -5', function(done) { + connection.should.be.ok; + var nRows = -5; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: true, prefetchRows: 100 }, + function(err, result) { + should.not.exist(err); + fetchRowFromRS(result.resultSet, nRows); + } + ); + + function fetchRowFromRS(rs, numRows) { + rs.getRows(numRows, function(err, rows) { + should.exist(err); + err.message.should.startWith('NJS-006: invalid type for parameter 1'); + rs.close(function(err) { + should.not.exist(err); + done(); + }); + }); + } + }) + + it('12.3.12 Negative - set the 1st parameter of getRows() to be null', function(done) { + connection.should.be.ok; + var nRows = null; // setting to 'undefined' is the same + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: true, prefetchRows: 100 }, + function(err, result) { + should.not.exist(err); + fetchRowFromRS(result.resultSet, nRows); + } + ); + + function fetchRowFromRS(rs, numRows) { + rs.getRows(numRows, function(err, rows) { + should.exist(err); + err.message.should.startWith('NJS-006: invalid type for parameter 1'); + rs.close(function(err) { + should.not.exist(err); + done(); + }); + }); + } + }) + }) + + describe('12.4 Testing function getRow()', function() { + it('12.4.1 works well with all correct setting', function(done) { + connection.should.be.ok; + var accessCount = 0; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: true, prefetchRows: 100 }, + function(err, result) { + should.not.exist(err); + fetchRowFromRS(result.resultSet); + } + ); + + function fetchRowFromRS(rs) { + rs.getRow(function(err, row) { + should.not.exist(err); + + if(row) { + accessCount++; + row[0].should.eql('staff ' + accessCount); + return fetchRowFromRS(rs); + } else { + rs.close(function(err) { + should.not.exist(err); + accessCount.should.be.exactly(rowsAmount); + done(); + }); + } + }); + } + }) + + it('12.4.2 data in resultSet is array when setting outFormat ARRAY', function(done) { + connection.should.be.ok; + var accessCount = 0; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: true, prefetchRows: 100, outFormat: oracledb.ARRAY }, + function(err, result) { + should.not.exist(err); + fetchRowFromRS(result.resultSet); + } + ); + + function fetchRowFromRS(rs) { + rs.getRow(function(err, row) { + should.not.exist(err); + + if(row) { + accessCount++; + row[0].should.eql('staff ' + accessCount); + row.should.be.an.Array; + return fetchRowFromRS(rs); + } else { + rs.close(function(err) { + should.not.exist(err); + accessCount.should.be.exactly(rowsAmount); + done(); + }); + } + }); + } + }) + + it('12.4.3 data in resultSet is object when setting outFormat OBJECT', function(done) { + connection.should.be.ok; + var accessCount = 0; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: true, prefetchRows: 100, outFormat: oracledb.OBJECT }, + function(err, result) { + should.not.exist(err); + fetchRowFromRS(result.resultSet); + } + ); + + function fetchRowFromRS(rs) { + rs.getRow(function(err, row) { + should.not.exist(err); + + if(row) { + accessCount++; + row.EMPLOYEES_NAME.should.eql('staff ' + accessCount); + row.should.be.an.Object; + return fetchRowFromRS(rs); + } else { + rs.close(function(err) { + should.not.exist(err); + accessCount.should.be.exactly(rowsAmount); + done(); + }); + } + }); + } + }) + + it('12.4.4 query 0 row', function(done) { + connection.should.be.ok; + var accessCount = 0; + connection.execute( + "SELECT employees_name FROM oracledb_employees WHERE employees_id > 300", + [], + { resultSet: true }, + function(err, result) { + should.not.exist(err); + fetchRowFromRS(result.resultSet); + } + ); + + function fetchRowFromRS(rs) { + rs.getRow(function(err, row) { + should.not.exist(err); + if(row) { + accessCount++; + row[0].should.eql('staff ' + accessCount); + row.should.be.an.Array; + return fetchRowFromRS(rs); + } else { + rs.close(function(err) { + should.not.exist(err); + accessCount.should.be.exactly(0); + done(); + }); + } + }); + } + }) + + it('12.4.5 Negative - set the first parameter like getRows()', function(done){ + connection.should.be.ok; + var nRows = 2; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: true, prefetchRows: 100 }, + function(err, result) { + should.not.exist(err); + fetchRowFromRS(result.resultSet, nRows); + } + ); + + function fetchRowFromRS(rs, numRows) { + rs.getRow(numRows, function(err, row) { + should.exist(err); + err.message.should.eql('NJS-009: invalid number of parameters'); + should.not.exist(row); + rs.close(function(err) { + should.not.exist(err); + done(); + }); + }); + } + }) + + }) + + describe('12.5 Testing function close()', function() { + it('12.5.1 does not call close()', function(done) { + connection.should.be.ok; + var nRows = Math.ceil(rowsAmount/10); + var accessCount = 0; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: true, prefetchRows: 100 }, + function(err, result) { + should.not.exist(err); + fetchRowFromRS(result.resultSet, nRows); + } + ); + + function fetchRowFromRS(rs, numRows) { + rs.getRows(numRows, function(err, rows) { + should.not.exist(err); + + if(rows.length > 0) { + accessCount++; + return fetchRowFromRS(rs, numRows); + } else { + accessCount.should.be.exactly(10); + done(); + } + }); + } + }) + + it('12.5.2 invokes close() twice', function(done) { + connection.should.be.ok; + var nRows = Math.ceil(rowsAmount/10); + var accessCount = 0; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: true, prefetchRows: 100 }, + function(err, result) { + should.not.exist(err); + fetchRowFromRS(result.resultSet, nRows); + } + ); + + function fetchRowFromRS(rs, numRows) { + rs.getRows(numRows, function(err, rows) { + should.not.exist(err); + + if(rows.length > 0) { + accessCount++; + return fetchRowFromRS(rs, numRows); + } else { + rs.close(function(err) { + should.not.exist(err); + accessCount.should.be.exactly(10); + rs.close(function(err) { + should.exist(err); + err.message.should.eql("NJS-018: invalid result set"); + done(); + }); + }); + } + }); + } + }) + + it('12.5.3 uses getRows after calling close()', function(done) { + connection.should.be.ok; + var nRows = Math.ceil(rowsAmount/10); + var accessCount = 0; + + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: true, prefetchRows: 100 }, + function(err, result) { + should.not.exist(err); + fetchRowFromRS(result.resultSet, nRows); + } + ); + + function fetchRowFromRS(rs, numRows) { + rs.getRows(numRows, function(err, rows) { + should.not.exist(err); + + if(rows.length > 0) { + accessCount++; + return fetchRowFromRS(rs, numRows); + } else { + rs.close(function(err) { + should.not.exist(err); + rs.getRows(numRows, function(err, rows) { + should.exist(err); + err.message.should.eql("NJS-018: invalid result set"); + done(); + }); + }); + } + }); + } + }) + + it('12.5.4 closes one resultSet and then open another resultSet', function(done) { + connection.should.be.ok; + var nRows = Math.ceil(rowsAmount/10); + var accessCount = 0; + + async.series([ + function(callback) { + connection.execute( + "SELECT employees_name FROM oracledb_employees", + [], + { resultSet: true, prefetchRows: 100 }, + function(err, result) { + should.not.exist(err); + fetchRowFromRS(result.resultSet, nRows, callback); + } + ); + }, + function(callback) { + accessCount = 0; + connection.execute( + "SELECT * FROM oracledb_employees", + [], + { resultSet: true, prefetchRows: 100 }, + function(err, result) { + should.not.exist(err); + fetchRowFromRS(result.resultSet, nRows, callback); + } + ); + } + ], done); + + function fetchRowFromRS(rs, numRows, callback) { + rs.getRows(numRows, function(err, rows) { + should.not.exist(err); + + if(rows.length > 0) { + accessCount++; + return fetchRowFromRS(rs, numRows, callback); + } else { + rs.close(function(err) { + should.not.exist(err); + accessCount.should.be.exactly(10); + callback(); + }); + } + }); + } + }) + + }) + + describe('12.6 Testing metaData', function() { + it('12.6.1 the amount and value of metaData should be correct', function(done) { + connection.should.be.ok; + + /* Helper functions */ + var StringBuffer = function() { + this.buffer = []; + this.index = 0; + }; + + StringBuffer.prototype = { + append: function(s) { + this.buffer[this.index] = s; + this.index += 1; + return this; + }, + + toString: function() { + return this.buffer.join(""); + } + }; + + var createTab = function(size) { + var buffer = new StringBuffer(); + buffer.append("CREATE TABLE oracledb_manycolumns( "); + + for(var i = 0; i < size-1; i++) { + buffer.append("c" + i + " NUMBER, "); + } + buffer.append("c" + (size-1) + " NUMBER"); + buffer.append(" )"); + + return buffer.toString(); + } + /*********************/ + var columnsAmount = 1000; + async.series([ + function(callback) { + var sql = createTab(columnsAmount); + // console.log(sql); + connection.execute( + sql, + function(err) { + should.not.exist(err); + callback(); + } + ); + }, + function(callback){ + connection.execute( + "SELECT * FROM oracledb_manycolumns", + [], + { resultSet: true}, + function(err, result){ + should.not.exist(err); + //console.log(result.resultSet.metaData); + for(var i = 0; i < columnsAmount; i++) { + (result.resultSet.metaData[i].name).should.be.exactly('C' + i); + } + callback(); + } + ); + }, + function(callback) { + connection.execute( + "DROP TABLE oracledb_manycolumns", + function(err) { + should.not.exist(err); + callback(); + } + ); + } + ], done); + }) + + it('12.6.2 can distinguish lower case and upper case', function(done) { + connection.should.be.ok; + var tableName = "oracledb_uppercase"; + var createTable = + " 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 + " ( " + + ' "c" NUMBER, ' + + ' "C" NUMBER ' + + " ) " + + " '); " + + " END; "; + + async.series([ + function(callback) { + connection.execute( + createTable, + function(err) { + should.not.exist(err); + callback(); + } + ); + }, + function(callback) { + connection.execute( + "SELECT * FROM " + tableName, + [], + { resultSet: true }, + function(err, result) { + should.not.exist(err); + // console.log(result.resultSet.metaData); + (result.resultSet.metaData[0].name).should.be.exactly('c'); + (result.resultSet.metaData[1].name).should.be.exactly('C'); + callback(); + } + ); + }, + function(callback) { + connection.execute( + "DROP TABLE " + tableName, + function(err) { + should.not.exist(err); + callback(); + } + ); + } + ], done); + }) + + it('12.6.3 can contain quotes', function(done) { + connection.should.be.ok; + var tableName = "oracledb_quotes"; + var createTable = + " 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 + " ( " + + ' "c' + "''" + '" NUMBER, ' + + ' "c" NUMBER ' + + " ) " + + " '); " + + " END; "; + + async.series([ + function(callback) { + connection.execute( + createTable, + function(err) { + should.not.exist(err); + callback(); + } + ); + }, + function(callback) { + connection.execute( + "SELECT * FROM " + tableName, + [], + { resultSet: true }, + function(err, result) { + should.not.exist(err); + // console.log(result.resultSet.metaData); + (result.resultSet.metaData[0].name).should.be.exactly("c'"); + (result.resultSet.metaData[1].name).should.be.exactly('c'); + callback(); + } + ); + }, + function(callback) { + connection.execute( + "DROP TABLE " + tableName, + function(err) { + should.not.exist(err); + callback(); + } + ); + } + ], done); + }) + + it('12.6.4 can contain underscore', function(done) { + connection.should.be.ok; + var tableName = "oracledb_underscore"; + var createTable = + " 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 + " ( " + + ' "c_" NUMBER, ' + + ' "c__" NUMBER ' + + " ) " + + " '); " + + " END; "; + + async.series([ + function(callback) { + connection.execute( + createTable, + function(err) { + should.not.exist(err); + callback(); + } + ); + }, + function(callback) { + connection.execute( + "SELECT * FROM " + tableName, + [], + { resultSet: true }, + function(err, result) { + should.not.exist(err); + // console.log(result.resultSet.metaData); + (result.resultSet.metaData[0].name).should.be.exactly("c_"); + (result.resultSet.metaData[1].name).should.be.exactly('c__'); + callback(); + } + ); + }, + function(callback) { + connection.execute( + "DROP TABLE " + tableName, + function(err) { + should.not.exist(err); + callback(); + } + ); + } + ], done); + }) + }) + + describe('12.7 Testing maxRows', function() { + it('12.7.1 maxRows option is ignored when resultSet option is true', function(done) { + connection.should.be.ok; + var accessCount = 0; + var rowsLimit = 50; + connection.execute( + "SELECT * FROM oracledb_employees", + [], + { resultSet: true, maxRows: rowsLimit }, + function(err, result) { + should.not.exist(err); + fetchRowFromRS(result.resultSet); + } + ); + function fetchRowFromRS(rs) { + rs.getRow(function(err, row) { + should.not.exist(err); + if(row) { + accessCount++; + return fetchRowFromRS(rs); + } else { + rs.close(function(err) { + should.not.exist(err); + done(); + }); + } + }); + } + }) + }) + +}) + + diff --git a/test/resultSet2.js b/test/resultSet2.js new file mode 100644 index 00000000..3ab390f0 --- /dev/null +++ b/test/resultSet2.js @@ -0,0 +1,508 @@ +/* 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 + * 55. resultSet2.js + * + * DESCRIPTION + * Testing driver resultSet 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('55 resultSet2.js', function() { + + if(dbConfig.externalAuth){ + var credential = { externalAuth: true, connectString: dbConfig.connectString }; + } else { + var credential = dbConfig; + } + + var connection = false; + var createTable = + "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 ( \ + employees_id NUMBER, \ + employees_name VARCHAR2(20) \ + ) \ + '); \ + END; "; + + var insertRows = + "DECLARE \ + x NUMBER := 0; \ + n VARCHAR2(20); \ + BEGIN \ + FOR i IN 1..300 LOOP \ + x := x + 1; \ + n := 'staff ' || x; \ + INSERT INTO oracledb_employees VALUES (x, n); \ + END LOOP; \ + END; "; + var rowsAmount = 300; + + beforeEach(function(done) { + oracledb.getConnection(credential, function(err, conn) { + if(err) { console.error(err.message); return; } + connection = conn; + connection.execute(createTable, function(err) { + if(err) { console.error(err.message); return; } + connection.execute( + insertRows, + [], + { autoCommit: true }, + function(err) { + if(err) { console.error(err.message); return; } + done(); + }); + }); + }); + }) + + afterEach(function(done) { + connection.execute( + 'DROP TABLE oracledb_employees', + function(err) { + if(err) { console.error(err.message); return; } + connection.release(function(err) { + if(err) { console.error(err.message); return; } + done(); + }); + } + ); + }) + + describe('55.1 query a RDBMS function', function() { + it('55.1.1 LPAD function', function(done) { + connection.should.be.ok; + connection.execute( + "select lpad('a',100,'x') from dual", + [], + { resultSet: true }, + function(err, result) { + should.not.exist(err); + fetchRowFromRS(result.resultSet); + } + ); + + function fetchRowFromRS(rs) { + rs.getRow(function(err, row) { + should.not.exist(err); + if(row) { + // console.log(row); + row[0].length.should.be.exactly(100); + return fetchRowFromRS(rs); + } else { + rs.close(function(err) { + should.not.exist(err); + done(); + }); + } + }); + } + }) + }) + + describe('55.2 binding variables', function() { + it('55.2.1 query with one binding variable', function(done) { + connection.should.be.ok; + var rowCount = 0; + connection.execute( + "SELECT * FROM oracledb_employees WHERE employees_id > :1", + [200], + { resultSet: true }, + function(err, result) { + should.not.exist(err); + // console.log(result.resultSet); + fetchRowFromRS(result.resultSet); + } + ); + + function fetchRowFromRS(rs) { + rs.getRow(function(err, row) { + should.not.exist(err); + if(row) { + rowCount++; + return fetchRowFromRS(rs); + } else { + rs.close(function(err) { + rowCount.should.be.exactly(100); + should.not.exist(err); + done(); + }); + } + }); + } + }) + + }) + + describe('55.3 alternating getRow() & getRows() function', function(done) { + it('55.3.1', 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( + "SELECT * FROM oracledb_employees WHERE employees_id > :1", + [200], + { resultSet: true }, + function(err, result) { + should.not.exist(err); + // console.log(result.resultSet); + fetchRowFromRS(result.resultSet); + } + ); + + function fetchRowFromRS(rs) { + if(flag === 1) { + rs.getRow(function(err, row) { + should.not.exist(err); + if(row) { + flag = 2; + accessCount++; + return fetchRowFromRS(rs); + } else { + flag = 3; + return fetchRowFromRS(rs); + } + }); + } + else if(flag === 2) { + rs.getRows(numRows, function(err, rows) { + should.not.exist(err); + if(rows.length > 0) { + flag = 1; + accessCount++; + return fetchRowFromRS(rs); + } else { + flag = 3; + return fetchRowFromRS(rs); + } + }); + } + 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); + done(); + }); + } + } + }) + }) + + describe('55.4 release connetion before close resultSet', function() { + var conn2 = false; + before(function(done) { + oracledb.getConnection( + credential, + function(err, conn) { + should.not.exist(err); + conn2 = conn; + done(); + } + ); + }) + + it('55.4.1 ', function(done) { + conn2.should.be.ok; + conn2.execute( + "SELECT * FROM oracledb_employees", + [], + { resultSet: true }, + function(err, result) { + should.not.exist(err); + fetchRowFromRS(result.resultSet); + } + ); + + function fetchRowFromRS(rs) { + rs.getRow(function(err, row) { + should.not.exist(err); + if(row) { + return fetchRowFromRS(rs); + } else { + conn2.release(function(err) { + should.not.exist(err); + rs.close(function(err) { + should.exist(err); + err.message.should.startWith('NJS-003'); + done(); + }); + }); + } + + }); + } + }) + }) + + describe('55.5 the content of resultSet should be consistent', function() { + it('55.5.1 (1) get RS (2) modify data in that table and commit (3) check RS', function(done) { + connection.should.be.ok; + var rowsCount = 0; + var rs = false; + async.series([ + function(callback) { + connection.execute( + "SELECT * FROM oracledb_employees", + [], + { resultSet: true }, + function(err, result) { + should.not.exist(err); + rs = result.resultSet; + callback(); + } + ); + }, + function(callback) { + connection.execute( + "TRUNCATE TABLE oracledb_employees", + [], + { autoCommit: true }, + function(err) { + should.not.exist(err); + callback(); + } + ); + }, + function(callback) { + fetchRowFromRS(rs, callback); + } + ], done); + + function fetchRowFromRS(rset, cb) { + rs.getRow(function(err, row) { + should.not.exist(err); + if(row) { + rowsCount++; + return fetchRowFromRS(rset, cb); + } else { + rs.close(function(err) { + should.not.exist(err); + rowsCount.should.eql(rowsAmount); + cb(); + }); + } + }); + } + + }) + }) + + describe('55.6 access resultSet simultaneously', function() { + it('55.6.1 concurrent operations on resultSet are not allowed', function(done) { + connection.should.be.ok; + var rowCount1 = 0; + var rowCount2 = 0; + var numRows = 10; // number of rows to return from each call to getRows() + connection.execute( + "SELECT * FROM oracledb_employees", + [], + { resultSet: true }, + function(err, result) { + should.not.exist(err); + async.parallel([ + function(callback) { + fetchRowFromRS(result.resultSet, callback); + }, + function(callback) { + fetchRowsFromRS(result.resultSet, callback); + } + ], function(err) { + if(err) { + // console.log(err); + err.message.should.startWith('NJS-017'); + result.resultSet.close(function(err) { + done(); + }); + } else { + result.resultSet.close(function(error) { + should.not.exist(error); + done(); + }); + } + }); + } + ); + + 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(); + } + } + }); + } + }) + }) + + describe('55.7 getting multiple resultSets', function() { + it('55.7.1 can access multiple resultSet on one connection', function(done) { + connection.should.be.ok; + var rowCount1 = 0; + var rowCount2 = 0; + var numRows = 10; // number of rows to return from each call to getRows() + async.parallel([ + function(callback) { + connection.execute( + "SELECT * FROM oracledb_employees", + [], + { resultSet: true }, + function(err, result) { + should.not.exist(err); + fetchRowFromRS(result.resultSet, callback); + } + ); + }, + function(callback) { + connection.execute( + "SELECT * FROM oracledb_employees", + [], + { resultSet: true }, + function(err, result) { + should.not.exist(err); + fetchRowsFromRS(result.resultSet, callback); + } + ); + } + ], function(err) { + should.not.exist(err); + done(); + }); + + function fetchRowFromRS(rs, cb) { + rs.getRow(function(err, row) { + should.not.exist(err); + if(row) { + rowCount1++; + return fetchRowFromRS(rs, cb); + } else { + rs.close(function(err) { + should.not.exist(err); + cb(); + }); + } + }); + } + + function fetchRowsFromRS(rs, cb) { + rs.getRows(numRows, function(err, rows) { + should.not.exist(err); + if(rows.length > 0) { + rowCount2 += numRows; + return fetchRowsFromRS(rs, cb); + } else { + rs.close(function(err) { + should.not.exist(err); + cb(); + }); + } + + }); + } + }) + }) + + describe('55.8 Negative - resultSet is only for query statement', function() { + it('55.8.1 resultSet cannot be returned for non-query statements', function(done) { + connection.should.be.ok; + connection.execute( + "UPDATE oracledb_employees SET employees_name = 'Alan' WHERE employees_id = 100", + [], + { resultSet: true }, + function(err, result) { + should.exist(err); + // console.log(err); + err.message.should.startWith('NJS-019'); + done(); + } + ); + + }) + }) + +}) + + + + + + + + + + + + + + + + + + +