Skip to content

Commit cdaa1a7

Browse files
author
Suraiya Hameed
committed
feat: add flag parsing and tests for returnvalue token
1 parent afdb800 commit cdaa1a7

File tree

3 files changed

+46
-92
lines changed

3 files changed

+46
-92
lines changed

src/tokens/returnvalue/index.js

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,6 @@ class ReturnValueToken extends Token {
88
paramName: ?string
99
status: ?number
1010
userType: ?number
11-
// TODO: parser flag
12-
flags: {
13-
nullable: ?boolean,
14-
caseSensitive: ?boolean,
15-
updateable: ?boolean,
16-
identity: ?boolean,
17-
computed: ?boolean,
18-
reservedODBC: ?boolean,
19-
fixedLenCLRType: ?boolean,
20-
encrypted: ?boolean
21-
}
2211
typeInfo: ?TypeInfo
2312
valueLength: ?number
2413
value: ?any
@@ -30,16 +19,6 @@ class ReturnValueToken extends Token {
3019
this.paramName = undefined;
3120
this.status = undefined;
3221
this.userType = undefined;
33-
this.flags = {
34-
nullable: undefined,
35-
caseSensitive: undefined,
36-
updateable: undefined,
37-
identity: undefined,
38-
computed: undefined,
39-
reservedODBC: undefined,
40-
fixedLenCLRType: undefined,
41-
encrypted: undefined
42-
};
4322
this.typeInfo = undefined;
4423
this.valueLength = undefined;
4524
this.value = undefined;

src/tokens/returnvalue/read.js

Lines changed: 3 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -59,48 +59,16 @@ function parseUserType_7_2(reader: Reader) {
5959
}
6060

6161
function parseFlags(reader: Reader) {
62-
if (reader.version < 0x72090002) {
63-
return parseFlags_7_0;
64-
} else if (reader.version < 0x74000004) {
65-
return parseFlags_7_2;
66-
} else {
67-
return parseFlags_7_4;
68-
}
69-
}
70-
71-
72-
function parseFlags_7_0(reader: Reader) {
62+
// for RETURNVALUE_TOKEN all the flags should be zero (TDS 2.2.7.18)
7363
if (!reader.bytesAvailable(2)) {
7464
return;
7565
}
7666

77-
// TODO: Implement flag parsing
7867
const flags = reader.readUInt16LE(0); // eslint-disable-line no-unused-vars
7968
reader.consumeBytes(2);
8069

81-
return parseTypeInfo;
82-
}
83-
84-
function parseFlags_7_2(reader: Reader) {
85-
if (!reader.bytesAvailable(2)) {
86-
return;
87-
}
88-
89-
// TODO: Implement flag parsing
90-
const flags = reader.readUInt16LE(0); // eslint-disable-line no-unused-vars
91-
reader.consumeBytes(2);
92-
93-
return parseTypeInfo;
94-
}
95-
96-
function parseFlags_7_4(reader: Reader) {
97-
if (!reader.bytesAvailable(2)) {
98-
return;
99-
}
100-
101-
// TODO: Implement flag parsing
102-
const flags = reader.readUInt16LE(0); // eslint-disable-line no-unused-vars
103-
reader.consumeBytes(2);
70+
if (0 != flags)
71+
throw new Error('Unknown flags in RETURNVALUE_TOKEN ');
10472

10573
return parseTypeInfo;
10674
}

test/returnValue-test.js

Lines changed: 43 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,24 @@ describe('Parsing a RETURNVALUE token', function() {
1515

1616
describe('in TDS 7.0 mode', function() {
1717

18-
let reader, data, paramOrdinal, paramName, status, userType, typeid, dataLength, value, offset, tempBuff;
18+
let reader, data, paramOrdinal, paramName, status, userType, flag, typeid, dataLength, value, offset, tempOffset, tempBuff;
1919

2020
before(function() {
2121
paramOrdinal = 1;
2222
paramName = '@count';
2323
status = 1;
2424
userType = 0;
25+
flag = 0;
2526
typeid = 0x26;
2627
value = 4;
27-
offset = 0;
28+
tempOffset = 0;
2829
tempBuff = Buffer.alloc(21);
2930
buildDataBuffer();
3031
});
3132

3233
beforeEach(function() {
3334
reader = new Reader(0x07000000);
35+
offset = tempOffset;
3436
});
3537

3638
function addListners(done, token) {
@@ -51,18 +53,17 @@ describe('Parsing a RETURNVALUE token', function() {
5153
}
5254

5355
function buildDataBuffer() {
54-
tempBuff.writeUInt8(0xAC, offset++);
55-
tempBuff.writeUInt16LE(paramOrdinal, offset);
56-
offset += 2;
57-
tempBuff.writeUInt8(paramName.length, offset++);
58-
tempBuff.write(paramName, offset, paramName.length * 2, 'ucs2');
59-
offset += paramName.length * 2;
60-
tempBuff.writeUInt8(status, offset++);
61-
tempBuff.writeUInt16LE(userType, offset);
62-
offset += 2;
63-
// Flag
64-
tempBuff.writeUInt16LE(0, offset);
65-
offset += 2;
56+
tempBuff.writeUInt8(0xAC, tempOffset++);
57+
tempBuff.writeUInt16LE(paramOrdinal, tempOffset);
58+
tempOffset += 2;
59+
tempBuff.writeUInt8(paramName.length, tempOffset++);
60+
tempBuff.write(paramName, tempOffset, paramName.length * 2, 'ucs2');
61+
tempOffset += paramName.length * 2;
62+
tempBuff.writeUInt8(status, tempOffset++);
63+
tempBuff.writeUInt16LE(userType, tempOffset);
64+
tempOffset += 2;
65+
tempBuff.writeUInt16LE(flag, tempOffset);
66+
tempOffset += 2;
6667
}
6768

6869
it('should parse the INTNTYPE(Int) token correctly', function(done) {
@@ -82,19 +83,43 @@ describe('Parsing a RETURNVALUE token', function() {
8283
addListners(done, token);
8384
reader.end(data);
8485
});
86+
87+
it('should throw exception on receiving non-zero flag', function(done) {
88+
dataLength = 4;
89+
90+
data = Buffer.alloc(28);
91+
tempBuff.copy(data, 0, 0, offset - 2);
92+
93+
// write non-zero flag
94+
data.writeUInt16LE(56, offset - 2);
95+
96+
// TYPE_INFO
97+
data.writeUInt8(typeid, offset++);
98+
data.writeUInt8(dataLength, offset++);
99+
100+
// TYPE_VARBYTE
101+
data.writeUInt8(dataLength, offset++);
102+
data.writeUInt32LE(value, offset);
103+
const token = {};
104+
105+
addListners(done, token);
106+
assert.throw(() => reader.end(data), Error, 'Unknown flags in RETURNVALUE_TOKEN');
107+
done();
108+
});
85109
});
86110

87111
describe('in TDS 7.2 mode', function() {
88112

89113
describe('test INTNTYPE', function() {
90114

91-
let reader, data, paramOrdinal, paramName, status, userType, typeid, dataLength, value, offset, tempBuff, tempOffset;
115+
let reader, data, paramOrdinal, paramName, status, userType, flag, typeid, dataLength, value, offset, tempBuff, tempOffset;
92116

93117
before(function() {
94118
paramOrdinal = 1;
95119
paramName = '@count';
96120
status = 1;
97121
userType = 0;
122+
flag = 0;
98123
typeid = 0x26;
99124
value = 4;
100125
tempOffset = 0;
@@ -104,6 +129,7 @@ describe('Parsing a RETURNVALUE token', function() {
104129

105130
beforeEach(function() {
106131
reader = new Reader(0x72090002);
132+
offset = tempOffset;
107133
});
108134

109135
function addListners(done, token) {
@@ -133,14 +159,12 @@ describe('Parsing a RETURNVALUE token', function() {
133159
tempBuff.writeUInt8(status, tempOffset++);
134160
tempBuff.writeUInt32LE(userType, tempOffset);
135161
tempOffset += 4;
136-
// Flag
137-
tempBuff.writeUInt16LE(0, tempOffset);
162+
tempBuff.writeUInt16LE(flag, tempOffset);
138163
tempOffset += 2;
139164
}
140165

141166
it('should parse the INTNTYPE(Tinyint) token correctly', function(done) {
142167
dataLength = 1;
143-
offset = tempOffset;
144168

145169
data = Buffer.alloc(27);
146170
tempBuff.copy(data);
@@ -159,7 +183,6 @@ describe('Parsing a RETURNVALUE token', function() {
159183

160184
it('should parse the INTNTYPE(smallint) token correctly', function(done) {
161185
dataLength = 2;
162-
offset = tempOffset;
163186

164187
data = Buffer.alloc(28);
165188
tempBuff.copy(data);
@@ -179,7 +202,6 @@ describe('Parsing a RETURNVALUE token', function() {
179202

180203
it('should parse the INTNTYPE(Int) token correctly', function(done) {
181204
dataLength = 4;
182-
offset = tempOffset;
183205

184206
data = Buffer.alloc(30);
185207
tempBuff.copy(data);
@@ -198,7 +220,6 @@ describe('Parsing a RETURNVALUE token', function() {
198220

199221
it('should parse the INTNTYPE(Bigint) token correctly', function(done) {
200222
dataLength = 8;
201-
offset = tempOffset;
202223

203224
data = Buffer.alloc(34);
204225
tempBuff.copy(data);
@@ -220,7 +241,6 @@ describe('Parsing a RETURNVALUE token', function() {
220241
it('should parse the INTNTYPE(null) token correctly', function(done) {
221242
dataLength = 8;
222243
value = null;
223-
offset = tempOffset;
224244

225245
data = Buffer.alloc(26);
226246
tempBuff.copy(data);
@@ -253,7 +273,7 @@ describe('Parsing a RETURNVALUE token', function() {
253273

254274
beforeEach(function() {
255275
reader = new Reader(0x72090002);
256-
276+
offset = tempOffset;
257277
});
258278

259279

@@ -301,7 +321,6 @@ describe('Parsing a RETURNVALUE token', function() {
301321
it('should parse the NULLTYPE token correctly', function(done) {
302322
typeid = 0x1F;
303323
value = null;
304-
offset = tempOffset;
305324

306325
data = Buffer.alloc(24);
307326
tempBuff.copy(data);
@@ -318,7 +337,6 @@ describe('Parsing a RETURNVALUE token', function() {
318337
it('should parse the INT1TYPE/TintInt token correctly', function(done) {
319338
typeid = 0x30;
320339
value = 255;
321-
offset = tempOffset;
322340

323341
data = Buffer.alloc(25);
324342
tempBuff.copy(data);
@@ -337,7 +355,6 @@ describe('Parsing a RETURNVALUE token', function() {
337355
it('should parse the BITTYPE token correctly', function(done) {
338356
typeid = 0x32;
339357
value = false;
340-
offset = tempOffset;
341358

342359
data = Buffer.alloc(25);
343360
tempBuff.copy(data);
@@ -356,7 +373,6 @@ describe('Parsing a RETURNVALUE token', function() {
356373
it('should parse the INT2TYPE/SmallInt token correctly', function(done) {
357374
typeid = 0x34;
358375
value = 32767;
359-
offset = tempOffset;
360376

361377
data = Buffer.alloc(26);
362378
tempBuff.copy(data);
@@ -375,7 +391,6 @@ describe('Parsing a RETURNVALUE token', function() {
375391
it('should parse the INT4TYPE/Int token correctly', function(done) {
376392
typeid = 0x38;
377393
value = -2147483648;
378-
offset = tempOffset;
379394

380395
data = Buffer.alloc(28);
381396
tempBuff.copy(data);
@@ -395,7 +410,6 @@ describe('Parsing a RETURNVALUE token', function() {
395410
typeid = 0x7F;
396411
// value = -2147483648;
397412
value = 147483648;
398-
offset = tempOffset;
399413

400414
data = Buffer.alloc(32);
401415
tempBuff.copy(data);
@@ -420,7 +434,6 @@ describe('Parsing a RETURNVALUE token', function() {
420434
const days = 43225; // days since 1900-01-01
421435
const minutes = 763;
422436
value = new Date('2018-05-07T12:43:00.000Z');
423-
offset = tempOffset;
424437

425438
data = Buffer.alloc(28);
426439
tempBuff.copy(data);
@@ -445,7 +458,6 @@ describe('Parsing a RETURNVALUE token', function() {
445458
const days = 43225;
446459
const minutes = 763;
447460
value = new Date('2018-05-07T12:43:00.000');
448-
offset = tempOffset;
449461

450462
data = Buffer.alloc(28);
451463
tempBuff.copy(data);
@@ -466,7 +478,6 @@ describe('Parsing a RETURNVALUE token', function() {
466478
it('should parse the FLT4TYPE/Real token correctly', function(done) {
467479
typeid = 0x3B;
468480
value = 9654.2529296875;
469-
offset = tempOffset;
470481

471482
data = Buffer.alloc(28);
472483
tempBuff.copy(data);
@@ -485,7 +496,6 @@ describe('Parsing a RETURNVALUE token', function() {
485496
it('should parse the FLT8TYPE/Float token correctly', function(done) {
486497
typeid = 0x3E;
487498
value = 9654.2546456567565767644;
488-
offset = tempOffset;
489499

490500
data = Buffer.alloc(32);
491501
tempBuff.copy(data);
@@ -504,7 +514,6 @@ describe('Parsing a RETURNVALUE token', function() {
504514
it('should parse the MONEYTYPE/Money token correctly', function(done) {
505515
typeid = 0x3C;
506516
value = 922337203.5807;
507-
offset = tempOffset;
508517

509518
const TDS_value = value * 10000;
510519
data = Buffer.alloc(32);
@@ -525,7 +534,6 @@ describe('Parsing a RETURNVALUE token', function() {
525534
it('should parse the MONEY4TYPE/SmallMoney token correctly', function(done) {
526535
typeid = 0x7A;
527536
value = -214748.3647;
528-
offset = tempOffset;
529537

530538
const TDS_value = value * 10000;
531539
data = Buffer.alloc(28);
@@ -545,7 +553,6 @@ describe('Parsing a RETURNVALUE token', function() {
545553
it('should parse the DATETIMETYPE/DateTime token correctly', function(done) {
546554
reader.options = {};
547555
reader.options.useUTC = true;
548-
offset = tempOffset;
549556

550557
typeid = 0x3D;
551558
value = new Date('2004-05-23T14:25:10.487Z');

0 commit comments

Comments
 (0)