Skip to content

Commit c28c5a7

Browse files
dotchevalexpenev-s
authored andcommitted
Fix: no result sets when procedure called with large blob (#103)
* Fix: no result sets when procedure called with large blob
1 parent fd6f5c7 commit c28c5a7

File tree

5 files changed

+101
-5
lines changed

5 files changed

+101
-5
lines changed

lib/protocol/ExecuteTask.js

+6
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ ExecuteTask.prototype.run = function run(next) {
9191
if (err) {
9292
return finalize(err);
9393
}
94+
self.pushReply(reply);
9495
writeLob();
9596
});
9697
}
@@ -128,6 +129,11 @@ ExecuteTask.prototype.pushReply = function pushReply(reply) {
128129
this.reply.rowsAffected = reply.rowsAffected;
129130
}
130131
}
132+
if (reply.resultSets && reply.resultSets.length) {
133+
// old results sets should not be present as there is no bulk select or procedure execute
134+
// still we keep them to be safe
135+
this.reply.resultSets = [].concat(this.reply.resultSets || [], reply.resultSets);
136+
}
131137
};
132138

133139
ExecuteTask.prototype.getParameters = function getParameters(availableSize, cb) {

test/acceptance/db.Lob.js

+52-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,13 @@
1616

1717
var fs = require('fs');
1818
var path = require('path');
19+
var util = require('util');
20+
var crypto = require('crypto');
1921
var async = require('async');
2022
var db = require('../db')();
23+
var RemoteDB = require('../db/RemoteDB');
24+
25+
var describeRemoteDB = db instanceof RemoteDB ? describe : describe.skip;
2126

2227
if (!Buffer.prototype.equals) {
2328
Buffer.prototype.equals = function (buffer) {
@@ -37,13 +42,15 @@ if (!Buffer.prototype.equals) {
3742
}
3843

3944
describe('db', function () {
45+
this.timeout(50000);
46+
4047
before(db.init.bind(db));
4148
after(db.end.bind(db));
49+
4250
var client = db.client;
4351
var transaction = client._connection._transaction;
4452

4553
describe('IMAGES', function () {
46-
this.timeout(5000);
4754
before(db.createImages.bind(db));
4855
after(db.dropImages.bind(db));
4956

@@ -167,6 +174,49 @@ describe('db', function () {
167174

168175
async.waterfall([prepare, insert, validate], done);
169176
});
177+
});
178+
179+
describeRemoteDB('HASH_BLOB', function() {
180+
var statement;
181+
182+
before(function (done) {
183+
async.series([
184+
db.createHashBlobProc.bind(db),
185+
client.prepare.bind(client, 'call HASH_BLOB (?)'),
186+
], function(err, results) {
187+
statement = results[1];
188+
done(err);
189+
});
190+
});
170191

192+
after(db.dropHashBlobProc.bind(db));
193+
194+
// call the procedure with images of different sizes
195+
var images = require('../fixtures/images');
196+
images.forEach(function(image) {
197+
var title = util.format('should call the procedure with %s (%dB) and get its hash in a result set',
198+
image.NAME, image.BDATA.length);
199+
it(title, function(done) {
200+
var params = [ image.BDATA ];
201+
statement.exec(params, function(err, outParams, rows) {
202+
if (err) {
203+
return done(err);
204+
}
205+
arguments.should.have.length(3);
206+
rows.should.have.length(1);
207+
rows[0].should.eql({
208+
ALGO: 'MD5',
209+
DIGEST: MD5(image.BDATA)
210+
});
211+
done();
212+
});
213+
});
214+
});
171215
});
172-
});
216+
});
217+
218+
function MD5(data) {
219+
var hash = crypto.createHash('md5');
220+
hash.update(data);
221+
return hash.digest('hex').toUpperCase();
222+
}

test/db/RemoteDB.js

+19
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,22 @@ RemoteDB.prototype.dropConcatStringsProc = function dropConcatStringsProc(cb) {
144144
var sql = 'drop procedure CONCAT_STRINGS_PROC cascade';
145145
this.client.exec(sql, cb);
146146
};
147+
148+
RemoteDB.prototype.createHashBlobProc = function createHashBlobProc(cb) {
149+
var create = [
150+
'create procedure HASH_BLOB (in image BLOB)',
151+
'language sqlscript reads sql data as',
152+
'begin',
153+
' select \'MD5\' as ALGO, TO_VARCHAR(HASH_MD5(TO_VARBINARY(image))) as DIGEST from dummy;',
154+
'end'
155+
].join('\n');
156+
var self = this;
157+
self.dropHashBlobProc(function() {
158+
// ignore any error as the procedure may not exist yet
159+
self.client.exec(create, cb);
160+
});
161+
}
162+
163+
RemoteDB.prototype.dropHashBlobProc = function dropHashBlobProc(cb) {
164+
this.client.exec('drop procedure HASH_BLOB cascade', cb);
165+
};

test/db/TestDB.js

+8
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,14 @@ TestDB.prototype.dropConcatStringsProc = function dropConcatStringsProc(cb) {
8080
doNothing(cb);
8181
};
8282

83+
TestDB.prototype.createHashBlobProc = function createHashBlobProc(cb) {
84+
doNothing(cb);
85+
};
86+
87+
TestDB.prototype.dropHashBlobProc = function dropHashBlobProc(cb) {
88+
doNothing(cb);
89+
};
90+
8391

8492
function doNothing(done) {
8593
process.nextTick(done);

test/lib.ExecuteTask.js

+16-3
Original file line numberDiff line numberDiff line change
@@ -182,10 +182,10 @@ describe('Lib', function () {
182182
}]
183183
}, {
184184
type: MessageType.WRITE_LOB,
185-
args: [null]
185+
args: [null, {}]
186186
}, {
187187
type: MessageType.COMMIT,
188-
args: [null]
188+
args: [null, {}]
189189
}]
190190
}, function done(err, reply) {
191191
(!err).should.be.ok;
@@ -218,7 +218,7 @@ describe('Lib', function () {
218218
}).run(next);
219219
});
220220

221-
it('should push a reply', function () {
221+
it('should accumulate rows affected', function () {
222222
var task = createExecuteTask();
223223
task.pushReply({});
224224
task.pushReply({
@@ -231,6 +231,19 @@ describe('Lib', function () {
231231
task.reply.rowsAffected.should.eql([1, 1, 1]);
232232
});
233233

234+
it('should accumulate result sets', function () {
235+
var task = createExecuteTask();
236+
task.pushReply({});
237+
task.pushReply({
238+
resultSets: [{}]
239+
});
240+
task.reply.resultSets.should.have.length(1);
241+
task.pushReply({
242+
resultSets: [{}, {}]
243+
});
244+
task.reply.resultSets.should.have.length(3);
245+
});
246+
234247
it('should getParameters with invalid values error', function (done) {
235248
var task = createExecuteTask();
236249
var invalidValuesError = new Error('invalid values error');

0 commit comments

Comments
 (0)