sqmicro-connection
Version:
Connection abstraction for SQ Micro.
70 lines (57 loc) • 2.04 kB
JavaScript
const { Transform } = require('stream');
const Private = Symbol['Private'];
const RECORD_TERMINATOR = '\n';
const DEFAULT_DELIMITER = '|';
const EMPTY_VALUE = '';
/**
* Поток преобразования сущностей в строки. Ожидает на входе объекты вида
* `{ row: object, fields: Array<string> }`. На выходе - строка. Например:
* @example
* // на входе:
* const data = {
* row: { a: 1, c: 2 },
* fields: ['a', 'b', 'c']
* };
* // на выходе (delimiter: '|'):
* const res = '1||2\n';
* @param {object} [options]
* @param {string} [options.delimiter=|] символ-разделитель полей.
*/
module.exports = class RecordFormatter extends Transform {
constructor(options = {}) {
super({
objectMode: true
});
this[Private] = {
delimiter: getDelimiter(options),
fieldNames: getFieldNames(options)
};
}
_transform(row, _, cb) {
const pvt = this[Private];
const record = pvt.fieldNames
.map(field => JSON.stringify(row[field]) || EMPTY_VALUE)
.join(pvt.delimiter)
+ RECORD_TERMINATOR;
this.push(record);
cb();
}
}
function getDelimiter(options) {
const delimiter = options.delimiter || DEFAULT_DELIMITER;
// delimiter should be compatible with any driver
if (typeof(delimiter) !== 'string' || delimiter.length !== 1) {
throw Error(`Delimiter must be a single character`);
}
// \n is record terminator (pg does not support another one).
if (delimiter === '\n') {
throw Error(`Delimiter should not be a new line symbol '\\n'.`)
}
return delimiter;
}
function getFieldNames(options) {
if (!options || !Array.isArray(options.fieldNames) || options.fieldNames.length < 1) {
throw Error(`options.fieldNames shoupd be a non-empty array of strings`);
}
return options.fieldNames;
}