Skip to content

Commit

Permalink
Error out on unbound parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
alexpenev-s committed Jul 7, 2017
1 parent 5a3731e commit e53d9c9
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 39 deletions.
69 changes: 35 additions & 34 deletions lib/protocol/Statement.js
Expand Up @@ -104,54 +104,55 @@ Statement.prototype._normalizeInputParameters = function _normalizeInputParamete
return metadata.dataType;
}

function isDefined(metadata) {
return typeof values[metadata.name] !== 'undefined'
}

function getObjectValue(metadata) {
if (!util.isUndefined(values[metadata.name])) {
return values[metadata.name];
}
return null;
return values[metadata.name];
}

var parameters = {
types: inputParameterMetadata.map(getDataType),
values: undefined
};
if (util.isArray(values)) {
if (!values.length) {
throw new Error('Invalid input parameter values');
}

parameters.values = values;
return parameters;
}
parameters.values = inputParameterMetadata.map(getObjectValue);
return parameters;
parameters.values = Array.isArray(values) ? values : inputParameterMetadata.filter(isDefined).map(getObjectValue);
var vals = parameters.values.length && Array.isArray(parameters.values[0]) ? parameters.values : [parameters.values];
var unbound = vals.some(function (e) {
return e.length !== parameters.types.length;
})
return unbound ? undefined : parameters;
};

Statement.prototype._execute = function _execute(values, options, cb) {
try {
var settings = util.filter.call(this._settings, [
'averageRowLength',
'fetchSize',
'readSize',
'rowsAsArray',
'nestTables',
'columnNameProperty'
]);
var result = this._createResult(this._connection, util.extend(settings, options));
result.setResultSetMetadata(this.resultSetMetadata);
result.setParameterMetadata(this.parameterMetadata.filter(isOutputParameter));
this._connection.execute({
functionCode: this.functionCode,
statementId: this.id,
parameters: this._normalizeInputParameters(values)
}, function handleReply(err, reply) {
result.handle(err, reply, cb);
});
} catch (err) {
var settings = util.filter.call(this._settings, [
'averageRowLength',
'fetchSize',
'readSize',
'rowsAsArray',
'nestTables',
'columnNameProperty'
]);
var result = this._createResult(this._connection, util.extend(settings, options));
var inputParams = this._normalizeInputParameters(values);
if (inputParams === undefined) {
process.nextTick(function () {
cb(err);
cb(new Error('Unbound parameters found.'));
});
return this;
}

result.setResultSetMetadata(this.resultSetMetadata);
result.setParameterMetadata(this.parameterMetadata.filter(isOutputParameter));
this._connection.execute({
functionCode: this.functionCode,
statementId: this.id,
parameters: inputParams
}, function handleReply(err, reply) {
result.handle(err, reply, cb);
});

return this;
};

Expand Down
50 changes: 45 additions & 5 deletions test/lib.Statement.js
Expand Up @@ -77,7 +77,7 @@ describe('Lib', function () {
});
});

it('should execute a statement with empty parameter values', function (
it('should generate an error on statements with empty parameter values', function (
done) {
var statement = createStatement();
var values = [];
Expand All @@ -87,6 +87,46 @@ describe('Lib', function () {
});
});

it('should generate an error on statements with unbound input parameters (array)', function (
done) {
var statement = createStatement();
var values = { 'bad': 1 };
statement.execute(values, function (err) {
err.should.be.instanceof(Error);
done();
});
});

it('should generate an error on statements with unbound input parameters (object)', function (
done) {
var statement = createStatement({
parameterMetadata: [{
dataType: TypeCode.TINYINT,
ioType: IoType.INPUT,
name: 'A'
}, {
dataType: TypeCode.SMALLINT,
ioType: IoType.OUTPUT,
name: 'B'
}, {
dataType: TypeCode.INT,
ioType: IoType.IN_OUT,
name: 'C'
}, {
dataType: TypeCode.BIGINT,
ioType: IoType.INPUT,
name: 'D'
}]
});

var statement = createStatement();
var values = [1, 2];
statement.execute(values, function (err) {
err.should.be.instanceof(Error);
done();
});
});

it('should execute a statement with an options object', function (
done) {
var replies = null;
Expand Down Expand Up @@ -185,7 +225,8 @@ describe('Lib', function () {
});
statement._normalizeInputParameters({
A: 1,
C: 3
C: 3,
D: null
}).should.eql({
types: [TypeCode.TINYINT, TypeCode.INT, TypeCode.BIGINT],
values: [1, 3, null]
Expand All @@ -199,9 +240,8 @@ describe('Lib', function () {
statement._normalizeInputParameters().should.equal(EMPTY_BUFFER);
});

it('should raise an error for empty parameters values', function () {
Statement.prototype._normalizeInputParameters.bind(createStatement(), [])
.should.throw();
it('should return undefined for non-bound parameters', function () {
(Statement.prototype._normalizeInputParameters.bind(createStatement(), [])() === undefined).should.be.true;
});

});
Expand Down

0 comments on commit e53d9c9

Please sign in to comment.