Skip to content

feat: Ability to pass in odbc connection to transport #320

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/Connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const availableTransports = {
* @property {string} [ipc=*NA] - The key name/security route to XMLSERVICE job. Default is ``*NA``.
* @property {string} [ctl=*here] - The control options for XMLSERVICE jobs. Default is ``*here``.
* @property {string} [xslib=QXMLSERV] - The XMLSERVICE library. Default is ``QXMLSERV``.
* @property {object} [odbcConnection] - An existing odbc connection already connected to the db.
*/

/**
Expand Down
128 changes: 85 additions & 43 deletions lib/transports/odbcTransport.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,62 @@ try {
}
}

/**
* Function to call xmlservice regardless if an existing connection was passed
* @private
* @param {Object} parameters - Arguments to call xml service procedure
*/
function callXmlService(parameters) {
const {
connection,
sql,
queryParameters,
done,
shouldCloseConnection,
verbose,
} = parameters;

if (verbose) {
console.log(`SQL to run is ${sql}`);
}

connection.query(sql, queryParameters, (queryError, results) => {
if (queryError) {
done(queryError, null);
return;
}
let xmlOutput = '';

if (!results) {
done('Empty result set was returned', null);
return;
}

results.forEach((chunk) => {
xmlOutput += chunk.OUT151;
});

if (shouldCloseConnection) {
connection.close((closeError) => {
if (closeError) {
done(closeError, null);
return;
}
done(null, xmlOutput);
});
} else {
done(null, xmlOutput);
}
});
}

/**
* @private
* @param {object} config - Configuration options for odbc transport
* @param {string} xmlIn - The xml input to run with xml service
* @param {function} done - User defined callback to invoke when completed
*/

function odbcCall(config, xmlInput, done) {
// odbc transport is not available bail out
if (odbc === null) {
Expand All @@ -28,59 +84,45 @@ function odbcCall(config, xmlInput, done) {
xslib = 'QXMLSERV',
verbose = false,
dsn = null,
odbcConnection = null,
} = config;

const sql = `call ${xslib}.iPLUGR512K(?,?,?)`;
const driver = 'IBM i Access ODBC Driver';
let connectionString;
const queryParameters = [ipc, ctl, xmlInput];
const parameters = {
sql, queryParameters, done, verbose, shouldCloseConnection: !odbcConnection,
};

if (dsn && typeof dsn === 'string') {
connectionString = `DSN=${dsn}`;
} else {
connectionString = `DRIVER=${driver};SYSTEM=${host};`;
if (!odbcConnection) { // get a connection then call xml service
// generate connection string
let connectionString;

if (username && typeof username === 'string') {
connectionString += `UID=${username};`;
}
if (password && typeof password === 'string') {
connectionString += `PWD=${password};`;
}
}

if (verbose) {
console.log(`SQL to run is ${sql}`);
}
if (dsn && typeof dsn === 'string') {
connectionString = `DSN=${dsn}`;
} else {
connectionString = `DRIVER=IBM i Access ODBC Driver;SYSTEM=${host};`;

odbc.connect(connectionString, (connectError, connection) => {
if (connectError) {
done(connectError, null);
return;
if (username && typeof username === 'string') {
connectionString += `UID=${username};`;
}
if (password && typeof password === 'string') {
connectionString += `PWD=${password};`;
}
}
connection.query(sql, [ipc, ctl, xmlInput], (queryError, results) => {
if (queryError) {
done(queryError, null);

// connect and call xmlservice
odbc.connect(connectionString, (connectError, connection) => {
if (connectError) {
done(connectError, null);
return;
}
connection.close((closeError) => {
if (closeError) {
done(closeError, null);
return;
}

if (!results) {
done('Empty result set was returned', null);
return;
}

let xmlOutput = '';

results.forEach((chunk) => {
xmlOutput += chunk.OUT151;
});
done(null, xmlOutput);
});
parameters.connection = connection;
callXmlService(parameters);
});
});
} else { // passed in connection should already be connected
parameters.connection = odbcConnection;
callXmlService(parameters);
}
}

exports.odbcCall = odbcCall;