Skip to content

Commit

Permalink
Merge pull request #41 from std4lqi/support-dcb
Browse files Browse the repository at this point in the history
Refine DCB parameters and support allocating PDS
  • Loading branch information
std4lqi authored Dec 16, 2019
2 parents ab76ca5 + 2d9a1d4 commit 5befdd6
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 23 deletions.
28 changes: 25 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,12 @@ c.connect({user: 'myname', password:'mypassword'})

#### Allocate

`allocateDataset(datasetName, allocateParams)` - Allocate dataset.
`allocateDataset(datasetName, allocateParams)` - Allocate sequential or partition (with the DCB attribut "DSORG=PO") dataset.

##### Parameter

* datasetName - _string_ - Dataset name to allocate.
* allocateParams - _object | string_ - A string of space separated DCB attributes or an object of DCB attribute key-value pairs, eg. "LRECL=80 RECFM=VB" or {"LRECL": 80, "RECFM": "VB"}.
* allocateParams - _object | string_ - A string of space separated DCB attributes or an object of DCB attribute key-value pairs, eg. "LRECL=80 RECFM=VB" or {"LRECL": 80, "RECFM": "VB"}. The tested attributes includes BLKsize/BLOCKSize, Directory, DSORG, LRecl, PDSTYPE, PRImary, RECfm, SECondary, and TRacks.

Option Key | Description
---- | ---
Expand Down Expand Up @@ -136,6 +136,16 @@ connection.allocateDataset('ABC.DEF', {'LRECL': 80, 'RECFM': 'FB', 'BLKSIZE': 32
});
```

```js
connection.allocateDataset('ABC.PDS', {'LRECL': 80, 'RECFM': 'FB', 'BLKSIZE': 320, 'DSORG': 'PO', 'DIRECTORY': 20})
.then(function() {
console.log('Success');
})
.catch(function(err) {
// handle error
});
```

#### List

`listDataset(dsnOrDir)` - List MVS datasets or USS files
Expand Down Expand Up @@ -189,7 +199,7 @@ connection.listDataset('/u/user1/')
* input - _any_ - A [ReadableStream](https://nodejs.org/api/stream.html#stream_readable_streams), a [Buffer](https://nodejs.org/api/buffer.html), or a path to a local file that needs uploading.
* destDataset - _string_ - Dataset name to used to store the uploaded file, if it starts with `/` this file will be uploaded to USS.
* dataType - _string (default: ascii)_ - Transfer data type, it should be 'ascii' or 'binary', **when transfering 'ascii' files, the end-of-line sequence of input should always be `\r\n`**, otherwise the transfered file will get truncated.
* allocateParams - _object | string_ - A string of space separated DCB attributes or an object of DCB attribute key-value pairs, eg. "LRECL=80 RECFM=VB" or {"LRECL": 80, "RECFM": "VB"}.
* allocateParams - _object | string_ - A string of space separated DCB attributes or an object of DCB attribute key-value pairs, eg. "LRECL=80 RECFM=VB" or {"LRECL": 80, "RECFM": "VB"}. The tested attributes: BLKsize/BLOCKSize, LRecl, RECfm, PRImary, SECondary, TRacks.

##### Return

Expand All @@ -209,6 +219,18 @@ connection.uploadDataset(input, 'hosts')
});
```

```js
var fs = require('fs');
var input = fs.readFileSync('/etc/hosts', 'utf8').replace(/\r?\n/g, '\r\n');
connection.uploadDataset(input, 'HLQ.HOSTS', "LRECL=80 RECFM=FB")
.then(function() {
console.log('Success');
})
.catch(function(err) {
// handle error
});
```

#### Read MVS dataset or USS file

`getDataset(dsn, dataType, stream)` - Get the contents of the MVS dataset or USS file.
Expand Down
75 changes: 55 additions & 20 deletions lib/zosAccessor.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,21 +71,67 @@ ZosAccessor.prototype.close = function () {
//==================================Dataset related operations=================

/**
* Allocate dataset
* Convert allocate params object to name/value pair string.
*/
function allocateParamsToString(allocateParams) {
if (typeof allocateParams === 'string') {
return allocateParams;
}

var params = [];
// allocateParams is an object
for (var key in allocateParams || {}) {
if (!allocateParams.hasOwnProperty(key)) {
continue;
}
if (allocateParams[key] === true) {
params.push(key.toUpperCase());
} else {
params.push(key.toUpperCase() + '=' + allocateParams[key]);
}
}
return params.join(' ');
}

/**
* Allocate sequential or partition (with the DCB attribut "DSORG=PO") dataset.
*
* @param {string} datasetName - Dataset name to allocate
* @param {object|string} allocateParams - A string of space separated DCB attributes or an object of DCB attribute key-value pairs.
* eg. "LRECL=80 RECFM=VB" or {"LRECL": 80, "RECFM": "VB"}.
* eg. "LRECL=80 RECFM=VB" or {"LRECL": 80, "RECFM": "VB"}.
* The tested attributes includes BLKsize/BLOCKSize, Directory, DSORG, LRecl, PDSTYPE, PRImary, RECfm, SECondary, and TRacks.
*/
ZosAccessor.prototype.allocateDataset = function(datasetName, allocateParams) {
var self = this;
var ftpClient = this.client;
datasetName = ensureFullQualifiedDSN(datasetName);
return self.listDataset(datasetName).then(function (datasetList) {
if (datasetList.length) {
throw new Error('Dataset ' + datasetName + ' already exists');
}
// TODO: Upload a space here, because an empty Buffer may cause the "connection reset" error.
return self.uploadDataset(new Buffer(' '), datasetName, undefined, allocateParams);

var allocateParamString = allocateParamsToString(allocateParams);
if (allocateParamString.indexOf("DSORG=PO") !== -1) {
// Allocate an PDS dataSet
var deferred = Q.defer();
ftpClient.site(allocateParamString, function (err, responseText, responseCode) {
if (err) {
return deferred.reject(err);
}
ftpClient.mkdir(datasetName, function (err) {
if (err) {
deferred.reject(err);
} else {
deferred.resolve();
}
});
});
return deferred.promise;
} else {
// Allocate a seq dataSet
// Upload a space here, because an empty Buffer may cause the "connection reset" error.
return self.uploadDataset(new Buffer(' '), datasetName, undefined, allocateParams);
}
});
};

Expand All @@ -98,7 +144,9 @@ ZosAccessor.prototype.allocateDataset = function(datasetName, allocateParams) {
* when transfering 'ascii' files, the end-of-line sequence of input should always be '\r\n',
* otherwise the transfered file will get truncated.
* @param {object|string} allocateParams - A string of space separated DCB attributes or an object of DCB attribute key-value pairs.
* eg. "LRECL=80 RECFM=VB" or {"LRECL": 80, "RECFM": "VB"}.
* eg. "LRECL=80 RECFM=VB" or {"LRECL": 80, "RECFM": "VB"}.
* The tested attributes: BLKsize/BLOCKSize, LRecl, RECfm, PRImary, SECondary, TRacks
*
*/
ZosAccessor.prototype.uploadDataset = function(input, destDataset, dataType, allocateParams) {
var deferred = Q.defer();
Expand All @@ -109,21 +157,8 @@ ZosAccessor.prototype.uploadDataset = function(input, destDataset, dataType, all
}

var siteParams = ['FILETYPE=SEQ'];
if (typeof allocateParams === 'string') {
siteParams.push(allocateParams);
} else {
// allocateParams is an object
for (var key in allocateParams || {}) {
if (!allocateParams.hasOwnProperty(key)) {
continue;
}
if (allocateParams[key] === true) {
siteParams.push(key.toUpperCase());
} else {
siteParams.push(key.toUpperCase() + '=' + allocateParams[key]);
}
}
}
var allocateParamString = allocateParamsToString(allocateParams);
siteParams.push(allocateParamString);

ftpClient[dataType](function (err) {
if (err) {
Expand Down

0 comments on commit 5befdd6

Please sign in to comment.