monetdb 2.0.2 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/connection.d.ts +1 -0
- package/dist/connection.js +3 -0
- package/dist/connection.js.map +1 -1
- package/dist/mapi.d.ts +9 -14
- package/dist/mapi.js +249 -226
- package/dist/mapi.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/connection.ts +114 -110
- package/src/mapi.ts +936 -921
- package/dist/QueryStream.d.ts +0 -7
- package/dist/QueryStream.js +0 -13
- package/dist/QueryStream.js.map +0 -1
- package/dist/connections.d.ts +0 -1
- package/dist/connections.js +0 -49
- package/dist/connections.js.map +0 -1
package/dist/mapi.js
CHANGED
@@ -272,14 +272,18 @@ function parseTupleLine(line, types) {
|
|
272
272
|
}
|
273
273
|
class Response {
|
274
274
|
constructor(opt = {}) {
|
275
|
-
this.
|
275
|
+
this.chunks = [];
|
276
|
+
//this.buff = Buffer.allocUnsafe(MAPI_BLOCK_SIZE).fill(0);
|
276
277
|
this.offset = 0;
|
277
278
|
this.parseOffset = 0;
|
278
|
-
this.segments = [];
|
279
279
|
this.settled = false;
|
280
|
+
this.last = false;
|
281
|
+
this.headerEmitted = false;
|
280
282
|
this.stream = opt.stream;
|
281
283
|
this.callbacks = opt.callbacks;
|
282
284
|
this.fileHandler = opt.fileHandler;
|
285
|
+
this.leftOver = 0;
|
286
|
+
this._str = "";
|
283
287
|
if (opt.stream) {
|
284
288
|
this.queryStream = new QueryStream();
|
285
289
|
if (opt.callbacks && opt.callbacks.resolve)
|
@@ -287,103 +291,89 @@ class Response {
|
|
287
291
|
}
|
288
292
|
}
|
289
293
|
append(data) {
|
290
|
-
let srcStartIndx = 0;
|
291
|
-
let srcEndIndx = srcStartIndx + data.length;
|
292
|
-
const l = this.segments.length;
|
293
|
-
let segment = (l > 0 && this.segments[l - 1]) || undefined;
|
294
|
-
let bytesCopied = 0;
|
294
|
+
//let srcStartIndx = 0;
|
295
|
+
//let srcEndIndx = srcStartIndx + data.length;
|
295
296
|
let bytesProcessed = 0;
|
296
|
-
if (
|
297
|
-
//
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
}
|
314
|
-
else {
|
315
|
-
const byteCntToRead = segment.bytes - segment.bytesOffset;
|
316
|
-
srcEndIndx = srcStartIndx + byteCntToRead;
|
317
|
-
bytesCopied = data.copy(this.buff, this.offset, srcStartIndx, srcEndIndx);
|
318
|
-
this.offset += bytesCopied;
|
319
|
-
segment.bytesOffset += bytesCopied;
|
320
|
-
// console.log(`segment is full ${segment.bytesOffset === segment.bytes}`);
|
321
|
-
bytesProcessed = bytesCopied;
|
322
|
-
}
|
323
|
-
if (this.isQueryResponse()) {
|
324
|
-
const tuples = [];
|
325
|
-
const firstPackage = this.parseOffset === 0;
|
326
|
-
this.parseOffset += this.parse(this.toString(this.parseOffset), tuples);
|
327
|
-
if (tuples.length > 0) {
|
328
|
-
if (this.queryStream) {
|
329
|
-
// emit header once
|
330
|
-
if (firstPackage && this.result && this.result.columns) {
|
331
|
-
this.queryStream.emit("header", this.result.columns);
|
332
|
-
}
|
333
|
-
// emit tuples
|
334
|
-
this.queryStream.emit("data", tuples);
|
335
|
-
}
|
336
|
-
else {
|
337
|
-
this.result.data = this.result.data || [];
|
338
|
-
for (let t of tuples) {
|
339
|
-
this.result.data.push(t);
|
340
|
-
}
|
341
|
-
}
|
342
|
-
}
|
343
|
-
}
|
297
|
+
if (this.leftOver == 0) {
|
298
|
+
// new mapi blk, read header
|
299
|
+
const hdr = data.readUInt16LE(0);
|
300
|
+
this.last = (hdr & 1) === 1;
|
301
|
+
this.leftOver = hdr >> 1;
|
302
|
+
data = data.subarray(MAPI_HEADER_SIZE);
|
303
|
+
bytesProcessed += MAPI_HEADER_SIZE;
|
304
|
+
//bytesCopied = data.copy(
|
305
|
+
// this.buff,
|
306
|
+
// this.offset,
|
307
|
+
// srcStartIndx,
|
308
|
+
// srcEndIndx
|
309
|
+
//);
|
310
|
+
//segment = new Segment(bytes, last, this.offset, bytesCopied);
|
311
|
+
//this.segments.push(segment);
|
312
|
+
//this.offset += bytesCopied;
|
313
|
+
//bytesProcessed = MAPI_HEADER_SIZE + bytesCopied;
|
344
314
|
}
|
315
|
+
//else {
|
316
|
+
// const byteCntToRead = segment.bytes - segment.bytesOffset;
|
317
|
+
// srcEndIndx = srcStartIndx + byteCntToRead;
|
318
|
+
// bytesCopied = data.copy(
|
319
|
+
// this.buff,
|
320
|
+
// this.offset,
|
321
|
+
// srcStartIndx,
|
322
|
+
// srcEndIndx
|
323
|
+
// );
|
324
|
+
// this.offset += bytesCopied;
|
325
|
+
// segment.bytesOffset += bytesCopied;
|
326
|
+
// // console.log(`segment is full ${segment.bytesOffset === segment.bytes}`);
|
327
|
+
// bytesProcessed = bytesCopied;
|
328
|
+
//}
|
329
|
+
const bytesToRead = Math.min(data.length, this.leftOver);
|
330
|
+
//console.log(`bytesToRead ${bytesToRead}`);
|
331
|
+
if (bytesToRead > 0) {
|
332
|
+
const chunk = data.subarray(0, bytesToRead);
|
333
|
+
this.chunks.push(chunk);
|
334
|
+
this.leftOver -= bytesToRead;
|
335
|
+
bytesProcessed += bytesToRead;
|
336
|
+
}
|
337
|
+
//if (this.isQueryResponse()) {
|
338
|
+
// const tuples = [];
|
339
|
+
// // const firstPackage = this.parseOffset === 0;
|
340
|
+
// this.parseOffset += this.parseQueryResponse(
|
341
|
+
// this.toString(this.parseOffset),
|
342
|
+
// tuples
|
343
|
+
// );
|
344
|
+
// console.log("tuples");
|
345
|
+
// console.log(tuples);
|
346
|
+
// if (tuples.length > 0) {
|
347
|
+
// if (this.queryStream) {
|
348
|
+
// // emit header once
|
349
|
+
// if (
|
350
|
+
// this.headerEmitted === false &&
|
351
|
+
// this.result &&
|
352
|
+
// this.result.columns
|
353
|
+
// ) {
|
354
|
+
// this.queryStream.emit("header", this.result.columns);
|
355
|
+
// this.headerEmitted = true;
|
356
|
+
// }
|
357
|
+
// // emit tuples
|
358
|
+
// this.queryStream.emit("data", tuples);
|
359
|
+
// } else {
|
360
|
+
// this.result.data = this.result.data || [];
|
361
|
+
// for (let t of tuples) {
|
362
|
+
// this.result.data.push(t);
|
363
|
+
// }
|
364
|
+
// }
|
365
|
+
// }
|
366
|
+
//}
|
367
|
+
//console.log(`bytesProcessed ${bytesToRead}`);
|
345
368
|
return bytesProcessed;
|
346
369
|
}
|
347
370
|
complete() {
|
348
|
-
|
349
|
-
if (l > 0) {
|
350
|
-
const segment = this.segments[l - 1];
|
351
|
-
return segment.last && segment.isFull();
|
352
|
-
}
|
353
|
-
return false;
|
354
|
-
}
|
355
|
-
seekOffset() {
|
356
|
-
const len = this.segments.length;
|
357
|
-
if (len) {
|
358
|
-
const last = this.segments[len - 1];
|
359
|
-
if (last.isFull())
|
360
|
-
return last.offset + last.bytes;
|
361
|
-
return last.offset;
|
362
|
-
}
|
363
|
-
return 0;
|
364
|
-
}
|
365
|
-
expand(byteCount) {
|
366
|
-
if (this.buff.length + byteCount > MAX_BUFF_SIZE &&
|
367
|
-
this.fileHandler instanceof file_transfer_1.FileDownloader) {
|
368
|
-
const offset = this.seekOffset();
|
369
|
-
if (offset) {
|
370
|
-
this.fileHandler.writeChunk(this.buff.subarray(0, offset));
|
371
|
-
this.buff = this.buff.subarray(offset);
|
372
|
-
this.offset -= offset;
|
373
|
-
}
|
374
|
-
}
|
375
|
-
const buff = buffer_1.Buffer.allocUnsafe(this.buff.length + byteCount).fill(0);
|
376
|
-
const bytesCopied = this.buff.copy(buff);
|
377
|
-
this.buff = buff;
|
378
|
-
// should be byteCount
|
379
|
-
return this.buff.length - bytesCopied;
|
380
|
-
}
|
381
|
-
firstCharacter() {
|
382
|
-
return this.buff.toString("utf8", 0, 1);
|
371
|
+
return this.last && (this.leftOver == 0);
|
383
372
|
}
|
384
373
|
errorMessage() {
|
385
|
-
|
386
|
-
|
374
|
+
const msg = this.toString();
|
375
|
+
if (msg.startsWith(MSG_ERROR)) {
|
376
|
+
return msg;
|
387
377
|
}
|
388
378
|
return "";
|
389
379
|
}
|
@@ -391,27 +381,32 @@ class Response {
|
|
391
381
|
return this.toString().startsWith(MSG_FILETRANS);
|
392
382
|
}
|
393
383
|
isPrompt() {
|
394
|
-
|
395
|
-
return this.complete() && this.firstCharacter() === "\x00";
|
384
|
+
return this.complete() && this.toString() == MSG_PROMPT;
|
396
385
|
}
|
397
386
|
isRedirect() {
|
398
|
-
return this.
|
387
|
+
return this.toString().startsWith(MSG_REDIRECT);
|
399
388
|
}
|
400
389
|
isQueryResponse() {
|
401
390
|
if (this.result && this.result.type) {
|
402
391
|
return this.result.type.startsWith(MSG_Q);
|
403
392
|
}
|
404
|
-
return this.
|
393
|
+
return this.toString().startsWith(MSG_Q);
|
405
394
|
}
|
406
395
|
isMsgMore() {
|
407
396
|
// server wants more ?
|
408
397
|
return this.toString().startsWith(MSG_MORE);
|
409
398
|
}
|
410
399
|
toString(start) {
|
411
|
-
|
400
|
+
if (this.complete() && !this.queryStream && this._str) {
|
401
|
+
if (start)
|
402
|
+
return this._str.substring(start);
|
403
|
+
return this._str;
|
404
|
+
}
|
405
|
+
const buff = buffer_1.Buffer.concat(this.chunks);
|
406
|
+
this._str = buff.toString("utf8");
|
412
407
|
if (start)
|
413
|
-
return
|
414
|
-
return
|
408
|
+
return this._str.substring(start);
|
409
|
+
return this._str;
|
415
410
|
}
|
416
411
|
settle(res) {
|
417
412
|
if (this.settled === false && this.complete()) {
|
@@ -439,116 +434,113 @@ class Response {
|
|
439
434
|
}
|
440
435
|
}
|
441
436
|
this.settled = true;
|
437
|
+
this._str = "";
|
438
|
+
this.chunks = [];
|
442
439
|
}
|
443
440
|
}
|
444
|
-
|
441
|
+
parseQueryResponse(data, res) {
|
445
442
|
let offset = 0;
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
this.result.malOptimizerTime = parseInt(malOptimizerTime);
|
465
|
-
this.result.sqlOptimizerTime = parseInt(sqlOptimizerTime);
|
466
|
-
}
|
467
|
-
else if (this.result.type === MSG_QUPDATE) {
|
468
|
-
const [affectedRowCnt, autoIncrementId, queryId, queryTime, malOptimizerTime, sqlOptimizerTime,] = rest;
|
469
|
-
this.result.affectedRows = parseInt(affectedRowCnt);
|
470
|
-
this.result.queryId = parseInt(queryId);
|
471
|
-
this.result.queryTime = parseInt(queryTime);
|
472
|
-
this.result.malOptimizerTime = parseInt(malOptimizerTime);
|
473
|
-
this.result.sqlOptimizerTime = parseInt(sqlOptimizerTime);
|
474
|
-
}
|
475
|
-
else if (this.result.type === MSG_QSCHEMA) {
|
476
|
-
const [queryTime, malOptimizerTime] = rest;
|
477
|
-
this.result.queryTime = parseInt(queryTime);
|
478
|
-
this.result.malOptimizerTime = parseInt(malOptimizerTime);
|
479
|
-
}
|
480
|
-
else if (this.result.type === MSG_QTRANS) {
|
481
|
-
// skip
|
482
|
-
}
|
483
|
-
else if (this.result.type === MSG_QPREPARE) {
|
484
|
-
const [id, rowCnt, columnCnt, rows] = rest;
|
485
|
-
this.result.id = parseInt(id);
|
486
|
-
this.result.rowCnt = parseInt(rowCnt);
|
487
|
-
this.result.columnCnt = parseInt(columnCnt);
|
488
|
-
}
|
489
|
-
// end 1st line
|
490
|
-
if (this.headers === undefined &&
|
491
|
-
data.charAt(eol + 1) === MSG_HEADER &&
|
492
|
-
lines > 5) {
|
493
|
-
let headers = {};
|
494
|
-
while (data.charAt(eol + 1) === MSG_HEADER) {
|
495
|
-
const hs = eol + 1;
|
496
|
-
eol = data.indexOf("\n", hs);
|
497
|
-
headers = Object.assign(Object.assign({}, headers), parseHeaderLine(data.substring(hs, eol)));
|
443
|
+
let eol = data.indexOf("\n");
|
444
|
+
let line = eol > 0 ? data.substring(0, eol) : undefined;
|
445
|
+
while (line) {
|
446
|
+
switch (line.charAt(0)) {
|
447
|
+
case MSG_Q:
|
448
|
+
// first line
|
449
|
+
this.result = this.result || {};
|
450
|
+
this.result.type = line.substring(0, 2);
|
451
|
+
const rest = line.substring(3).trim().split(" ");
|
452
|
+
if (this.result.type === MSG_QTABLE) {
|
453
|
+
const [id, rowCnt, columnCnt, rows, queryId, queryTime, malOptimizerTime, sqlOptimizerTime,] = rest;
|
454
|
+
this.result.id = parseInt(id);
|
455
|
+
this.result.rowCnt = parseInt(rowCnt);
|
456
|
+
this.result.columnCnt = parseInt(columnCnt);
|
457
|
+
this.result.queryId = parseInt(queryId);
|
458
|
+
this.result.queryTime = parseInt(queryTime);
|
459
|
+
this.result.malOptimizerTime = parseInt(malOptimizerTime);
|
460
|
+
this.result.sqlOptimizerTime = parseInt(sqlOptimizerTime);
|
498
461
|
}
|
499
|
-
this.
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
table,
|
507
|
-
name,
|
508
|
-
type,
|
509
|
-
index: i,
|
510
|
-
});
|
462
|
+
else if (this.result.type === MSG_QUPDATE) {
|
463
|
+
const [affectedRowCnt, autoIncrementId, queryId, queryTime, malOptimizerTime, sqlOptimizerTime,] = rest;
|
464
|
+
this.result.affectedRows = parseInt(affectedRowCnt);
|
465
|
+
this.result.queryId = parseInt(queryId);
|
466
|
+
this.result.queryTime = parseInt(queryTime);
|
467
|
+
this.result.malOptimizerTime = parseInt(malOptimizerTime);
|
468
|
+
this.result.sqlOptimizerTime = parseInt(sqlOptimizerTime);
|
511
469
|
}
|
512
|
-
this.result.
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
const
|
529
|
-
|
530
|
-
|
531
|
-
ts = eol + 1;
|
532
|
-
eol = data.indexOf("\n", ts);
|
470
|
+
else if (this.result.type === MSG_QSCHEMA) {
|
471
|
+
const [queryTime, malOptimizerTime] = rest;
|
472
|
+
this.result.queryTime = parseInt(queryTime);
|
473
|
+
this.result.malOptimizerTime = parseInt(malOptimizerTime);
|
474
|
+
}
|
475
|
+
else if (this.result.type === MSG_QTRANS) {
|
476
|
+
// skip
|
477
|
+
}
|
478
|
+
else if (this.result.type === MSG_QPREPARE) {
|
479
|
+
const [id, rowCnt, columnCnt, rows] = rest;
|
480
|
+
this.result.id = parseInt(id);
|
481
|
+
this.result.rowCnt = parseInt(rowCnt);
|
482
|
+
this.result.columnCnt = parseInt(columnCnt);
|
483
|
+
}
|
484
|
+
break;
|
485
|
+
case MSG_HEADER:
|
486
|
+
const header = parseHeaderLine(line);
|
487
|
+
if (this.result.headers !== undefined) {
|
488
|
+
this.result.headers = Object.assign(Object.assign({}, this.result.headers), header);
|
533
489
|
}
|
534
490
|
else {
|
535
|
-
|
491
|
+
this.result.headers = header;
|
492
|
+
}
|
493
|
+
// if we have all headers we can compile column info
|
494
|
+
const haveAllHeaders = Boolean(this.result.headers.tableNames) &&
|
495
|
+
Boolean(this.result.headers.columnNames) &&
|
496
|
+
Boolean(this.result.headers.columnTypes);
|
497
|
+
if (this.result.columns === undefined && haveAllHeaders) {
|
498
|
+
const colums = [];
|
499
|
+
for (let i = 0; i < this.result.columnCnt; i++) {
|
500
|
+
const table = this.result.headers.tableNames[i];
|
501
|
+
const name = this.result.headers.columnNames[i];
|
502
|
+
const type = this.result.headers.columnTypes[i];
|
503
|
+
colums.push({
|
504
|
+
table,
|
505
|
+
name,
|
506
|
+
type,
|
507
|
+
index: i,
|
508
|
+
});
|
509
|
+
}
|
510
|
+
this.result.columns = colums;
|
536
511
|
}
|
537
|
-
|
512
|
+
break;
|
513
|
+
case MSG_TUPLE:
|
514
|
+
const tuple = parseTupleLine(line, this.result.headers.columnTypes);
|
515
|
+
res.push(tuple);
|
516
|
+
break;
|
517
|
+
default:
|
518
|
+
throw TypeError(`Invalid query response line!\n${line}`);
|
538
519
|
}
|
520
|
+
// line is processed advance offset
|
521
|
+
offset = eol + 1;
|
522
|
+
// get next line
|
523
|
+
eol = data.indexOf("\n", offset);
|
524
|
+
line = eol > 0 ? data.substring(offset, eol) : undefined;
|
539
525
|
}
|
540
526
|
return offset;
|
541
527
|
}
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
528
|
+
streamResult() {
|
529
|
+
if (this.queryStream && this.isQueryResponse()) {
|
530
|
+
const tuples = [];
|
531
|
+
this.parseOffset += this.parseQueryResponse(this.toString(this.parseOffset), tuples);
|
532
|
+
if (tuples.length > 0) {
|
533
|
+
// emit header once
|
534
|
+
if (this.headerEmitted === false &&
|
535
|
+
this.result &&
|
536
|
+
this.result.columns) {
|
537
|
+
this.queryStream.emit("header", this.result.columns);
|
538
|
+
this.headerEmitted = true;
|
539
|
+
}
|
540
|
+
// emit tuples
|
541
|
+
this.queryStream.emit("data", tuples);
|
542
|
+
}
|
543
|
+
}
|
552
544
|
}
|
553
545
|
}
|
554
546
|
class MapiConnection extends events_1.EventEmitter {
|
@@ -561,23 +553,12 @@ class MapiConnection extends events_1.EventEmitter {
|
|
561
553
|
socket.addListener("data", this.recv.bind(this));
|
562
554
|
socket.addListener("error", this.handleSocketError.bind(this));
|
563
555
|
socket.addListener("timeout", this.handleTimeout.bind(this));
|
564
|
-
socket.
|
565
|
-
console.log("
|
566
|
-
this.emit("end");
|
556
|
+
socket.once("end", () => {
|
557
|
+
console.log("Server has ended the connection");
|
567
558
|
});
|
568
559
|
return socket;
|
569
560
|
};
|
570
561
|
this.state = MAPI_STATE.INIT;
|
571
|
-
this.socket = this.createSocket(config.timeout);
|
572
|
-
// this.socket = new Socket();
|
573
|
-
// if (config.timeout) this.socket.setTimeout(config.timeout);
|
574
|
-
// this.socket.addListener("data", this.recv.bind(this));
|
575
|
-
// this.socket.addListener("error", this.handleSocketError.bind(this));
|
576
|
-
// this.socket.addListener("timeout", this.handleTimeout.bind(this));
|
577
|
-
// this.socket.addListener("close", () => {
|
578
|
-
// console.log("socket close event");
|
579
|
-
// this.emit("end");
|
580
|
-
// });
|
581
562
|
this.redirects = 0;
|
582
563
|
this.queue = [];
|
583
564
|
this.database = config.database;
|
@@ -608,18 +589,46 @@ class MapiConnection extends events_1.EventEmitter {
|
|
608
589
|
return (0, events_1.once)(this, "ready");
|
609
590
|
}
|
610
591
|
ready() {
|
611
|
-
return this.state === MAPI_STATE.READY;
|
592
|
+
return this.socket && this.socket.writable && this.state === MAPI_STATE.READY;
|
612
593
|
}
|
613
594
|
disconnect() {
|
614
595
|
return new Promise((resolve, reject) => {
|
615
|
-
this.socket.
|
616
|
-
this.
|
596
|
+
if (!this.socket || this.socket.destroyed) {
|
597
|
+
this.socket = null;
|
617
598
|
this.state = MAPI_STATE.INIT;
|
618
|
-
|
619
|
-
|
620
|
-
|
599
|
+
return resolve(true);
|
600
|
+
}
|
601
|
+
const onClose = () => {
|
602
|
+
cleanup();
|
603
|
+
this.socket = null;
|
604
|
+
this.state = MAPI_STATE.INIT;
|
605
|
+
resolve(true);
|
606
|
+
};
|
607
|
+
const onError = (err) => {
|
608
|
+
var _a;
|
609
|
+
console.error(err);
|
610
|
+
cleanup();
|
611
|
+
(_a = this.socket) === null || _a === void 0 ? void 0 : _a.destroy(); // force cleanup
|
612
|
+
this.socket = null;
|
613
|
+
this.state = MAPI_STATE.INIT;
|
614
|
+
reject(err);
|
615
|
+
};
|
616
|
+
const cleanup = () => {
|
617
|
+
var _a, _b;
|
618
|
+
(_a = this.socket) === null || _a === void 0 ? void 0 : _a.removeListener("close", onClose);
|
619
|
+
(_b = this.socket) === null || _b === void 0 ? void 0 : _b.removeListener("error", onError);
|
620
|
+
};
|
621
|
+
this.socket.once("close", onClose);
|
622
|
+
this.socket.once("error", onError);
|
623
|
+
// Initiate graceful shutdown
|
624
|
+
this.socket.end();
|
621
625
|
});
|
622
626
|
}
|
627
|
+
destroy() {
|
628
|
+
if (this.socket && !this.socket.destroyed)
|
629
|
+
this.socket.destroy();
|
630
|
+
this.socket = null;
|
631
|
+
}
|
623
632
|
login(challenge) {
|
624
633
|
const challengeParts = challenge.split(":");
|
625
634
|
const [salt, identity, protocol, hashes, endian, algo, opt_level] = challengeParts;
|
@@ -718,7 +727,8 @@ class MapiConnection extends events_1.EventEmitter {
|
|
718
727
|
this.emit("error", new Error("Timeout"));
|
719
728
|
}
|
720
729
|
handleSocketError(err) {
|
721
|
-
console.error(err);
|
730
|
+
console.error('Socket error: ', err);
|
731
|
+
this.destroy();
|
722
732
|
}
|
723
733
|
request(sql, stream = false) {
|
724
734
|
return __awaiter(this, void 0, void 0, function* () {
|
@@ -751,8 +761,9 @@ class MapiConnection extends events_1.EventEmitter {
|
|
751
761
|
recv(data) {
|
752
762
|
let bytesLeftOver;
|
753
763
|
let resp;
|
754
|
-
// process queue left to right,
|
755
|
-
//
|
764
|
+
// process queue left to right,
|
765
|
+
// find 1st uncomplete response
|
766
|
+
// remove complete responses
|
756
767
|
while (this.queue.length) {
|
757
768
|
const next = this.queue[0];
|
758
769
|
if (next.complete() || next.settled) {
|
@@ -766,17 +777,23 @@ class MapiConnection extends events_1.EventEmitter {
|
|
766
777
|
if (resp === undefined && this.queue.length === 0) {
|
767
778
|
// challenge message
|
768
779
|
// or direct call to send has being made
|
769
|
-
//
|
780
|
+
// request api appends Response to the queue
|
770
781
|
resp = new Response();
|
771
782
|
this.queue.push(resp);
|
772
783
|
}
|
773
|
-
|
784
|
+
let offset = 0;
|
785
|
+
let end = data.length;
|
786
|
+
do {
|
787
|
+
offset += resp.append(data.subarray(offset, end));
|
788
|
+
} while ((offset < end) && !resp.complete());
|
789
|
+
if (resp.queryStream)
|
790
|
+
resp.streamResult();
|
774
791
|
if (resp.complete())
|
775
792
|
this.handleResponse(resp);
|
776
793
|
bytesLeftOver = data.length - offset;
|
777
794
|
if (bytesLeftOver) {
|
778
|
-
const msg = `some ${bytesLeftOver} bytes left over!`;
|
779
|
-
console.warn(msg);
|
795
|
+
//const msg = `some ${bytesLeftOver} bytes left over!`;
|
796
|
+
//console.warn(msg);
|
780
797
|
this.recv(data.subarray(offset));
|
781
798
|
}
|
782
799
|
}
|
@@ -794,7 +811,7 @@ class MapiConnection extends events_1.EventEmitter {
|
|
794
811
|
return;
|
795
812
|
}
|
796
813
|
if (resp.isPrompt()) {
|
797
|
-
console.log("login OK");
|
814
|
+
//console.log("login OK");
|
798
815
|
this.state = MAPI_STATE.READY;
|
799
816
|
this.emit("ready", this.state);
|
800
817
|
return;
|
@@ -802,7 +819,7 @@ class MapiConnection extends events_1.EventEmitter {
|
|
802
819
|
return this.login(resp.toString());
|
803
820
|
}
|
804
821
|
if (resp.isFileTransfer()) {
|
805
|
-
console.log("file transfer");
|
822
|
+
//console.log("file transfer");
|
806
823
|
let fhandler;
|
807
824
|
const msg = resp.toString(MSG_FILETRANS.length).trim();
|
808
825
|
let mode, offset, file;
|
@@ -839,11 +856,17 @@ class MapiConnection extends events_1.EventEmitter {
|
|
839
856
|
resp.fileHandler.ready()) {
|
840
857
|
// end of download
|
841
858
|
const fileHandler = resp.fileHandler;
|
842
|
-
|
859
|
+
const buff = buffer_1.Buffer.concat(resp.chunks);
|
860
|
+
fileHandler.writeChunk(buff);
|
843
861
|
// we do expect a final response from server
|
844
862
|
this.queue.push(new Response({ fileHandler }));
|
845
863
|
return resp.settle(fileHandler.close());
|
846
864
|
}
|
865
|
+
if (resp.isQueryResponse()) {
|
866
|
+
const data = [];
|
867
|
+
resp.parseQueryResponse(resp.toString(), data);
|
868
|
+
resp.result.data = data;
|
869
|
+
}
|
847
870
|
resp.settle();
|
848
871
|
}
|
849
872
|
}
|