UNPKG

jsharmony-db-iseries

Version:

jsHarmony Database Connector for DB2/iSeries

322 lines (291 loc) 13.8 kB
/* Copyright 2022 apHarmony This file is part of jsHarmony. jsHarmony is free software: you can redistribute it and/or modify it.skip under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. jsHarmony is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this package. If not, see <http://www.gnu.org/licenses/>. */ var JSHiseries = require('../index'); var JSHdb = require('jsharmony-db'); var types = JSHdb.types; var assert = require('assert'); var _ = require('lodash'); //var moment = require('moment'); var initialdbconfig = require('./dbconfig'); var driver = new JSHiseries(); driver.platform.Config.debug_params.db_error_sql_state = true; driver.platform.Config.debug_params.db_raw_sql = true; //driver.platform.Config.debug_params.db_perf_reporting = true; var dbconfig = _.extend({_driver: driver, connectionString: "DSN=ODBC;Uid=DBUSER;pwd=DBPASS", initialSize: 1, options: {pooled: true} }, initialdbconfig); describe('Driver',function(){ this.timeout(9000); after(function(done){ driver.Close(done); }); it('ExecError', function (done) { driver.ExecError({detail: 'detail', position: 5}, function(err, value) { assert.ok(err, "callback with err"); assert.ok(!value, "callback without value"); done(); }, "prefix", "some code"); }); it('ExecError prefix stripping', function (done) { driver.ExecError({ odbcErrors: [ { state: 'HY000', code: -104, message: '[IBM][System i Access ODBC Driver][DB2 for i5/OS]SQL0104 - Token <END-OF-STATEMENT> was not valid. Valid tokens: + - AS <IDENTIFIER>.' }, { state: 'HY000', code: 69898, message: '[IBM][System i Access ODBC Driver][DB2 for i5/OS]PWS0005 - Error occurred in the database host server code.' } ] }, function(err, value) { console.log(err); assert.ok(err.message.match('Token'), "has message"); assert.ok(!err.message.match('host server code'), "does not have generic error"); assert.ok(!err.message.match('System i'), "Does not have prefix"); done(); }, "prefix", "some code"); }); it('logRawSQL', function () { var before = driver.platform.Config.debug_params.db_raw_sql; driver.platform.Config.debug_params.db_raw_sql = true; driver.logRawSQL("some code"); driver.platform.Config.debug_params.db_raw_sql = before; }); it('ExecSession: unpooled', function(done) { var config = _.extend({_driver: driver, connectionString: "DSN=ODBC;Uid=DBUSER;pwd=DBPASS", initialSize: 1 }, initialdbconfig); driver.ExecSession(null, config, function(err, con, preStatements, conComplete) { if(err) return done(err); assert.ok(con, "got a connection"); assert.ok("caller" in conComplete, "got a callback"); conComplete(err, 'result'); }, done); }); it('ExecSession: pooled', function(done) { driver.ExecSession(null, dbconfig, function(err, con, preStatements, conComplete) { if(err) return done(err); assert.ok(con, "got a connection"); assert.ok("caller" in conComplete, "got a callback"); conComplete(err, 'result'); }, done); }); it('escape', function() { assert.equal(driver.sql.escape(), ''); assert.equal(driver.sql.escape(0), 0); assert.equal(driver.sql.escape(''), ''); assert.equal(driver.sql.escape('\t'), '\t'); assert.equal(driver.sql.escape('\x00'), ''); assert.equal(driver.sql.escape('don\'t'), 'don\'\'t'); }); describe('getDBParam', function() { it('NULL', function() { assert.equal(driver.getDBParam(types.VarChar(), null), 'NULL'); assert.equal(driver.getDBParam(types.VarChar(), undefined), 'NULL'); }); it('VarChar/Char', function() { assert.equal(driver.getDBParam(types.VarChar(10), 'hi'), "'hi'"); assert.equal(driver.getDBParam(types.VarChar(1), 'hi'), "'h'"); assert.equal(driver.getDBParam(types.VarChar(types.MAX), 'hi'), "'hi'"); assert.equal(driver.getDBParam(types.VarChar(), ''), "''"); assert.equal(driver.getDBParam(types.VarChar(), 'don\'t'), "'don''t'"); assert.equal(driver.getDBParam(types.Char(10), 'hi'), "'hi'"); }); it('VarBinary', function() { assert.equal(driver.getDBParam(types.VarBinary(10), 'hi'), "BX'6869'"); assert.equal(driver.getDBParam(types.VarBinary(1), 'hi'), "BX'6869'"); // ???? assert.equal(driver.getDBParam(types.VarBinary(types.MAX), 'hi'), "BX'6869'"); assert.equal(driver.getDBParam(types.VarBinary(), ''), "BX''"); assert.equal(driver.getDBParam(types.VarBinary(), 'don\'t'), "BX'646F6E2774'"); }); it('Ints', function() { assert.equal(driver.getDBParam(types.BigInt, 0), "0"); assert.equal(driver.getDBParam(types.Int, -123456), "-123456"); assert.equal(driver.getDBParam(types.SmallInt, "123456"), "123456"); assert.equal(driver.getDBParam(types.TinyInt, 1/0), "NULL"); }); it('Bools', function() { assert.equal(driver.getDBParam(types.Boolean, true), "1"); assert.equal(driver.getDBParam(types.Boolean, false), "0"); assert.equal(driver.getDBParam(types.Boolean, null), "NULL"); }); it('Decimal', function() { assert.equal(driver.getDBParam(types.Decimal(15, 0), 0), "0"); assert.equal(driver.getDBParam(types.Decimal(10, 10), 3.14), "3.14"); }); it('Float', function() { assert.equal(driver.getDBParam(types.Float(15), 0), "0"); assert.equal(driver.getDBParam(types.Float(10), 3.14), "3.14"); }); it('Date', function() { assert.equal(driver.getDBParam(types.Date, 0), "DATE('1970-01-01')", 'number'); assert.equal(driver.getDBParam(types.Date, new Date(2022, 0, 27)), "DATE('2022-01-27')", 'date'); assert.equal(driver.getDBParam(types.Date, "2022-01-27"), "DATE('2022-01-26')", 'string'); // strings utc }); it('Time', function() { assert.equal(driver.getDBParam(types.Time(), 0), "TIME('00.00.00')", 'number'); assert.equal(driver.getDBParam(types.Time(), new Date(2022, 0, 27, 1, 2, 3)), "TIME('01.02.03')", 'date'); assert.equal(driver.getDBParam(types.Time(), "2022-01-27 01:02:03"), "TIME('01.02.03')", 'string'); }); it('DateTime', function() { assert.equal(driver.getDBParam(types.DateTime(), 0), "TIMESTAMP('1970-01-01 00:00:00.000')", 'number'); assert.equal(driver.getDBParam(types.DateTime(), new Date(2022, 0, 27, 1, 2, 3)), "TIMESTAMP('2022-01-27 01:02:03.000')", 'date'); assert.equal(driver.getDBParam(types.DateTime(), "2022-01-27 01:02:03"), "TIMESTAMP('2022-01-27 01:02:03.000')", 'string'); }); }); it('applySQLParams', function() { assert.equal(driver.applySQLParams("select @one", [types.BigInt], {one: 1}), "select 1"); assert.equal(driver.applySQLParams("select @one, @two", [types.VarChar(), types.DateTime()], {one: 'one', two: "2022-01-27 01:02:03"}), "select 'one', TIMESTAMP('2022-01-27 01:02:03.000')"); }); it('ExecStatement - select', function(done) { driver.ExecSession(null, dbconfig, function(err, con, presql, conComplete) { console.log('------------------------1', err); if(err) return conComplete(err); driver.ExecStatement(con, dbconfig, "SELECT 1 AS ONE FROM SYSIBM.SYSDUMMY1", function(err, result) { console.log('-------------------2', err); if(err) return conComplete(err); assert(result, 'result is not null'); assert.equal(result.rows.length, 1); assert.equal(result.rows[0].ONE, 1); conComplete(err, 'result'); }); }, done); }); it('ExecStatement - select trim', function(done) { driver.ExecSession(null, dbconfig, function(err, con, presql, conComplete) { assert.ifError(err); driver.ExecStatement(con, dbconfig, "SELECT 'hi ' AS ONE FROM SYSIBM.SYSDUMMY1", function(err, result) { if (err) return done(err); assert.equal(result.rows[0].ONE, 'hi'); conComplete(err, 'result'); }); }, done); }); it('ExecStatement - other', function(done) { driver.ExecSession(null, dbconfig, function(err, con, presql, conComplete) { if(err) return conComplete(err); driver.ExecStatement(con, dbconfig, "DECLARE GLOBAL TEMPORARY TABLE SESSION.JSHARMONY_META AS (SELECT 'USystem' CONTEXT FROM SYSIBM.SYSDUMMY1) WITH DATA WITH REPLACE", function(err, result) { if(err) return conComplete(err); assert.equal(result.rows, null); conComplete(err, 'result'); }); }, done); }); it('ExecStatements - select', function(done) { driver.ExecSession(null, dbconfig, function(err, con, presql, conComplete) { if(err) return conComplete(err); driver.ExecStatements(con, dbconfig, ["SELECT 1 AS ONE FROM SYSIBM.SYSDUMMY1", "SELECT 2 AS TWO FROM SYSIBM.SYSDUMMY1"], function(err, results) { if(err) return conComplete(err); assert.equal(results.length, 2); assert.equal(results[0][0].ONE, 1); assert.equal(results[1][0].TWO, 2); conComplete(err, 'result'); }); }, done); }); it('ExecStatements - other and select', function(done) { driver.ExecSession(null, dbconfig, function(err, con, presql, conComplete) { if(err) return conComplete(err); driver.ExecStatements(con, dbconfig, ["DECLARE GLOBAL TEMPORARY TABLE SESSION.JSHARMONY_META AS (SELECT 'USystem' CONTEXT FROM SYSIBM.SYSDUMMY1) WITH DATA WITH REPLACE", "SELECT 1 AS ONE FROM SYSIBM.SYSDUMMY1"], function(err, results) { console.log(results); if(err) return conComplete(err); assert.equal(results.length, 1); assert.equal(results[0][0].ONE, 1); conComplete(err, 'result'); }); }, done); }); describe('getContextStatements', function() { it('with context', function() { var context = driver.getContextStatements('S1', {}); assert(context.length > 0); assert(_.some(context, function(statement) {return statement.match('S1');})); }); it('without context', function() { var context = driver.getContextStatements('', {}); assert(context.length == 0); }); it('meta once', function() { var con = {}; var context1 = driver.getContextStatements('S1', con); var context2 = driver.getContextStatements('S1', con); assert.equal(context1.length, 2); assert.equal(context2.length, 1); assert(_.some(context1, function(statement) {return statement.match('S1');})); assert(_.some(context2, function(statement) {return statement.match('S1');})); }); }); describe('splitSQL', function() { it('plain statement', function() { var statements = JSHiseries._splitSQL('select 1'); assert.equal(statements.length, 1); assert.equal(statements[0], 'select 1'); }); it('trailing semicolon', function() { var statements = JSHiseries._splitSQL('select 1;'); assert.equal(statements.length, 1); assert.equal(statements[0], 'select 1'); }); it('multiple statements', function() { var statements = JSHiseries._splitSQL('select 1; select 2'); assert.equal(statements.length, 2); assert.equal(statements[0], 'select 1'); }); it('embedded begin-end', function() { var statements = JSHiseries._splitSQL('BEGIN select 1\\; END'); assert.equal(statements.length, 1); assert.equal(statements[0], 'BEGIN select 1; END'); }); }); it('Exec: scalar', function(done) { driver.Exec(null, 'S1`', 'scalar', "SELECT 1 AS ONE FROM SYSIBM.SYSDUMMY1", [], {}, function(err, result, other) { if(err) return done(err); assert.equal(result, 1); done(); }, dbconfig); }); it('Exec: row', function(done) { driver.Exec(null, 'S1`', 'row', "SELECT 1 AS ONE, 2 AS TWO FROM SYSIBM.SYSDUMMY1", [], {}, function(err, result, other) { if(err) return done(err); assert.equal(result.ONE, 1); assert.equal(result.TWO, 2); done(); }, dbconfig); }); it('Exec: row - returns xrowcount for other statements', function(done) { driver.Exec(null, 'S1`', 'row', "UPDATE SESSION.JSHARMONY_META SET CONTEXT = 'S1'; return_row_count()", [], {}, function(err, result, other) { console.log(err, result, other); if (err) return done(err); assert.equal(result.xrowcount, 1); done(); }, dbconfig); }); it('Exec: recordset', function(done) { driver.Exec(null, 'S1`', 'recordset', "SELECT 1 AS ONE FROM SYSIBM.SYSDUMMY1", [], {}, function(err, result, other) { if(err) return done(err); assert.equal(result.length, 1); assert.equal(result[0].ONE, 1); done(); }, dbconfig); }); it('Exec: multirecordset', function(done) { driver.Exec(null, 'S1`', 'multirecordset', "SELECT 1 AS ONE FROM SYSIBM.SYSDUMMY1; SELECT 2 AS TWO FROM SYSIBM.SYSDUMMY1", [], {}, function(err, result, other) { if(err) return done(err); assert.equal(result.length, 2); assert.equal(result[0][0].ONE, 1); assert.equal(result[1][0].TWO, 2); done(); }, dbconfig); }); });