From fb66fdab880dc3a4cf1a10d5a739b005c9930d0c Mon Sep 17 00:00:00 2001 From: Mark Irish Date: Fri, 13 Mar 2020 10:27:31 -0500 Subject: [PATCH 1/4] [issue97] Add DataQueue class Add a DataQueue class that can be called similar to the Java toolkit Experiment with pulling out API data into a const variable --- lib/DataQueue.js | 207 +++++++++++++++++++++++++++++++++++++++++++++++ lib/itoolkit.js | 2 + 2 files changed, 209 insertions(+) create mode 100644 lib/DataQueue.js diff --git a/lib/DataQueue.js b/lib/DataQueue.js new file mode 100644 index 00000000..ae558a2b --- /dev/null +++ b/lib/DataQueue.js @@ -0,0 +1,207 @@ +const { ProgramCall } = require('./ProgramCall'); +const { CommandCall } = require('./CommandCall'); +const { xmlToJson } = require('./utils'); + +// QRCVDTAQ Parameters +const QRCVDTAQParameters = { + DataQueueName: { io: 'in', type: '10A' }, + LibraryName: { io: 'in', type: '10A' }, + LengthOfData: { io: 'in', type: '5p0' }, + Data: { io: 'out', type: '10A' }, + WaitTime: { io: 'in', type: '5p0' } +} + +class DataQueue { + /** + * @description Creates a new DataQueue object + * @constructor + * @param {object} connection + * @param {string} name + * @param {string} library + */ + constructor(connection, name, library = '') { + this.connection = connection; + + if (name.length > 10) { + throw Error("DataQueue name must be 10 or fewer characters long."); + } + + if (library.length > 10) { + throw Error("DataQueue library must be 10 of fewer characers long."); + } + + this.name = name; + this.library = library ? library : '*CURLIB'; + this.qualifiedName = this.name.padEnd(10, ' ') + this.library.padEnd(10, ' '); + this.maxLength = undefined; + } + + ////////////////////////////////////////////////////////////////////////////// + // Create Data Queue (CLDTAQ) CL Command + ////////////////////////////////////////////////////////////////////////////// + /** + * @description Creates a Data Queue on the system of the connection passed in + * the constructor. + * @constructor + * @param {number} maxLength + * @param {function} callback + */ + create(maxLength, callback) { + console.log(CommandCall.CommandCall); + this.maxLength = maxLength; + const commandConfig = { + type: 'cl', + command: `CRTDTAQ DTAQ(${this.library ? `${this.library}/` : ''}${this.name}) MAXLEN(${this.maxLength})` + } + + this.connection.add(new CommandCall(commandConfig)); + this.connection.run((error, xmlOutput) => { + if (error) { + return callback(error); + } + + const result = xmlToJson(xmlOutput); + callback(null, result); + }); + } + + ////////////////////////////////////////////////////////////////////////////// + // Delete Data Queue (DLTDTAQ) CL Command + ////////////////////////////////////////////////////////////////////////////// + delete(callback) { + const commandConfig = { + type: 'cl', + command: `DLTDTAQ DTAQ(${this.library ? `${this.library}/`: ''}${this.name})` + } + + this.connection.add(new CommandCall(commandConfig)); + this.connection.run((error, xmlOutput) => { + if (error) { + return callback(error); + } + + const result = xmlToJson(xmlOutput); + callback(null, result); + }); + } + + ////////////////////////////////////////////////////////////////////////////// + // Receive Data Queue (QRCVDTAQ) API + ////////////////////////////////////////////////////////////////////////////// + + async receive(wait, length, callback) { + if (typeof wait === 'function') { + callback = wait; + wait = 0; + } + + if (length == undefined) { + if (this.maxLength == undefined) { + const description = await this._getDataQueueDescription(); + this.maxLength = description[0].data[2].value; + } + + length = this.maxLength; + } + + const program = new ProgramCall('QRCVDTAQ', { lib: 'QSYS' }); + + program.addParam(this.name, QRCVDTAQParameters.DataQueueName.type, { io: QRCVDTAQParameters.DataQueueName.io }); + program.addParam(this.library, QRCVDTAQParameters.LibraryName.type, { io: QRCVDTAQParameters.LibraryName.io }); + program.addParam(length, QRCVDTAQParameters.LengthOfData.type, { io: QRCVDTAQParameters.LengthOfData.io }); + program.addParam('', `${this.maxLength}A`, { io: QRCVDTAQParameters.Data.io }); + program.addParam(wait, QRCVDTAQParameters.WaitTime.type, { io: QRCVDTAQParameters.WaitTime.io }); + + this.connection.add(program) + this.connection.run((error, xmlOutput) => { + if (error) { + return callback(error, null); + } + const result = xmlToJson(xmlOutput); + const data = result[0].data[0].value; + return callback(null, data); + }); + } + + // alias for receive, as the API is "RCV", but jt400 uses the term "read" + async read(wait, callback) { + return this.receive(wait, callback); + } + + ////////////////////////////////////////////////////////////////////////////// + // Send Data Queue (QSNDDTAQ) API + ////////////////////////////////////////////////////////////////////////////// + + async send(data, callback) { + const program = new ProgramCall('QSNDDTAQ', { lib: 'QSYS' }); + program.addParam(this.name, '10A'); // Data queue name + program.addParam(this.library, '10A'); // Library name + program.addParam(data.length, '5p0'); // Length of data + program.addParam(data, `${data.length}A`); // Data + + this.connection.add(program) + this.connection.run((error, xmlOutput) => { + if (error) { + return callback(error, null); + } + const result = xmlToJson(xmlOutput); + return callback(null, result); + }); + } + + async write(data, callback) { + return this.write(data, callback); + } + + ////////////////////////////////////////////////////////////////////////////// + // Clear Data Queue (QCLRDTAQ) API + ////////////////////////////////////////////////////////////////////////////// + + async clear() { + const program = new ProgramCall('QCLRDTAQ', { lib: 'QSYS' }); + program.addParam(this.name, '10A'); // Data queue name + program.addParam(this.library, '10A'); // Library name + + this.connection.add(program) + this.connection.run((error, xmlOutput) => { + if (error) { + return callback(error, null); + } + const result = xmlToJson(xmlOutput); + return callback(null, result); + }); + } + + ////////////////////////////////////////////////////////////////////////////// + // "Private" Functions + ////////////////////////////////////////////////////////////////////////////// + + + async _getDataQueueDescription(callback) { + const program = new ProgramCall('QMHQRDQD', { lib: 'QSYS' }); + + const receiverVariable = [ + [0, '10i0'], + [0, '10i0'], + [0, '10i0'] + ]; + + program.addParam(receiverVariable, { io: 'out', len: 'varLen'}); // Receiver variable + program.addParam(0, '10i0', { setlen: 'varLen'}); // Length of receiver variable + program.addParam('RDQD0100', '8A'); // Format name + program.addParam(this.qualifiedName, '20A'); // Qualified data queue name + + this.connection.add(program) + this.connection.run((error, xmlOutput) => { + if (error) { + return callback(error, null); + } + + const result = xmlToJson(xmlOutput); + this.maxLength = result[0].data[2].value + return callback(null, result); + }); + } +} + +module.exports.DataQueue = DataQueue; diff --git a/lib/itoolkit.js b/lib/itoolkit.js index 68432a43..230b2425 100644 --- a/lib/itoolkit.js +++ b/lib/itoolkit.js @@ -26,6 +26,7 @@ const { CommandCall } = require('./CommandCall'); const { Connection } = require('./Connection'); const { Toolkit } = require('./Toolkit'); const { xmlToJson } = require('./utils'); +const { DataQueue } = require('./DataQueue'); const { iPgm, @@ -49,6 +50,7 @@ module.exports = { Connection, Toolkit, xmlToJson, + DataQueue, // deprecated exports below, replaced by functionality above iCmd, iConn, From 22a78852a19a568446fbf130c6341f055feb8dfe Mon Sep 17 00:00:00 2001 From: Mark Irish Date: Mon, 30 Mar 2020 08:19:06 -0500 Subject: [PATCH 2/4] DataQueue: remove some log statements --- lib/DataQueue.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/DataQueue.js b/lib/DataQueue.js index ae558a2b..ccd28961 100644 --- a/lib/DataQueue.js +++ b/lib/DataQueue.js @@ -6,7 +6,7 @@ const { xmlToJson } = require('./utils'); const QRCVDTAQParameters = { DataQueueName: { io: 'in', type: '10A' }, LibraryName: { io: 'in', type: '10A' }, - LengthOfData: { io: 'in', type: '5p0' }, + LengthOfData: { io: 'out', type: '5p0' }, Data: { io: 'out', type: '10A' }, WaitTime: { io: 'in', type: '5p0' } } @@ -46,8 +46,7 @@ class DataQueue { * @param {number} maxLength * @param {function} callback */ - create(maxLength, callback) { - console.log(CommandCall.CommandCall); + async create(maxLength, callback) { this.maxLength = maxLength; const commandConfig = { type: 'cl', @@ -68,7 +67,7 @@ class DataQueue { ////////////////////////////////////////////////////////////////////////////// // Delete Data Queue (DLTDTAQ) CL Command ////////////////////////////////////////////////////////////////////////////// - delete(callback) { + async delete(callback) { const commandConfig = { type: 'cl', command: `DLTDTAQ DTAQ(${this.library ? `${this.library}/`: ''}${this.name})` @@ -118,7 +117,7 @@ class DataQueue { return callback(error, null); } const result = xmlToJson(xmlOutput); - const data = result[0].data[0].value; + const data = result[0].data[1].value; return callback(null, data); }); } @@ -186,8 +185,8 @@ class DataQueue { [0, '10i0'] ]; - program.addParam(receiverVariable, { io: 'out', len: 'varLen'}); // Receiver variable - program.addParam(0, '10i0', { setlen: 'varLen'}); // Length of receiver variable + program.addParam(receiverVariable, { io: 'out', len: 'varLen'}); // Receiver variable + program.addParam(0, '10i0', { setlen: 'varLen'}); // Length of receiver variable program.addParam('RDQD0100', '8A'); // Format name program.addParam(this.qualifiedName, '20A'); // Qualified data queue name From 646aa5c657228823fcd4f018112aef9c9694d86d Mon Sep 17 00:00:00 2001 From: Mark Irish Date: Thu, 4 Mar 2021 10:21:48 -0600 Subject: [PATCH 3/4] Update DataQueue class Signed-off-by: Mark Irish --- lib/DataQueue.js | 77 +++++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 31 deletions(-) diff --git a/lib/DataQueue.js b/lib/DataQueue.js index ccd28961..63bbf8c2 100644 --- a/lib/DataQueue.js +++ b/lib/DataQueue.js @@ -1,6 +1,6 @@ const { ProgramCall } = require('./ProgramCall'); const { CommandCall } = require('./CommandCall'); -const { xmlToJson } = require('./utils'); +// const { xmlToJson } = require('./utils'); // QRCVDTAQ Parameters const QRCVDTAQParameters = { @@ -59,8 +59,8 @@ class DataQueue { return callback(error); } - const result = xmlToJson(xmlOutput); - callback(null, result); + // const result = xmlToJson(xmlOutput); + callback(null, xmlOutput); }); } @@ -79,8 +79,8 @@ class DataQueue { return callback(error); } - const result = xmlToJson(xmlOutput); - callback(null, result); + // const result = xmlToJson(xmlOutput); + callback(null, xmlOutput); }); } @@ -105,27 +105,35 @@ class DataQueue { const program = new ProgramCall('QRCVDTAQ', { lib: 'QSYS' }); - program.addParam(this.name, QRCVDTAQParameters.DataQueueName.type, { io: QRCVDTAQParameters.DataQueueName.io }); - program.addParam(this.library, QRCVDTAQParameters.LibraryName.type, { io: QRCVDTAQParameters.LibraryName.io }); - program.addParam(length, QRCVDTAQParameters.LengthOfData.type, { io: QRCVDTAQParameters.LengthOfData.io }); - program.addParam('', `${this.maxLength}A`, { io: QRCVDTAQParameters.Data.io }); - program.addParam(wait, QRCVDTAQParameters.WaitTime.type, { io: QRCVDTAQParameters.WaitTime.io }); + program.addParam ( + { value: this.name, ...QRCVDTAQParameters.DataQueueName } + ); + program.addParam ( + { value: this.library, ...QRCVDTAQParameters.LibraryName } + ); + program.addParam ( + { value: length, ...QRCVDTAQParameters.LengthOfData } + ); + program.addParam ( + { value: '', ...QRCVDTAQParameters.Data } + ); + program.addParam ( + { value: wait, ...QRCVDTAQParameters.WaitTime} + ); this.connection.add(program) this.connection.run((error, xmlOutput) => { if (error) { return callback(error, null); } - const result = xmlToJson(xmlOutput); - const data = result[0].data[1].value; - return callback(null, data); + return callback(null, xmlOutput); }); } // alias for receive, as the API is "RCV", but jt400 uses the term "read" async read(wait, callback) { - return this.receive(wait, callback); - } + return this.receive(wait, callback); + } ////////////////////////////////////////////////////////////////////////////// // Send Data Queue (QSNDDTAQ) API @@ -133,23 +141,24 @@ class DataQueue { async send(data, callback) { const program = new ProgramCall('QSNDDTAQ', { lib: 'QSYS' }); - program.addParam(this.name, '10A'); // Data queue name - program.addParam(this.library, '10A'); // Library name - program.addParam(data.length, '5p0'); // Length of data - program.addParam(data, `${data.length}A`); // Data + program.addParam({value: this.name, type: '10A'}); // Data queue name + program.addParam({value: this.library, type: '10A'}); // Library name + program.addParam({value: data.length, type: '5p0'}); // Length of data + program.addParam({value: data, type: `${data.length}A`}); // Data this.connection.add(program) this.connection.run((error, xmlOutput) => { if (error) { return callback(error, null); } - const result = xmlToJson(xmlOutput); - return callback(null, result); + // const result = xmlToJson(xmlOutput); + return callback(null, xmlOutput); }); } + // alias for send, as the API is "SND", but jt400 uses the term "write" async write(data, callback) { - return this.write(data, callback); + return this.send(data, callback); } ////////////////////////////////////////////////////////////////////////////// @@ -166,8 +175,8 @@ class DataQueue { if (error) { return callback(error, null); } - const result = xmlToJson(xmlOutput); - return callback(null, result); + // const result = xmlToJson(xmlOutput); + return callback(null, xmlOutput); }); } @@ -185,10 +194,18 @@ class DataQueue { [0, '10i0'] ]; - program.addParam(receiverVariable, { io: 'out', len: 'varLen'}); // Receiver variable - program.addParam(0, '10i0', { setlen: 'varLen'}); // Length of receiver variable - program.addParam('RDQD0100', '8A'); // Format name - program.addParam(this.qualifiedName, '20A'); // Qualified data queue name + program.addParam ( // Receiver variable + { value: receiverVariable, type: 'ds', io: 'out', len: 'varLen' } + ); + program.addParam ( // Length of receiver variable + { value: 0, type: '10i0', setlen: 'varLen' } + ); + program.addParam ( // Format name + { value: 'RDQD0100', type: '8A' } + ); + program.addParam ( // Qualified data queue name + { value: this.qualifiedName, type: '20A' } + ); this.connection.add(program) this.connection.run((error, xmlOutput) => { @@ -196,9 +213,7 @@ class DataQueue { return callback(error, null); } - const result = xmlToJson(xmlOutput); - this.maxLength = result[0].data[2].value - return callback(null, result); + return callback(null, xmlOutput); }); } } From 37c37ac99f8ba9b50538936bb7eee1a15451f46d Mon Sep 17 00:00:00 2001 From: Mark Irish Date: Thu, 4 Mar 2021 15:27:05 -0600 Subject: [PATCH 4/4] Fix DataQueue implementation Signed-off-by: Mark Irish --- lib/DataQueue.js | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/lib/DataQueue.js b/lib/DataQueue.js index 63bbf8c2..8c920faa 100644 --- a/lib/DataQueue.js +++ b/lib/DataQueue.js @@ -7,7 +7,7 @@ const QRCVDTAQParameters = { DataQueueName: { io: 'in', type: '10A' }, LibraryName: { io: 'in', type: '10A' }, LengthOfData: { io: 'out', type: '5p0' }, - Data: { io: 'out', type: '10A' }, + Data: { io: 'out' }, WaitTime: { io: 'in', type: '5p0' } } @@ -59,7 +59,6 @@ class DataQueue { return callback(error); } - // const result = xmlToJson(xmlOutput); callback(null, xmlOutput); }); } @@ -79,7 +78,6 @@ class DataQueue { return callback(error); } - // const result = xmlToJson(xmlOutput); callback(null, xmlOutput); }); } @@ -96,13 +94,18 @@ class DataQueue { if (length == undefined) { if (this.maxLength == undefined) { - const description = await this._getDataQueueDescription(); - this.maxLength = description[0].data[2].value; + const description = await this._getDataQueueDescription((error, result) => { + if (error) console.error(error); + console.log(description); + this.maxLength = 100; + }); } length = this.maxLength; } + console.log(`Length in receive is ${length}`); + const program = new ProgramCall('QRCVDTAQ', { lib: 'QSYS' }); program.addParam ( @@ -115,7 +118,7 @@ class DataQueue { { value: length, ...QRCVDTAQParameters.LengthOfData } ); program.addParam ( - { value: '', ...QRCVDTAQParameters.Data } + { value: '', ...QRCVDTAQParameters.Data, type: `${length}A` } ); program.addParam ( { value: wait, ...QRCVDTAQParameters.WaitTime} @@ -140,6 +143,7 @@ class DataQueue { ////////////////////////////////////////////////////////////////////////////// async send(data, callback) { + console.log("data length is " + data.length); const program = new ProgramCall('QSNDDTAQ', { lib: 'QSYS' }); program.addParam({value: this.name, type: '10A'}); // Data queue name program.addParam({value: this.library, type: '10A'}); // Library name @@ -151,7 +155,7 @@ class DataQueue { if (error) { return callback(error, null); } - // const result = xmlToJson(xmlOutput); + return callback(null, xmlOutput); }); } @@ -165,17 +169,17 @@ class DataQueue { // Clear Data Queue (QCLRDTAQ) API ////////////////////////////////////////////////////////////////////////////// - async clear() { + async clear(callback) { const program = new ProgramCall('QCLRDTAQ', { lib: 'QSYS' }); - program.addParam(this.name, '10A'); // Data queue name - program.addParam(this.library, '10A'); // Library name + program.addParam({ value: this.name, type: '10A'} ); // Data queue name + program.addParam({ value: this.library, type: '10A'}); // Library name this.connection.add(program) this.connection.run((error, xmlOutput) => { if (error) { return callback(error, null); } - // const result = xmlToJson(xmlOutput); + return callback(null, xmlOutput); }); } @@ -189,13 +193,13 @@ class DataQueue { const program = new ProgramCall('QMHQRDQD', { lib: 'QSYS' }); const receiverVariable = [ - [0, '10i0'], - [0, '10i0'], - [0, '10i0'] + { value: 0, type: '10i0' }, + { value: 0, type: '10i0' }, + { value: 0, type: '10i0' }, ]; program.addParam ( // Receiver variable - { value: receiverVariable, type: 'ds', io: 'out', len: 'varLen' } + { value: receiverVariable, fields: receiverVariable, type: 'ds', io: 'out', len: 'varLen' } ); program.addParam ( // Length of receiver variable { value: 0, type: '10i0', setlen: 'varLen' }