From b7575649063bd9a9ad32d1d644105a3a5104603f Mon Sep 17 00:00:00 2001 From: Qi Liang Date: Mon, 19 Jun 2023 09:10:37 +0800 Subject: [PATCH] Add siteParams to downloadDataset(...) Signed-off-by: Qi Liang --- README.md | 3 ++- package-lock.json | 2 +- package.json | 2 +- src/__unit__/zosAccessor.test.ts | 5 +++++ src/zosAccessor.ts | 21 ++++++++++++++------- 5 files changed, 23 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index d1ff1df..4c420b2 100644 --- a/README.md +++ b/README.md @@ -256,13 +256,14 @@ await connection.uploadDataset(input, 'HLQ.HOSTS', "LRECL=80 RECFM=FB"); #### Download MVS dataset -`downloadDataset(dsn: string, transferMode: TransferMode = TransferMode.ASCII, stream = false)` - Downloads the specified dataset or member of patition dataset. +`downloadDataset(dsn: string, transferMode: TransferMode = TransferMode.ASCII, stream = false, siteParams?: string)` - Downloads the specified dataset or member of patition dataset. ##### Parameter * dsn - _string_ - Specify a full qualified dataset name, or USS file name. It **CAN NOT** contain any wildcard (*). * transferMode - _TransferMode_ - `TransferMode.ASCII`, `TransferMode.BINARY`, `TransferMode.ASCII_STRIP_EOL`, `TransferMode.ASCII_RDW`, or `TransferMode.BINARY_RDW`. When downloading a text dataset, transferMode should be either `TransferMode.ASCII` or `TransferMode.ASCII_STRIP_EOL` so that z/OS FTP service converts `EBCDIC` characters to `ASCII`. `TransferMode.ASCII_STRIP_EOL` asks z/OS FTP service not to append a `CLRF` to the end of each record. `TransferMode.ASCII_RDW` and `TransferMode.BINARY_RDW` support to download variable length dataset, which add 4-byte Record Description Word (RDW) at the beginning of each record. * stream - _boolean_ - `true` if you want to obtain a [ReadableStream](https://nodejs.org/api/stream.html#stream_readable_streams) of the data set content, or `false` to read a full dataset into memory (in Buffer). The buffer accepts up to 4MB data. For large dataset, use `stream=true` instead. +* siteParams - _string_ - Add extra site parameters, for example, 'sbd=(IBM-1047,ISO8859-1)' for encoding setting. ##### Return diff --git a/package-lock.json b/package-lock.json index 01a7e30..0b047f3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "zos-node-accessor", - "version": "2.0.4", + "version": "2.0.7", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index cbc295a..8050b1f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "zos-node-accessor", - "version": "2.0.5", + "version": "2.0.7", "description": "Accessing z/OS dataset and interacting with JES in NodeJS way", "main": "./lib/zosAccessor.js", "types": "./lib/zosAccessor.d.ts", diff --git a/src/__unit__/zosAccessor.test.ts b/src/__unit__/zosAccessor.test.ts index fa94f11..9e80405 100644 --- a/src/__unit__/zosAccessor.test.ts +++ b/src/__unit__/zosAccessor.test.ts @@ -441,6 +441,11 @@ describe('z/OS node accessor', () => { expect(mockFtp4.site).toBeCalledWith('rdw', expect.any(Function)); }); + it('can download dataset with site params', async () => { + await client.downloadDataset('dsn', TransferMode.BINARY, true, 'site params'); + expect(mockFtp4.site).toBeCalledWith('FILETYPE=SEQ TRAILINGBLANKS SBSENDEOL=CRLF site params', expect.any(Function)); + }); + it('can convert allocation parameter object to string', async () => { await client.uploadDataset('hello', uploadDSN, TransferMode.ASCII, { LRECL: 80, RECFM: 'FB'}); expect(mockFtp4.site).toBeCalledWith('FILETYPE=SEQ LRECL=80 RECFM=FB', expect.any(Function)); diff --git a/src/zosAccessor.ts b/src/zosAccessor.ts index 5297c81..38e891c 100644 --- a/src/zosAccessor.ts +++ b/src/zosAccessor.ts @@ -1,6 +1,6 @@ /****************************************************************************/ /* */ -/* Copyright (c) 2017, 2021 IBM Corp. */ +/* Copyright (c) 2017, 2023 IBM Corp. */ /* All rights reserved. This program and the accompanying materials */ /* are made available under the terms of the Eclipse Public License v1.0 */ /* which accompanies this distribution, and is available at */ @@ -429,7 +429,7 @@ class ZosAccessor { } private async download(dsn: string, transferMode: TransferMode = TransferMode.ASCII, - stream = false): Promise { + stream = false, siteParams?: string): Promise { const deferred = Q.defer(); const ftpClient = this.client; @@ -445,12 +445,17 @@ class ZosAccessor { transferMode = TransferMode.ASCII; } + let site = 'FILETYPE=SEQ TRAILINGBLANKS ' + sbsendeol; + if (siteParams) { + site += ' ' + siteParams; + } + // ftpClient.ascii() or ftpClient.binary() ftpClient[transferMode]((err: Error) => { if (err) { return deferred.reject(err); } - ftpClient.site('FILETYPE=SEQ TRAILINGBLANKS ' + sbsendeol, (err1: Error) => { + ftpClient.site(site, (err1: Error) => { if (err1) { return deferred.reject(err1); } @@ -500,10 +505,12 @@ class ZosAccessor { * @param {boolean} stream - `true` if you want to obtain a `ReadStream` of the data set content, or `false` * to read a full dataset into memory (in Buffer). The buffer accepts up to 4MB data. * For large dataset, use `stream=true` instead. + * @param {string} siteParams - Add extra site parameters, for example, 'sbd=(IBM-1047,ISO8859-1)' for encoding + * setting. * @returns `ReadStream` or `Buffer` */ public async downloadDataset(dsn: string, transferMode: TransferMode = TransferMode.ASCII, - stream = false): Promise { + stream = false, siteParams?: string): Promise { if (transferMode === TransferMode.ASCII_RDW || transferMode === TransferMode.BINARY_RDW) { if (transferMode === TransferMode.ASCII_RDW) { transferMode = TransferMode.ASCII; @@ -516,12 +523,12 @@ class ZosAccessor { if (err) { return deferred.reject(err); } - const file = await this.download(dsn, transferMode, stream); + const file = await this.download(dsn, transferMode, stream, siteParams); deferred.resolve(file); }); return deferred.promise; } - return await this.download(dsn, transferMode, stream); + return await this.download(dsn, transferMode, stream, siteParams); } /** @@ -1215,7 +1222,7 @@ class ZosAccessor { * @param owner the owner of job */ private checkJobNameAndOwner(jobname: string, owner: string) { - if ((jobname && jobname.length > 8) || (owner && owner.length) > 8) { + if ((jobname && jobname.length > 8) || (owner && owner.length > 8)) { throw new Error( "Value of prefix or owner is not valid. It is longer than 8 characters." );