dolphindb 3.0.2 → 3.0.20
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 -2
- package/README.zh.md +1 -2
- package/browser.d.ts +244 -44
- package/browser.js +741 -178
- package/browser.js.map +1 -1
- package/i18n/dict.json +6 -0
- package/i18n/index.js +1 -1
- package/i18n/index.js.map +1 -1
- package/index.d.ts +242 -42
- package/index.js +746 -190
- package/index.js.map +1 -1
- package/package.json +6 -6
- package/test.d.ts +1 -2
- package/test.js +74 -9
- package/test.js.map +1 -1
- package/unused.js +5 -1
- package/unused.js.map +1 -1
- package/data-types/decimal-128.d.ts +0 -21
- package/data-types/decimal-128.js +0 -34
- package/data-types/decimal-128.js.map +0 -1
- package/shared/bigint-128-array.d.ts +0 -26
- package/shared/bigint-128-array.js +0 -145
- package/shared/bigint-128-array.js.map +0 -1
- package/shared/constants.d.ts +0 -113
- package/shared/constants.js +0 -123
- package/shared/constants.js.map +0 -1
- package/shared/data-view-extends.d.ts +0 -4
- package/shared/data-view-extends.js +0 -45
- package/shared/data-view-extends.js.map +0 -1
- package/shared/utils.d.ts +0 -4
- package/shared/utils.js +0 -17
- package/shared/utils.js.map +0 -1
package/index.js
CHANGED
|
@@ -1,24 +1,131 @@
|
|
|
1
|
-
// import { table, getBorderCharacters, type TableUserConfig } from 'table'
|
|
2
1
|
import dayjs from 'dayjs';
|
|
3
2
|
import DayjsCustomParseFormat from 'dayjs/plugin/customParseFormat.js';
|
|
4
3
|
dayjs.extend(DayjsCustomParseFormat);
|
|
5
4
|
import ipaddrjs from 'ipaddr.js';
|
|
6
5
|
const { fromByteArray: buf2ipaddr } = ipaddrjs;
|
|
7
|
-
import { concat, assert, inspect, typed_array_to_buffer, connect_websocket, Lock, genid, WebSocketOpen, WebSocketClosed, WebSocketClosing } from 'xshell';
|
|
6
|
+
import { concat, assert, inspect, typed_array_to_buffer, connect_websocket, Lock, genid, seq, zip_object, WebSocketOpen, WebSocketClosed, WebSocketClosing, } from 'xshell';
|
|
8
7
|
import { t } from './i18n/index.js';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const value_str = values.length ? ` ${values.map(v => String(v) + 'n').join(', ')} ` : '';
|
|
20
|
-
return `${this[Symbol.toStringTag]}(${this.length}) [${value_str}]`;
|
|
8
|
+
export const nulls = {
|
|
9
|
+
int8: -0x80, // -128
|
|
10
|
+
int16: -0x80_00, // -32768
|
|
11
|
+
int32: -0x80_00_00_00, // -21_4748_3648
|
|
12
|
+
int64: -0x8000000000000000n, // -922_3372_0368_5477_5808
|
|
13
|
+
int128: -0x80000000000000000000000000000000n, // -170_1411_8346_0469_2317_3168_7303_7158_8410_5728
|
|
14
|
+
float32: -3.4028234663852886e+38,
|
|
15
|
+
/** -Number.MAX_VALUE */
|
|
16
|
+
double: -Number.MAX_VALUE,
|
|
17
|
+
bytes16: Uint8Array.from(new Array(16).fill(0))
|
|
21
18
|
};
|
|
19
|
+
export var DdbForm;
|
|
20
|
+
(function (DdbForm) {
|
|
21
|
+
DdbForm[DdbForm["scalar"] = 0] = "scalar";
|
|
22
|
+
DdbForm[DdbForm["vector"] = 1] = "vector";
|
|
23
|
+
DdbForm[DdbForm["pair"] = 2] = "pair";
|
|
24
|
+
DdbForm[DdbForm["matrix"] = 3] = "matrix";
|
|
25
|
+
DdbForm[DdbForm["set"] = 4] = "set";
|
|
26
|
+
DdbForm[DdbForm["dict"] = 5] = "dict";
|
|
27
|
+
DdbForm[DdbForm["table"] = 6] = "table";
|
|
28
|
+
DdbForm[DdbForm["chart"] = 7] = "chart";
|
|
29
|
+
/** 节点内部通信可能会使用,调用函数执行脚本一般不会返回这种类型 */
|
|
30
|
+
DdbForm[DdbForm["chunk"] = 8] = "chunk";
|
|
31
|
+
/** sysobj */
|
|
32
|
+
DdbForm[DdbForm["object"] = 9] = "object";
|
|
33
|
+
})(DdbForm || (DdbForm = {}));
|
|
34
|
+
/** DolphinDB DataType
|
|
35
|
+
对应的 array vector 类型为 64 + 基本类型
|
|
36
|
+
对应的 extended 类型为 128 + 基本类型 */
|
|
37
|
+
export var DdbType;
|
|
38
|
+
(function (DdbType) {
|
|
39
|
+
DdbType[DdbType["void"] = 0] = "void";
|
|
40
|
+
DdbType[DdbType["bool"] = 1] = "bool";
|
|
41
|
+
DdbType[DdbType["char"] = 2] = "char";
|
|
42
|
+
DdbType[DdbType["short"] = 3] = "short";
|
|
43
|
+
DdbType[DdbType["int"] = 4] = "int";
|
|
44
|
+
DdbType[DdbType["long"] = 5] = "long";
|
|
45
|
+
DdbType[DdbType["date"] = 6] = "date";
|
|
46
|
+
DdbType[DdbType["month"] = 7] = "month";
|
|
47
|
+
DdbType[DdbType["time"] = 8] = "time";
|
|
48
|
+
DdbType[DdbType["minute"] = 9] = "minute";
|
|
49
|
+
DdbType[DdbType["second"] = 10] = "second";
|
|
50
|
+
DdbType[DdbType["datetime"] = 11] = "datetime";
|
|
51
|
+
DdbType[DdbType["timestamp"] = 12] = "timestamp";
|
|
52
|
+
DdbType[DdbType["nanotime"] = 13] = "nanotime";
|
|
53
|
+
DdbType[DdbType["nanotimestamp"] = 14] = "nanotimestamp";
|
|
54
|
+
DdbType[DdbType["float"] = 15] = "float";
|
|
55
|
+
DdbType[DdbType["double"] = 16] = "double";
|
|
56
|
+
DdbType[DdbType["symbol"] = 17] = "symbol";
|
|
57
|
+
DdbType[DdbType["string"] = 18] = "string";
|
|
58
|
+
DdbType[DdbType["uuid"] = 19] = "uuid";
|
|
59
|
+
DdbType[DdbType["functiondef"] = 20] = "functiondef";
|
|
60
|
+
DdbType[DdbType["handle"] = 21] = "handle";
|
|
61
|
+
DdbType[DdbType["code"] = 22] = "code";
|
|
62
|
+
DdbType[DdbType["datasource"] = 23] = "datasource";
|
|
63
|
+
DdbType[DdbType["resource"] = 24] = "resource";
|
|
64
|
+
DdbType[DdbType["any"] = 25] = "any";
|
|
65
|
+
DdbType[DdbType["compressed"] = 26] = "compressed";
|
|
66
|
+
DdbType[DdbType["dict"] = 27] = "dict";
|
|
67
|
+
DdbType[DdbType["datehour"] = 28] = "datehour";
|
|
68
|
+
DdbType[DdbType["ipaddr"] = 30] = "ipaddr";
|
|
69
|
+
DdbType[DdbType["int128"] = 31] = "int128";
|
|
70
|
+
DdbType[DdbType["blob"] = 32] = "blob";
|
|
71
|
+
DdbType[DdbType["complex"] = 34] = "complex";
|
|
72
|
+
DdbType[DdbType["point"] = 35] = "point";
|
|
73
|
+
DdbType[DdbType["duration"] = 36] = "duration";
|
|
74
|
+
DdbType[DdbType["decimal32"] = 37] = "decimal32";
|
|
75
|
+
DdbType[DdbType["decimal64"] = 38] = "decimal64";
|
|
76
|
+
DdbType[DdbType["decimal128"] = 39] = "decimal128";
|
|
77
|
+
DdbType[DdbType["object"] = 40] = "object";
|
|
78
|
+
DdbType[DdbType["pynone"] = 41] = "pynone";
|
|
79
|
+
DdbType[DdbType["symbol_extended"] = 145] = "symbol_extended";
|
|
80
|
+
})(DdbType || (DdbType = {}));
|
|
81
|
+
export var DdbFunctionType;
|
|
82
|
+
(function (DdbFunctionType) {
|
|
83
|
+
DdbFunctionType[DdbFunctionType["SystemFunc"] = 0] = "SystemFunc";
|
|
84
|
+
DdbFunctionType[DdbFunctionType["SystemProc"] = 1] = "SystemProc";
|
|
85
|
+
DdbFunctionType[DdbFunctionType["OperatorFunc"] = 2] = "OperatorFunc";
|
|
86
|
+
DdbFunctionType[DdbFunctionType["UserDefinedFunc"] = 3] = "UserDefinedFunc";
|
|
87
|
+
DdbFunctionType[DdbFunctionType["PartialFunc"] = 4] = "PartialFunc";
|
|
88
|
+
DdbFunctionType[DdbFunctionType["DynamicFunc"] = 5] = "DynamicFunc";
|
|
89
|
+
DdbFunctionType[DdbFunctionType["PiecewiseFunc"] = 6] = "PiecewiseFunc";
|
|
90
|
+
DdbFunctionType[DdbFunctionType["JitFunc"] = 7] = "JitFunc";
|
|
91
|
+
DdbFunctionType[DdbFunctionType["JitPartialFunc"] = 8] = "JitPartialFunc";
|
|
92
|
+
})(DdbFunctionType || (DdbFunctionType = {}));
|
|
93
|
+
export var DdbDurationUnit;
|
|
94
|
+
(function (DdbDurationUnit) {
|
|
95
|
+
DdbDurationUnit[DdbDurationUnit["ns"] = 0] = "ns";
|
|
96
|
+
DdbDurationUnit[DdbDurationUnit["us"] = 1] = "us";
|
|
97
|
+
DdbDurationUnit[DdbDurationUnit["ms"] = 2] = "ms";
|
|
98
|
+
DdbDurationUnit[DdbDurationUnit["s"] = 3] = "s";
|
|
99
|
+
DdbDurationUnit[DdbDurationUnit["m"] = 4] = "m";
|
|
100
|
+
DdbDurationUnit[DdbDurationUnit["H"] = 5] = "H";
|
|
101
|
+
DdbDurationUnit[DdbDurationUnit["d"] = 6] = "d";
|
|
102
|
+
DdbDurationUnit[DdbDurationUnit["w"] = 7] = "w";
|
|
103
|
+
DdbDurationUnit[DdbDurationUnit["M"] = 8] = "M";
|
|
104
|
+
DdbDurationUnit[DdbDurationUnit["y"] = 9] = "y";
|
|
105
|
+
DdbDurationUnit[DdbDurationUnit["B"] = 10] = "B";
|
|
106
|
+
})(DdbDurationUnit || (DdbDurationUnit = {}));
|
|
107
|
+
export var DdbChartType;
|
|
108
|
+
(function (DdbChartType) {
|
|
109
|
+
DdbChartType[DdbChartType["area"] = 0] = "area";
|
|
110
|
+
DdbChartType[DdbChartType["bar"] = 1] = "bar";
|
|
111
|
+
DdbChartType[DdbChartType["column"] = 2] = "column";
|
|
112
|
+
DdbChartType[DdbChartType["histogram"] = 3] = "histogram";
|
|
113
|
+
DdbChartType[DdbChartType["line"] = 4] = "line";
|
|
114
|
+
DdbChartType[DdbChartType["pie"] = 5] = "pie";
|
|
115
|
+
DdbChartType[DdbChartType["scatter"] = 6] = "scatter";
|
|
116
|
+
DdbChartType[DdbChartType["trend"] = 7] = "trend";
|
|
117
|
+
DdbChartType[DdbChartType["kline"] = 8] = "kline";
|
|
118
|
+
})(DdbChartType || (DdbChartType = {}));
|
|
119
|
+
// server 实现中区分了 0: NULL (nothing), 1: NULL (null), 2: DFLT (default)
|
|
120
|
+
// Void::serialize()
|
|
121
|
+
// (isNothing() ? 0 : 1) + (isDefault_ ? 2 : 0);
|
|
122
|
+
export var DdbVoidType;
|
|
123
|
+
(function (DdbVoidType) {
|
|
124
|
+
DdbVoidType[DdbVoidType["undefined"] = 0] = "undefined";
|
|
125
|
+
DdbVoidType[DdbVoidType["null"] = 1] = "null";
|
|
126
|
+
DdbVoidType[DdbVoidType["default"] = 2] = "default";
|
|
127
|
+
})(DdbVoidType || (DdbVoidType = {}));
|
|
128
|
+
export const dictables = new Set([DdbType.any, DdbType.string, DdbType.double, DdbType.float, DdbType.int, DdbType.long]);
|
|
22
129
|
/** 可以表示所有 DolphinDB 数据库中的数据类型 Can represent data types in all DolphinDB databases */
|
|
23
130
|
export class DdbObj {
|
|
24
131
|
static dec = new TextDecoder('utf-8');
|
|
@@ -39,15 +146,13 @@ export class DdbObj {
|
|
|
39
146
|
length;
|
|
40
147
|
/** table name / column name */
|
|
41
148
|
name;
|
|
42
|
-
/**
|
|
43
|
-
最低维、第 1 维
|
|
149
|
+
/** 最低维、第 1 维
|
|
44
150
|
- vector: rows = n, cols = 1
|
|
45
151
|
- pair: rows = 2, cols = 1
|
|
46
152
|
- matrix: rows = n, cols = m
|
|
47
153
|
- set: 同 vector
|
|
48
154
|
- dict: 包含 keys, values 向量
|
|
49
|
-
- table: 同 matrix
|
|
50
|
-
*/
|
|
155
|
+
- table: 同 matrix */
|
|
51
156
|
rows;
|
|
52
157
|
/** 第 2 维 */
|
|
53
158
|
cols;
|
|
@@ -127,7 +232,7 @@ export class DdbObj {
|
|
|
127
232
|
let i_start = i_items_start + len_items;
|
|
128
233
|
for (let i = 0; i < cols; i++) {
|
|
129
234
|
const type = buf_data[i_start];
|
|
130
|
-
if (type === DdbType.
|
|
235
|
+
if (type === DdbType.compressed)
|
|
131
236
|
throw new Error(t('{{form}}<{{type}}> 暂时不支持解析', { form: 'table', type: 'compress' }));
|
|
132
237
|
let col = this.parse_vector(buf_data.subarray(i_start + 2), le, type);
|
|
133
238
|
col.length += 2;
|
|
@@ -376,20 +481,21 @@ export class DdbObj {
|
|
|
376
481
|
return [12, { scale: dv.getInt32(0, le), data: data === nulls.int64 ? null : data }];
|
|
377
482
|
}
|
|
378
483
|
case DdbType.decimal128: {
|
|
379
|
-
|
|
484
|
+
const dv = new DataView(buf.buffer, buf.byteOffset);
|
|
485
|
+
const data = get_big_int_128(dv, 4, le);
|
|
486
|
+
return [20, { scale: dv.getInt32(0, le), data: data === nulls.int128 ? null : data }];
|
|
380
487
|
}
|
|
381
488
|
default:
|
|
382
489
|
throw new Error(String(DdbType[type] || type) + t(' 暂时不支持解析'));
|
|
383
490
|
}
|
|
384
491
|
}
|
|
385
492
|
/** parse: rows, cols, items
|
|
386
|
-
返回的 ddbobj.length 不包括 vector 的 type 和 form
|
|
387
|
-
*/
|
|
493
|
+
返回的 ddbobj.length 不包括 vector 的 type 和 form */
|
|
388
494
|
static parse_vector(buf, le, type) {
|
|
389
495
|
const dv = new DataView(buf.buffer, buf.byteOffset);
|
|
390
496
|
const rows = dv.getUint32(0, le);
|
|
391
497
|
let i_items_start = 8;
|
|
392
|
-
if (type < 64 || type >= 128) {
|
|
498
|
+
if (type < 64 || type >= 128) { // 普通数组
|
|
393
499
|
const [len_items, value] = this.parse_vector_items(buf.subarray(i_items_start), le, type, rows);
|
|
394
500
|
return new this({
|
|
395
501
|
le,
|
|
@@ -401,119 +507,121 @@ export class DdbObj {
|
|
|
401
507
|
value,
|
|
402
508
|
});
|
|
403
509
|
}
|
|
404
|
-
// array vector
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
}
|
|
454
|
-
let i_block_start = i_items_start;
|
|
455
|
-
// 解析一个 block
|
|
456
|
-
for (let i_row = 0; i_row < rows;) {
|
|
457
|
-
/** 对应 array vector 中元素个数 */
|
|
458
|
-
const rows = dv.getUint16(i_block_start, le);
|
|
459
|
-
/** 每个 length 占用的字节数 */
|
|
460
|
-
const unit = dv.getUint8(i_block_start + 2);
|
|
461
|
-
/** array vector 每个元素的子元素长度 */
|
|
462
|
-
let lengths;
|
|
463
|
-
const i_lengths_start = i_block_start + 4;
|
|
464
|
-
const i_data_start = i_lengths_start + rows * unit;
|
|
465
|
-
const lengths_buf = buf.slice(i_lengths_start, i_data_start);
|
|
466
|
-
switch (unit) {
|
|
467
|
-
case 1:
|
|
468
|
-
lengths = lengths_buf;
|
|
469
|
-
break;
|
|
470
|
-
case 2:
|
|
471
|
-
lengths = new Uint16Array(lengths_buf.buffer);
|
|
472
|
-
break;
|
|
473
|
-
case 4:
|
|
474
|
-
lengths = new Uint32Array(lengths_buf.buffer);
|
|
475
|
-
break;
|
|
476
|
-
default:
|
|
477
|
-
throw new Error(t('array vector 存在非法 unit: {{unit}}', { unit }));
|
|
510
|
+
else { // array vector
|
|
511
|
+
// av = array(INT[], 0, 3)
|
|
512
|
+
// append!(av, [1..4])
|
|
513
|
+
// append!(av, [1..70000])
|
|
514
|
+
// av
|
|
515
|
+
// <Buffer 44 01 type = array vector, form = vector
|
|
516
|
+
// 02 00 00 00 74 11 01 00 rows = 2, cols = 70004 (0x011174)
|
|
517
|
+
// block 0
|
|
518
|
+
// 01 00 block.rows = 1
|
|
519
|
+
// 04 block.unit = 4
|
|
520
|
+
// 00 reserved
|
|
521
|
+
// 04 00 00 00 block.lengths = [4]
|
|
522
|
+
// 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 block.data
|
|
523
|
+
// block 1
|
|
524
|
+
// 01 00 block.rows = 1
|
|
525
|
+
// 04 block.unit = 4
|
|
526
|
+
// 00 reserved
|
|
527
|
+
// 70 11 01 00 block.lengths = [70000 (0x00011170)]
|
|
528
|
+
// 01 00 00 00 02 00 00 00 ... 279992 more bytes> block.data
|
|
529
|
+
// decimal array vector
|
|
530
|
+
// a = array(DECIMAL32(2)[], 0, 10)
|
|
531
|
+
// append!(a, [
|
|
532
|
+
// [1, 2, 3],
|
|
533
|
+
// [4, 5],
|
|
534
|
+
// [6, 7, 8],
|
|
535
|
+
// [9, 10]
|
|
536
|
+
// ])
|
|
537
|
+
// print(a)
|
|
538
|
+
// a
|
|
539
|
+
// [[1.00,2.00,3.00],[4.00,5.00],[6.00,7.00,8.00],[9.00,10.00]]
|
|
540
|
+
// <Buffer 65 01 type = 101 = 64 + 37 (decimal32) , form = vector
|
|
541
|
+
// 04 00 00 00 0a 00 00 00 rows = 4, cols = 10
|
|
542
|
+
// scale (只有 decimal32 才有)
|
|
543
|
+
// 02 00 00 00 scale = 2
|
|
544
|
+
// block 0
|
|
545
|
+
// 04 00 block.rows = 4
|
|
546
|
+
// 01 block.unit = 1
|
|
547
|
+
// 00 reserved
|
|
548
|
+
// 03 02 03 02 block.lengths = [3, 2, 3, 2]
|
|
549
|
+
// 64 00 00 00 c8 00 00 00 2c 01 00 00 90 01 00 00 f4 01 00 00 58 02 00 00 bc 02 00 00 ... 12 more bytes> [100, 200, 300, ...]
|
|
550
|
+
// block 1
|
|
551
|
+
// ...
|
|
552
|
+
const type_ = type - 64;
|
|
553
|
+
const cols = dv.getUint32(4, le);
|
|
554
|
+
let blocks = [];
|
|
555
|
+
// decimal 会在所有 blocks 之前多一个 scale
|
|
556
|
+
if (is_decimal_type(type_)) {
|
|
557
|
+
blocks.scale = dv.getInt32(i_items_start, le);
|
|
558
|
+
i_items_start += 4;
|
|
478
559
|
}
|
|
479
|
-
let
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
560
|
+
let i_block_start = i_items_start;
|
|
561
|
+
// 解析一个 block
|
|
562
|
+
for (let i_row = 0; i_row < rows;) {
|
|
563
|
+
/** 对应 array vector 中元素个数 */
|
|
564
|
+
const rows = dv.getUint16(i_block_start, le);
|
|
565
|
+
/** 每个 length 占用的字节数 */
|
|
566
|
+
const unit = dv.getUint8(i_block_start + 2);
|
|
567
|
+
/** array vector 每个元素的子元素长度 */
|
|
568
|
+
let lengths;
|
|
569
|
+
const i_lengths_start = i_block_start + 4;
|
|
570
|
+
const i_data_start = i_lengths_start + rows * unit;
|
|
571
|
+
const lengths_buf = buf.slice(i_lengths_start, i_data_start);
|
|
572
|
+
switch (unit) {
|
|
573
|
+
case 1:
|
|
574
|
+
lengths = lengths_buf;
|
|
575
|
+
break;
|
|
576
|
+
case 2:
|
|
577
|
+
lengths = new Uint16Array(lengths_buf.buffer);
|
|
578
|
+
break;
|
|
579
|
+
case 4:
|
|
580
|
+
lengths = new Uint32Array(lengths_buf.buffer);
|
|
581
|
+
break;
|
|
582
|
+
default:
|
|
583
|
+
throw new Error(t('array vector 存在非法 unit: {{unit}}', { unit }));
|
|
584
|
+
}
|
|
585
|
+
let total_length = 0;
|
|
586
|
+
for (const x of lengths)
|
|
587
|
+
total_length += x;
|
|
588
|
+
let len_items;
|
|
589
|
+
let data;
|
|
590
|
+
switch (type_) {
|
|
591
|
+
case DdbType.decimal32:
|
|
592
|
+
len_items = total_length * 4;
|
|
593
|
+
data = new Int32Array(buf.buffer.slice(buf.byteOffset + i_data_start, buf.byteOffset + i_data_start + len_items));
|
|
594
|
+
break;
|
|
595
|
+
case DdbType.decimal64:
|
|
596
|
+
len_items = total_length * 8;
|
|
597
|
+
data = new BigInt64Array(buf.buffer.slice(buf.byteOffset + i_data_start, buf.byteOffset + i_data_start + len_items));
|
|
598
|
+
break;
|
|
599
|
+
case DdbType.decimal128:
|
|
600
|
+
len_items = total_length * 16;
|
|
601
|
+
data = new BigInt128Array(buf.buffer.slice(buf.byteOffset + i_data_start, buf.byteOffset + i_data_start + len_items));
|
|
602
|
+
break;
|
|
603
|
+
default:
|
|
604
|
+
[len_items, data] = this.parse_vector_items(buf.subarray(i_data_start), le, type - 64, total_length);
|
|
605
|
+
}
|
|
606
|
+
blocks.push({
|
|
607
|
+
unit,
|
|
608
|
+
rows,
|
|
609
|
+
lengths,
|
|
610
|
+
data: data
|
|
611
|
+
});
|
|
612
|
+
i_block_start = i_data_start + len_items;
|
|
613
|
+
i_row += rows;
|
|
498
614
|
}
|
|
499
|
-
|
|
500
|
-
|
|
615
|
+
return new this({
|
|
616
|
+
le,
|
|
617
|
+
form: DdbForm.vector,
|
|
618
|
+
type,
|
|
619
|
+
length: i_block_start,
|
|
620
|
+
cols,
|
|
501
621
|
rows,
|
|
502
|
-
|
|
503
|
-
data: data
|
|
622
|
+
value: blocks
|
|
504
623
|
});
|
|
505
|
-
i_block_start = i_data_start + len_items;
|
|
506
|
-
i_row += rows;
|
|
507
624
|
}
|
|
508
|
-
return new this({
|
|
509
|
-
le,
|
|
510
|
-
form: DdbForm.vector,
|
|
511
|
-
type,
|
|
512
|
-
length: i_block_start,
|
|
513
|
-
cols,
|
|
514
|
-
rows,
|
|
515
|
-
value: blocks
|
|
516
|
-
});
|
|
517
625
|
}
|
|
518
626
|
/** 有可能没有字节对齐,不能直接使用原有 message 的 arraybuffer, 统一复制出来,让原有 arraybuffer 被回收掉比较好 */
|
|
519
627
|
static parse_vector_items(buf, le, type, length) {
|
|
@@ -685,8 +793,16 @@ export class DdbObj {
|
|
|
685
793
|
}
|
|
686
794
|
];
|
|
687
795
|
}
|
|
688
|
-
case DdbType.decimal128:
|
|
689
|
-
|
|
796
|
+
case DdbType.decimal128: {
|
|
797
|
+
const dv = new DataView(buf.buffer, buf.byteOffset);
|
|
798
|
+
return [
|
|
799
|
+
4 + 16 * length,
|
|
800
|
+
{
|
|
801
|
+
scale: dv.getInt32(0, le),
|
|
802
|
+
data: new BigInt128Array(buf.buffer.slice(buf.byteOffset + 4, buf.byteOffset + 4 + 16 * length))
|
|
803
|
+
}
|
|
804
|
+
];
|
|
805
|
+
}
|
|
690
806
|
// 以下情况时, DdbType.duration 实际会返回一个 any vector
|
|
691
807
|
// [2y, 1M, 3d, 7H, 11m, 12s, 15ms, 16us, 17ns]
|
|
692
808
|
// <Buffer 19 01 type = any, form = vector
|
|
@@ -710,16 +826,13 @@ export class DdbObj {
|
|
|
710
826
|
});
|
|
711
827
|
return [8 * length, durations];
|
|
712
828
|
}
|
|
713
|
-
case DdbType.
|
|
829
|
+
case DdbType.compressed:
|
|
714
830
|
return [
|
|
715
831
|
length,
|
|
716
832
|
new Uint8Array(buf.buffer.slice(buf.byteOffset, buf.byteOffset + length))
|
|
717
833
|
];
|
|
718
834
|
default:
|
|
719
|
-
throw new Error(t('{{form}}<{{type}}> 暂时不支持解析', {
|
|
720
|
-
form: 'vector',
|
|
721
|
-
type: String(DdbType[type] || type)
|
|
722
|
-
}));
|
|
835
|
+
throw new Error(t('{{form}}<{{type}}> 暂时不支持解析', { form: 'vector', type: get_type_name(type) }));
|
|
723
836
|
}
|
|
724
837
|
}
|
|
725
838
|
pack() {
|
|
@@ -831,8 +944,10 @@ export class DdbObj {
|
|
|
831
944
|
const { scale, data } = this.value;
|
|
832
945
|
return [Int32Array.of(scale), BigInt64Array.of(data === null ? nulls.int64 : data)];
|
|
833
946
|
}
|
|
834
|
-
case DdbType.decimal128:
|
|
835
|
-
|
|
947
|
+
case DdbType.decimal128: {
|
|
948
|
+
const { scale, data } = value;
|
|
949
|
+
return [Int32Array.of(scale), BigInt128Array.of(data === null ? nulls.int128 : data)];
|
|
950
|
+
}
|
|
836
951
|
default:
|
|
837
952
|
throw new Error(String(DdbType[type] || type) + t(' 暂时不支持序列化'));
|
|
838
953
|
}
|
|
@@ -899,7 +1014,7 @@ export class DdbObj {
|
|
|
899
1014
|
];
|
|
900
1015
|
}
|
|
901
1016
|
default:
|
|
902
|
-
throw new Error(t('vector {{type}} 暂不支持序列化', { type:
|
|
1017
|
+
throw new Error(t('vector {{type}} 暂不支持序列化', { type: get_type_name(type) }));
|
|
903
1018
|
}
|
|
904
1019
|
})();
|
|
905
1020
|
if (!body)
|
|
@@ -950,7 +1065,7 @@ export class DdbObj {
|
|
|
950
1065
|
case DdbType.uuid:
|
|
951
1066
|
case DdbType.ipaddr:
|
|
952
1067
|
case DdbType.int128:
|
|
953
|
-
case DdbType.
|
|
1068
|
+
case DdbType.compressed:
|
|
954
1069
|
return [value];
|
|
955
1070
|
case DdbType.blob: {
|
|
956
1071
|
let bufs = new Array(length * 2);
|
|
@@ -1004,20 +1119,61 @@ export class DdbObj {
|
|
|
1004
1119
|
return [Int32Array.of(scale), data];
|
|
1005
1120
|
}
|
|
1006
1121
|
default:
|
|
1007
|
-
throw new Error(t('vector {{type}} 暂不支持序列化', { type:
|
|
1122
|
+
throw new Error(t('vector {{type}} 暂不支持序列化', { type: get_type_name(type) }));
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
data() {
|
|
1126
|
+
const { form, type, value, le, rows, name } = this;
|
|
1127
|
+
switch (form) {
|
|
1128
|
+
case DdbForm.scalar:
|
|
1129
|
+
return convert(type, value, le);
|
|
1130
|
+
case DdbForm.vector:
|
|
1131
|
+
case DdbForm.pair:
|
|
1132
|
+
case DdbForm.set: {
|
|
1133
|
+
const data = converts(type, value, rows, le);
|
|
1134
|
+
return (form === DdbForm.set ? new Set(data) : data);
|
|
1135
|
+
}
|
|
1136
|
+
case DdbForm.table: {
|
|
1137
|
+
const cols = value;
|
|
1138
|
+
const jscols = cols.map(col => col.data());
|
|
1139
|
+
const keys = cols.map(({ name }) => name);
|
|
1140
|
+
return {
|
|
1141
|
+
name: name || '',
|
|
1142
|
+
columns: cols.map(({ name }) => name),
|
|
1143
|
+
types: cols.map(({ type }) => type),
|
|
1144
|
+
data: seq(rows, i => zip_object(keys, seq(cols.length, j => jscols[j][i])))
|
|
1145
|
+
};
|
|
1146
|
+
}
|
|
1147
|
+
case DdbForm.dict: {
|
|
1148
|
+
const [keys, values] = value;
|
|
1149
|
+
return zip_object(keys.data(), values.data());
|
|
1150
|
+
}
|
|
1151
|
+
case DdbForm.chart:
|
|
1152
|
+
return value;
|
|
1153
|
+
case DdbForm.matrix: {
|
|
1154
|
+
const ncolumns = this.cols;
|
|
1155
|
+
const { rows: _rows, cols: _cols, data } = value;
|
|
1156
|
+
const jsdata = converts(type, data, rows * ncolumns, le);
|
|
1157
|
+
return {
|
|
1158
|
+
type,
|
|
1159
|
+
nrows: rows,
|
|
1160
|
+
ncolumns,
|
|
1161
|
+
rows: _rows?.data(),
|
|
1162
|
+
columns: _cols?.data(),
|
|
1163
|
+
data: seq(rows, i => seq(ncolumns, j => jsdata[j * rows + i]))
|
|
1164
|
+
};
|
|
1165
|
+
}
|
|
1166
|
+
default:
|
|
1167
|
+
throw new Error(t('{{form}} {{type}} 暂不支持 data()', { form, type: get_type_name(type) }));
|
|
1008
1168
|
}
|
|
1009
1169
|
}
|
|
1010
1170
|
[inspect.custom](depth, _options, _inspect) {
|
|
1011
|
-
const options = { nullstr: true,
|
|
1171
|
+
const options = { nullstr: true, ..._options };
|
|
1012
1172
|
const type = this.inspect_type();
|
|
1013
1173
|
const data = (() => {
|
|
1014
1174
|
switch (this.form) {
|
|
1015
1175
|
case DdbForm.scalar:
|
|
1016
|
-
|
|
1017
|
-
if (this.type === DdbType.string)
|
|
1018
|
-
return this.value;
|
|
1019
|
-
else
|
|
1020
|
-
return format(this.type, this.value, this.le, options);
|
|
1176
|
+
return format(this.type, this.value, this.le, options);
|
|
1021
1177
|
case DdbForm.vector:
|
|
1022
1178
|
case DdbForm.pair:
|
|
1023
1179
|
case DdbForm.set: {
|
|
@@ -1131,7 +1287,7 @@ export class DdbObj {
|
|
|
1131
1287
|
return format_array(items, data.length > limit);
|
|
1132
1288
|
}
|
|
1133
1289
|
default: {
|
|
1134
|
-
const limit = this.type === DdbType.
|
|
1290
|
+
const limit = this.type === DdbType.compressed ? 5 : 50;
|
|
1135
1291
|
let items = new Array(Math.min(limit, this.value.length));
|
|
1136
1292
|
for (let i = 0; i < items.length; i++)
|
|
1137
1293
|
items[i] = format(this.type, this.value[i], this.le, options);
|
|
@@ -1195,7 +1351,8 @@ export class DdbObj {
|
|
|
1195
1351
|
static to_ddbobjs(values) {
|
|
1196
1352
|
return values.map(value => this.to_ddbobj(value));
|
|
1197
1353
|
}
|
|
1198
|
-
/** 将 table 转换为 rows,空值转换为 null
|
|
1354
|
+
/** 将 table 转换为 rows,空值转换为 null
|
|
1355
|
+
@deprecated 用 data() */
|
|
1199
1356
|
to_rows() {
|
|
1200
1357
|
assert(this.form === DdbForm.table, t('form 必须是 DdbForm.table, 否则不能 to_rows'));
|
|
1201
1358
|
let rows = new Array(this.rows);
|
|
@@ -1285,6 +1442,25 @@ export class DdbObj {
|
|
|
1285
1442
|
return obj;
|
|
1286
1443
|
}
|
|
1287
1444
|
}
|
|
1445
|
+
/** 根据 DdbType 获取其名称,array vector type 自动在后面加上 [] */
|
|
1446
|
+
export function get_type_name(type) {
|
|
1447
|
+
return `${DdbType[type] || type}${64 <= type && type < 128 ? '[]' : ''}`;
|
|
1448
|
+
}
|
|
1449
|
+
export function is_decimal_type(type) {
|
|
1450
|
+
return type === DdbType.decimal32 || type === DdbType.decimal64 || type === DdbType.decimal128;
|
|
1451
|
+
}
|
|
1452
|
+
export function is_decimal_null_value(type, value) {
|
|
1453
|
+
return ((value === nulls.int128 && type === DdbType.decimal128) ||
|
|
1454
|
+
(value === nulls.int64 && type === DdbType.decimal64) ||
|
|
1455
|
+
(value === nulls.int32 && type === DdbType.decimal32));
|
|
1456
|
+
}
|
|
1457
|
+
export function get_duration_unit(code) {
|
|
1458
|
+
let str = String.fromCharCode((code >> 24) & 0xff);
|
|
1459
|
+
str += String.fromCharCode((code >> 16) & 0xff);
|
|
1460
|
+
str += String.fromCharCode((code >> 8) & 0xff);
|
|
1461
|
+
str += String.fromCharCode(code & 0xff);
|
|
1462
|
+
return str;
|
|
1463
|
+
}
|
|
1288
1464
|
/** 整数一定用这个 number formatter, InspectOptions.decimals 不传也用这个 */
|
|
1289
1465
|
let default_formatter = new Intl.NumberFormat('en-US', { maximumFractionDigits: 20 });
|
|
1290
1466
|
let _decimals = 20;
|
|
@@ -1389,7 +1565,7 @@ export function format(type, value, le, options = {}) {
|
|
|
1389
1565
|
case DdbType.nanotimestamp:
|
|
1390
1566
|
return format_time(nanotimestamp2str, nulls.int64);
|
|
1391
1567
|
case DdbType.float:
|
|
1392
|
-
return
|
|
1568
|
+
return value === null || value === nulls.float32 ?
|
|
1393
1569
|
inspect(null, options)
|
|
1394
1570
|
:
|
|
1395
1571
|
options.colors ?
|
|
@@ -1397,7 +1573,7 @@ export function format(type, value, le, options = {}) {
|
|
|
1397
1573
|
:
|
|
1398
1574
|
formatter.format(value);
|
|
1399
1575
|
case DdbType.double:
|
|
1400
|
-
return
|
|
1576
|
+
return value === null || value === nulls.double ?
|
|
1401
1577
|
inspect(null, options)
|
|
1402
1578
|
:
|
|
1403
1579
|
options.colors ?
|
|
@@ -1406,6 +1582,10 @@ export function format(type, value, le, options = {}) {
|
|
|
1406
1582
|
formatter.format(value);
|
|
1407
1583
|
case DdbType.symbol:
|
|
1408
1584
|
case DdbType.string:
|
|
1585
|
+
case DdbType.handle:
|
|
1586
|
+
case DdbType.datasource:
|
|
1587
|
+
case DdbType.code:
|
|
1588
|
+
case DdbType.resource:
|
|
1409
1589
|
return inspect(value, options);
|
|
1410
1590
|
case DdbType.uuid:
|
|
1411
1591
|
return options.colors ?
|
|
@@ -1414,11 +1594,6 @@ export function format(type, value, le, options = {}) {
|
|
|
1414
1594
|
uuid2str(value, le);
|
|
1415
1595
|
case DdbType.functiondef:
|
|
1416
1596
|
return inspect(value.name, options);
|
|
1417
|
-
case DdbType.handle:
|
|
1418
|
-
case DdbType.datasource:
|
|
1419
|
-
case DdbType.code:
|
|
1420
|
-
case DdbType.resource:
|
|
1421
|
-
return inspect(value, options);
|
|
1422
1597
|
case DdbType.datehour:
|
|
1423
1598
|
return format_time(datehour2str, nulls.int32);
|
|
1424
1599
|
case DdbType.ipaddr:
|
|
@@ -1467,7 +1642,43 @@ export function format(type, value, le, options = {}) {
|
|
|
1467
1642
|
/** 格式化向量、集合中的第 index 项为字符串,空值返回 'null' 字符串 formatted vector, the index-th item in the collection is a string, a null value returns a 'null' string */
|
|
1468
1643
|
export function formati(obj, index, options = {}) {
|
|
1469
1644
|
assert(index < obj.rows, 'index < obj.rows');
|
|
1470
|
-
if (
|
|
1645
|
+
if (obj.type < 64 || obj.type >= 128) // 普通数组
|
|
1646
|
+
switch (obj.type) {
|
|
1647
|
+
case DdbType.symbol_extended: {
|
|
1648
|
+
const { base, data } = obj.value;
|
|
1649
|
+
return format(DdbType.string, base[data[index]], obj.le, options);
|
|
1650
|
+
}
|
|
1651
|
+
case DdbType.void:
|
|
1652
|
+
return format(obj.type, obj.value, obj.le, options);
|
|
1653
|
+
case DdbType.uuid:
|
|
1654
|
+
case DdbType.int128:
|
|
1655
|
+
case DdbType.ipaddr:
|
|
1656
|
+
return format(obj.type, obj.value.subarray(16 * index, 16 * (index + 1)), obj.le, options);
|
|
1657
|
+
case DdbType.blob: {
|
|
1658
|
+
const value = obj.value[index];
|
|
1659
|
+
return value.length > 100 ?
|
|
1660
|
+
DdbObj.dec.decode(value.subarray(0, 98)) + '…'
|
|
1661
|
+
:
|
|
1662
|
+
DdbObj.dec.decode(value);
|
|
1663
|
+
}
|
|
1664
|
+
case DdbType.complex:
|
|
1665
|
+
case DdbType.point:
|
|
1666
|
+
return format(obj.type, obj.value.subarray(2 * index, 2 * (index + 1)), obj.le, options);
|
|
1667
|
+
case DdbType.decimal32:
|
|
1668
|
+
case DdbType.decimal64:
|
|
1669
|
+
case DdbType.decimal128: {
|
|
1670
|
+
const { scale, data } = obj.value;
|
|
1671
|
+
const x = data[index];
|
|
1672
|
+
if (is_decimal_null_value(obj.type, x))
|
|
1673
|
+
return '';
|
|
1674
|
+
const s = String(x < 0 ? -x : x).padStart(scale, '0');
|
|
1675
|
+
const str = (x < 0 ? '-' : '') + (scale ? `${s.slice(0, -scale) || '0'}.${s.slice(-scale)}` : s);
|
|
1676
|
+
return options.colors ? str.green : str;
|
|
1677
|
+
}
|
|
1678
|
+
default:
|
|
1679
|
+
return format(obj.type, obj.value[index], obj.le, options);
|
|
1680
|
+
}
|
|
1681
|
+
else { // array vector
|
|
1471
1682
|
// 因为 array vector 目前只支持:Logical, Integral(不包括 INT128, COMPRESS 类型), Floating, Temporal
|
|
1472
1683
|
// 都对应 TypedArray 中的一格,所以 lengths.length 等于 block 中的 row 的个数
|
|
1473
1684
|
// av = array(INT[], 0, 5)
|
|
@@ -1530,40 +1741,155 @@ export function formati(obj, index, options = {}) {
|
|
|
1530
1741
|
}
|
|
1531
1742
|
}
|
|
1532
1743
|
}
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
return format(DdbType.string, base[data[index]], obj.le, options);
|
|
1537
|
-
}
|
|
1744
|
+
}
|
|
1745
|
+
export function convert(type, value, le) {
|
|
1746
|
+
switch (type) {
|
|
1538
1747
|
case DdbType.void:
|
|
1539
|
-
return
|
|
1748
|
+
return value === DdbVoidType.null ? null : undefined;
|
|
1749
|
+
case DdbType.char:
|
|
1750
|
+
return value === null || value === nulls.int8 ? '' : String.fromCharCode(value);
|
|
1751
|
+
case DdbType.bool:
|
|
1752
|
+
return value === null || value === nulls.int8 ? null : Boolean(value);
|
|
1753
|
+
case DdbType.short:
|
|
1754
|
+
return value === null || value === nulls.int16 ? null : value;
|
|
1755
|
+
case DdbType.int:
|
|
1756
|
+
return value === null || value === nulls.int32 ? null : value;
|
|
1757
|
+
case DdbType.float:
|
|
1758
|
+
return value === null || value === nulls.float32 ? null : value;
|
|
1759
|
+
case DdbType.double:
|
|
1760
|
+
return value === null || value === nulls.double ? null : value;
|
|
1761
|
+
case DdbType.long:
|
|
1762
|
+
return value === null || value === nulls.int64 ? null : value;
|
|
1763
|
+
case DdbType.functiondef:
|
|
1764
|
+
return value.name;
|
|
1765
|
+
case DdbType.string:
|
|
1766
|
+
case DdbType.symbol:
|
|
1767
|
+
case DdbType.code:
|
|
1768
|
+
case DdbType.handle:
|
|
1769
|
+
case DdbType.datasource:
|
|
1770
|
+
case DdbType.resource:
|
|
1771
|
+
case DdbType.blob:
|
|
1772
|
+
return value;
|
|
1773
|
+
case DdbType.complex:
|
|
1774
|
+
case DdbType.point: {
|
|
1775
|
+
const [x, y] = value;
|
|
1776
|
+
return [
|
|
1777
|
+
x === null || x === nulls.double ? null : x,
|
|
1778
|
+
y === null || y === nulls.double ? null : y,
|
|
1779
|
+
];
|
|
1780
|
+
}
|
|
1781
|
+
case DdbType.date:
|
|
1782
|
+
case DdbType.month:
|
|
1783
|
+
case DdbType.time:
|
|
1784
|
+
case DdbType.minute:
|
|
1785
|
+
case DdbType.second:
|
|
1786
|
+
case DdbType.datetime:
|
|
1787
|
+
case DdbType.datehour:
|
|
1788
|
+
case DdbType.timestamp:
|
|
1789
|
+
case DdbType.nanotime:
|
|
1790
|
+
case DdbType.nanotimestamp:
|
|
1791
|
+
case DdbType.duration:
|
|
1540
1792
|
case DdbType.uuid:
|
|
1541
|
-
case DdbType.int128:
|
|
1542
1793
|
case DdbType.ipaddr:
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
const value = obj.value[index];
|
|
1546
|
-
return value.length > 100 ?
|
|
1547
|
-
DdbObj.dec.decode(value.subarray(0, 98)) + '…'
|
|
1548
|
-
:
|
|
1549
|
-
DdbObj.dec.decode(value);
|
|
1550
|
-
}
|
|
1551
|
-
case DdbType.complex:
|
|
1552
|
-
case DdbType.point:
|
|
1553
|
-
return format(obj.type, obj.value.subarray(2 * index, 2 * (index + 1)), obj.le, options);
|
|
1794
|
+
case DdbType.int128:
|
|
1795
|
+
// decimal 类型转换为固定位数小数的 string 不丢失精度,一般也是展示用
|
|
1554
1796
|
case DdbType.decimal32:
|
|
1555
1797
|
case DdbType.decimal64:
|
|
1556
|
-
case DdbType.decimal128:
|
|
1557
|
-
|
|
1558
|
-
const x = data[index];
|
|
1559
|
-
if (is_decimal_null_value(obj.type, x))
|
|
1560
|
-
return '';
|
|
1561
|
-
const s = String(x < 0 ? -x : x).padStart(scale, '0');
|
|
1562
|
-
const str = (x < 0 ? '-' : '') + (scale ? `${s.slice(0, -scale) || '0'}.${s.slice(-scale)}` : s);
|
|
1563
|
-
return options.colors ? str.green : str;
|
|
1564
|
-
}
|
|
1798
|
+
case DdbType.decimal128:
|
|
1799
|
+
return format(type, value, le, { colors: false });
|
|
1565
1800
|
default:
|
|
1566
|
-
|
|
1801
|
+
throw new Error(String(DdbType[type] || type) + t(' 暂时不支持转换为 js 对象'));
|
|
1802
|
+
}
|
|
1803
|
+
}
|
|
1804
|
+
/** 转换一个向量到 js 原生数组 */
|
|
1805
|
+
export function converts(type, value, rows, le) {
|
|
1806
|
+
if (type < 64 || type >= 128)
|
|
1807
|
+
switch (type) {
|
|
1808
|
+
// 可以直接用下标取值再转换的类型
|
|
1809
|
+
case DdbType.bool:
|
|
1810
|
+
case DdbType.char:
|
|
1811
|
+
case DdbType.short:
|
|
1812
|
+
case DdbType.int:
|
|
1813
|
+
case DdbType.float:
|
|
1814
|
+
case DdbType.double:
|
|
1815
|
+
case DdbType.long:
|
|
1816
|
+
case DdbType.date:
|
|
1817
|
+
case DdbType.month:
|
|
1818
|
+
case DdbType.time:
|
|
1819
|
+
case DdbType.minute:
|
|
1820
|
+
case DdbType.second:
|
|
1821
|
+
case DdbType.datetime:
|
|
1822
|
+
case DdbType.datehour:
|
|
1823
|
+
case DdbType.timestamp:
|
|
1824
|
+
case DdbType.nanotime:
|
|
1825
|
+
case DdbType.nanotimestamp:
|
|
1826
|
+
case DdbType.duration:
|
|
1827
|
+
case DdbType.string:
|
|
1828
|
+
case DdbType.symbol:
|
|
1829
|
+
case DdbType.code:
|
|
1830
|
+
case DdbType.handle:
|
|
1831
|
+
case DdbType.datasource:
|
|
1832
|
+
case DdbType.resource:
|
|
1833
|
+
case DdbType.functiondef:
|
|
1834
|
+
case DdbType.blob:
|
|
1835
|
+
return Array.prototype.map.call(value, (x) => convert(type, x, le));
|
|
1836
|
+
case DdbType.void:
|
|
1837
|
+
return [];
|
|
1838
|
+
case DdbType.symbol_extended: {
|
|
1839
|
+
const { base, data } = value;
|
|
1840
|
+
return Array.prototype.map.call(data, (x) => base[x]);
|
|
1841
|
+
}
|
|
1842
|
+
case DdbType.complex:
|
|
1843
|
+
case DdbType.point:
|
|
1844
|
+
return seq(rows, i => [value[2 * i], value[2 * (i + 1)]]);
|
|
1845
|
+
case DdbType.uuid:
|
|
1846
|
+
case DdbType.ipaddr:
|
|
1847
|
+
case DdbType.int128:
|
|
1848
|
+
return seq(rows, i => convert(type, value.subarray(16 * i, 16 * (i + 1)), le));
|
|
1849
|
+
case DdbType.decimal32:
|
|
1850
|
+
case DdbType.decimal64:
|
|
1851
|
+
case DdbType.decimal128: {
|
|
1852
|
+
const { scale, data } = value;
|
|
1853
|
+
// todo: 用 Array.prototype.map.call 时对 BigInt128Array 这个代理对象无效?为什么只能通过下标访问?
|
|
1854
|
+
return seq(rows, i => {
|
|
1855
|
+
const x = data[i];
|
|
1856
|
+
if (is_decimal_null_value(type, x))
|
|
1857
|
+
return '';
|
|
1858
|
+
const s = String(x < 0 ? -x : x).padStart(scale, '0');
|
|
1859
|
+
return (x < 0 ? '-' : '') + (scale ? `${s.slice(0, -scale) || '0'}.${s.slice(-scale)}` : s);
|
|
1860
|
+
});
|
|
1861
|
+
}
|
|
1862
|
+
case DdbType.any:
|
|
1863
|
+
return value.map(x => x.data());
|
|
1864
|
+
default:
|
|
1865
|
+
throw new Error(String(DdbType[type] || type) + '[]' + t(' 暂时不支持转换为 js 对象'));
|
|
1866
|
+
}
|
|
1867
|
+
else { // array vector
|
|
1868
|
+
const type_ = type - 64;
|
|
1869
|
+
return value.map(({ lengths, data, rows }) => {
|
|
1870
|
+
let acc_len = 0;
|
|
1871
|
+
return Array.prototype.map.call(lengths, (length) => {
|
|
1872
|
+
const result = (() => {
|
|
1873
|
+
switch (type_) {
|
|
1874
|
+
case DdbType.decimal32:
|
|
1875
|
+
case DdbType.decimal64:
|
|
1876
|
+
case DdbType.decimal128:
|
|
1877
|
+
return converts(type_, { scale: value.scale, data: data.subarray(acc_len, acc_len + length) }, length, le);
|
|
1878
|
+
case DdbType.complex:
|
|
1879
|
+
case DdbType.point:
|
|
1880
|
+
return converts(type_, data.subarray(acc_len, acc_len + 2 * length), length, le);
|
|
1881
|
+
case DdbType.uuid:
|
|
1882
|
+
case DdbType.int128:
|
|
1883
|
+
case DdbType.ipaddr:
|
|
1884
|
+
return converts(type_, data.subarray(acc_len, acc_len + 16 * length), length, le);
|
|
1885
|
+
default:
|
|
1886
|
+
return converts(type_, data.subarray(acc_len, acc_len + length), length, le);
|
|
1887
|
+
}
|
|
1888
|
+
})();
|
|
1889
|
+
acc_len += length;
|
|
1890
|
+
return result;
|
|
1891
|
+
});
|
|
1892
|
+
}).flat();
|
|
1567
1893
|
}
|
|
1568
1894
|
}
|
|
1569
1895
|
export class DdbVoid extends DdbObj {
|
|
@@ -2186,7 +2512,6 @@ export class DDB {
|
|
|
2186
2512
|
print_object_buffer = false;
|
|
2187
2513
|
print_message = true;
|
|
2188
2514
|
parse_object = true;
|
|
2189
|
-
pnode_run_defined = false;
|
|
2190
2515
|
/** 在 websocket 收到的第一个 error 时,
|
|
2191
2516
|
在 connect_websocket 的 on_error 回调中构造 DdbConnectionError 并保存到 DDB 对象上,
|
|
2192
2517
|
这个 error 的错误信息最准确 */
|
|
@@ -2197,6 +2522,8 @@ export class DDB {
|
|
|
2197
2522
|
pconnect;
|
|
2198
2523
|
/** 首次定义 pnode_run 的 promise,保证并发调用 rpc 时只定义一次 pnode_run */
|
|
2199
2524
|
ppnode_run;
|
|
2525
|
+
/** 首次定义 invoke 的 promise,保证并发调用 rpc 时只定义一次 invoke */
|
|
2526
|
+
pinvoke;
|
|
2200
2527
|
get connected() {
|
|
2201
2528
|
return !this.error && this.lwebsocket.resource?.readyState === WebSocketOpen;
|
|
2202
2529
|
}
|
|
@@ -2529,8 +2856,7 @@ export class DDB {
|
|
|
2529
2856
|
不做解析,以便后续转发、序列化
|
|
2530
2857
|
Set parse_object during this rpc, and restore the original after the end.
|
|
2531
2858
|
When it is false, the returned DdbObj only contains buffer and le without parsing,
|
|
2532
|
-
so as to facilitate subsequent forwarding and serialization
|
|
2533
|
-
*/
|
|
2859
|
+
so as to facilitate subsequent forwarding and serialization */
|
|
2534
2860
|
async eval(script, { urgent, listener, parse_object, } = {}) {
|
|
2535
2861
|
return this.rpc('script', { script, urgent, listener, parse_object });
|
|
2536
2862
|
}
|
|
@@ -2595,6 +2921,45 @@ export class DDB {
|
|
|
2595
2921
|
on_more_messages
|
|
2596
2922
|
});
|
|
2597
2923
|
}
|
|
2924
|
+
/** 调用 dolphindb 函数,传入 js 原生数组作为参数,返回 js 原生对象或值(调用 DdbObj.data() 后的结果)
|
|
2925
|
+
- func: 函数名
|
|
2926
|
+
- args?: `[ ]` 调用参数,可以是 js 原生数组
|
|
2927
|
+
- options?: 调用选项
|
|
2928
|
+
- urgent?: 紧急 flag。使用 urgent worker 执行,防止被其它作业阻塞
|
|
2929
|
+
- node?: 设置结点 alias 时发送到集群中对应的结点执行 (使用 DolphinDB 中的 rpc 方法)
|
|
2930
|
+
- nodes?: 设置多个结点 alias 时发送到集群中对应的多个结点执行 (使用 DolphinDB 中的 pnodeRun 方法)
|
|
2931
|
+
- func_type?: 设置 node 参数且参数数组为空时必传,需指定函数类型,其它情况下不传
|
|
2932
|
+
- add_node_alias?: 设置 nodes 参数时选传,其它情况不传
|
|
2933
|
+
- listener?: 处理本次 rpc 期间的消息 (DdbMessage) */
|
|
2934
|
+
async invoke(func, args, options) {
|
|
2935
|
+
await (this.pinvoke ??= this.eval(this.python ?
|
|
2936
|
+
'\n' +
|
|
2937
|
+
'def invoke (func_name, args_json):\n' +
|
|
2938
|
+
' args = fromStdJson(args_json)\n' +
|
|
2939
|
+
' if type(args) != ANY:\n' +
|
|
2940
|
+
' args = cast(args, ANY)\n' +
|
|
2941
|
+
' return unifiedCall(funcByName(func_name), args)\n'
|
|
2942
|
+
:
|
|
2943
|
+
'\n' +
|
|
2944
|
+
'def invoke (func_name, args_json) {\n' +
|
|
2945
|
+
' args = fromStdJson(args_json)\n' +
|
|
2946
|
+
' if (type(args) != ANY)\n' +
|
|
2947
|
+
' args = cast(args, ANY)\n' +
|
|
2948
|
+
' return unifiedCall(funcByName(func_name), args)\n' +
|
|
2949
|
+
'}\n', { urgent: true }));
|
|
2950
|
+
if (options?.node)
|
|
2951
|
+
options.func_type = DdbFunctionType.UserDefinedFunc;
|
|
2952
|
+
return (await this.call(args?.length ? 'invoke' : func, args?.length ? [func, JSON.stringify(args)] : undefined, options)).data();
|
|
2953
|
+
}
|
|
2954
|
+
/** 执行 dolphindb 脚本,返回 js 原生对象或值(调用 DdbObj.data() 后的结果)
|
|
2955
|
+
- script?: 执行的脚本
|
|
2956
|
+
- options?: 执行选项
|
|
2957
|
+
- urgent?: 紧急 flag,确保提交的脚本使用 urgent worker 处理,防止被其它作业阻塞
|
|
2958
|
+
- listener?: 处理本次 rpc 期间的消息 (DdbMessage) */
|
|
2959
|
+
async execute(script, options) {
|
|
2960
|
+
return (await this.eval(script, options))
|
|
2961
|
+
.data();
|
|
2962
|
+
}
|
|
2598
2963
|
/** upload variable through websocket (variable command) */
|
|
2599
2964
|
async upload(
|
|
2600
2965
|
/** 上传的变量名 Uploaded variables' name */
|
|
@@ -2744,4 +3109,195 @@ export class DDB {
|
|
|
2744
3109
|
colnames);
|
|
2745
3110
|
}
|
|
2746
3111
|
}
|
|
3112
|
+
export class BigInt128Array {
|
|
3113
|
+
static of(...items) {
|
|
3114
|
+
return new BigInt128Array(items);
|
|
3115
|
+
}
|
|
3116
|
+
static from(arrayLike, mapfn, thisArg) {
|
|
3117
|
+
if (mapfn) {
|
|
3118
|
+
const array = [];
|
|
3119
|
+
for (let i = 0; i < arrayLike.length; i++)
|
|
3120
|
+
array.push(mapfn.call(thisArg, arrayLike[i], i));
|
|
3121
|
+
return new BigInt128Array(array);
|
|
3122
|
+
}
|
|
3123
|
+
else {
|
|
3124
|
+
const v = new BigInt128Array(arrayLike.length);
|
|
3125
|
+
v.set(arrayLike);
|
|
3126
|
+
}
|
|
3127
|
+
}
|
|
3128
|
+
BYTES_PER_ELEMENT = 16;
|
|
3129
|
+
buffer;
|
|
3130
|
+
byteLength;
|
|
3131
|
+
byteOffset;
|
|
3132
|
+
constructor(fisrtArg, byteOffset, length) {
|
|
3133
|
+
if (typeof fisrtArg === 'number') {
|
|
3134
|
+
const length = fisrtArg;
|
|
3135
|
+
this.buffer = new ArrayBuffer(length * this.BYTES_PER_ELEMENT);
|
|
3136
|
+
this.byteOffset = 0;
|
|
3137
|
+
this.byteLength = length * this.BYTES_PER_ELEMENT;
|
|
3138
|
+
}
|
|
3139
|
+
else if (fisrtArg instanceof ArrayBuffer || fisrtArg instanceof SharedArrayBuffer) {
|
|
3140
|
+
this.buffer = fisrtArg;
|
|
3141
|
+
this.byteOffset = byteOffset ?? 0;
|
|
3142
|
+
let byteLength = 0;
|
|
3143
|
+
if (length !== undefined) {
|
|
3144
|
+
byteLength = length * this.BYTES_PER_ELEMENT;
|
|
3145
|
+
if (byteLength + this.byteOffset > fisrtArg.byteLength)
|
|
3146
|
+
throw new RangeError(`valid typed array length: ${length}`);
|
|
3147
|
+
}
|
|
3148
|
+
else {
|
|
3149
|
+
byteLength = fisrtArg.byteLength - this.byteOffset;
|
|
3150
|
+
if (byteLength % this.BYTES_PER_ELEMENT !== 0)
|
|
3151
|
+
throw new RangeError('byte length of BigInt128Array should be a multiple of 16');
|
|
3152
|
+
}
|
|
3153
|
+
this.byteLength = byteLength;
|
|
3154
|
+
}
|
|
3155
|
+
else {
|
|
3156
|
+
const array = [];
|
|
3157
|
+
for (const value of fisrtArg)
|
|
3158
|
+
array.push(value);
|
|
3159
|
+
this.buffer = new ArrayBuffer(array.length * this.BYTES_PER_ELEMENT);
|
|
3160
|
+
this.byteOffset = 0;
|
|
3161
|
+
this.byteLength = array.length * this.BYTES_PER_ELEMENT;
|
|
3162
|
+
this.set(array);
|
|
3163
|
+
}
|
|
3164
|
+
return new Proxy(this, {
|
|
3165
|
+
get(target, key) {
|
|
3166
|
+
if (typeof key === 'string') {
|
|
3167
|
+
const index = Number(key);
|
|
3168
|
+
// only positive integer index is allowed
|
|
3169
|
+
if (Number.isInteger(index) && index >= 0 && index < target.length)
|
|
3170
|
+
return target.at(index);
|
|
3171
|
+
}
|
|
3172
|
+
return Reflect.get(target, key);
|
|
3173
|
+
},
|
|
3174
|
+
set(target, key, value) {
|
|
3175
|
+
if (typeof key === 'string') {
|
|
3176
|
+
const index = Number(key);
|
|
3177
|
+
if (Number.isInteger(index) && index >= 0 && index < target.length)
|
|
3178
|
+
target.set([value], index);
|
|
3179
|
+
// ignore invalid number index setter, and never set value to target
|
|
3180
|
+
return true;
|
|
3181
|
+
}
|
|
3182
|
+
return Reflect.set(target, key, value);
|
|
3183
|
+
}
|
|
3184
|
+
});
|
|
3185
|
+
}
|
|
3186
|
+
get length() {
|
|
3187
|
+
return this.byteLength / this.BYTES_PER_ELEMENT;
|
|
3188
|
+
}
|
|
3189
|
+
set(array, offset = 0) {
|
|
3190
|
+
if (offset + array.length > this.length)
|
|
3191
|
+
throw new RangeError('offset is out of bounds');
|
|
3192
|
+
const dv = new DataView(this.buffer);
|
|
3193
|
+
for (let i = 0; i < array.length; i++) {
|
|
3194
|
+
const byteOffset = this.byteOffset + (offset + i) * this.BYTES_PER_ELEMENT;
|
|
3195
|
+
set_big_int_128(dv, byteOffset, array[i]);
|
|
3196
|
+
}
|
|
3197
|
+
}
|
|
3198
|
+
at(index) {
|
|
3199
|
+
const length = this.length;
|
|
3200
|
+
if (index < 0)
|
|
3201
|
+
index += length;
|
|
3202
|
+
if (index >= length || index < 0)
|
|
3203
|
+
return undefined;
|
|
3204
|
+
const dv = new DataView(this.buffer);
|
|
3205
|
+
return get_big_int_128(dv, this.byteOffset + index * this.BYTES_PER_ELEMENT);
|
|
3206
|
+
}
|
|
3207
|
+
subarray(begin = 0, end = this.length) {
|
|
3208
|
+
const length = this.length;
|
|
3209
|
+
// subarray arguments should be the same behavior as other TypedArray
|
|
3210
|
+
// https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/subarray#%E8%AF%B4%E6%98%8E
|
|
3211
|
+
if (begin < 0)
|
|
3212
|
+
begin += length;
|
|
3213
|
+
if (end < 0)
|
|
3214
|
+
end += length;
|
|
3215
|
+
if (begin < 0)
|
|
3216
|
+
begin = 0;
|
|
3217
|
+
else if (begin > length)
|
|
3218
|
+
begin = length;
|
|
3219
|
+
if (end < 0)
|
|
3220
|
+
end = 0;
|
|
3221
|
+
else if (end > length)
|
|
3222
|
+
end = length;
|
|
3223
|
+
const newLength = Math.max(end - begin, 0);
|
|
3224
|
+
return new BigInt128Array(this.buffer, this.byteOffset + begin * this.BYTES_PER_ELEMENT, newLength);
|
|
3225
|
+
}
|
|
3226
|
+
[Symbol.iterator]() {
|
|
3227
|
+
let index = 0;
|
|
3228
|
+
const array = this;
|
|
3229
|
+
return {
|
|
3230
|
+
next() {
|
|
3231
|
+
if (index < array.length)
|
|
3232
|
+
return { value: array.at(index++), done: false };
|
|
3233
|
+
else
|
|
3234
|
+
return { done: true };
|
|
3235
|
+
},
|
|
3236
|
+
};
|
|
3237
|
+
}
|
|
3238
|
+
toString() {
|
|
3239
|
+
const values = [];
|
|
3240
|
+
for (const value of this)
|
|
3241
|
+
values.push(value);
|
|
3242
|
+
return values.join(',');
|
|
3243
|
+
}
|
|
3244
|
+
// Simulate other TypedArray behavior in nodejs
|
|
3245
|
+
[inspect.custom]() {
|
|
3246
|
+
const values = [];
|
|
3247
|
+
for (const value of this)
|
|
3248
|
+
values.push(value);
|
|
3249
|
+
const value_str = values.length ? ` ${values.map(v => String(v) + 'n').join(', ')} ` : '';
|
|
3250
|
+
return `${this[Symbol.toStringTag]}(${this.length}) [${value_str}]`;
|
|
3251
|
+
}
|
|
3252
|
+
}
|
|
3253
|
+
Object.defineProperty(BigInt128Array.prototype, Symbol.toStringTag, {
|
|
3254
|
+
configurable: false,
|
|
3255
|
+
writable: false,
|
|
3256
|
+
enumerable: false,
|
|
3257
|
+
value: 'BigInt128Array',
|
|
3258
|
+
});
|
|
3259
|
+
// DataView Extends for bigint 128 operations
|
|
3260
|
+
function get_big_uint_128(dataview, byte_offset, le = true) {
|
|
3261
|
+
let cursor = byte_offset + (le ? 15 : 0);
|
|
3262
|
+
const end = byte_offset + (le ? -1 : 16);
|
|
3263
|
+
const step = le ? -1 : 1;
|
|
3264
|
+
let value = 0n;
|
|
3265
|
+
while (cursor !== end) {
|
|
3266
|
+
value = value << 8n | BigInt(dataview.getUint8(cursor));
|
|
3267
|
+
cursor += step;
|
|
3268
|
+
}
|
|
3269
|
+
return value;
|
|
3270
|
+
}
|
|
3271
|
+
function get_big_int_128(dataview, byte_offset, le = true) {
|
|
3272
|
+
return BigInt.asIntN(128, get_big_uint_128(dataview, byte_offset, le));
|
|
3273
|
+
}
|
|
3274
|
+
function set_big_uint_128(dataView, byte_offset, value, le = true) {
|
|
3275
|
+
let cursor = byte_offset + (le ? 0 : 15);
|
|
3276
|
+
const end = byte_offset + (le ? 16 : -1);
|
|
3277
|
+
const step = le ? 1 : -1;
|
|
3278
|
+
while (cursor !== end) {
|
|
3279
|
+
dataView.setUint8(cursor, Number(value & 0xffn));
|
|
3280
|
+
value = value >> 8n;
|
|
3281
|
+
cursor += step;
|
|
3282
|
+
}
|
|
3283
|
+
}
|
|
3284
|
+
function set_big_int_128(dataview, byte_offset, value, le = true) {
|
|
3285
|
+
set_big_uint_128(dataview, byte_offset, value, le);
|
|
3286
|
+
}
|
|
3287
|
+
// 大端
|
|
3288
|
+
// const dataBE = new ArrayBuffer(16)
|
|
3289
|
+
// const dataViewBE = new DataView(dataBE)
|
|
3290
|
+
// set_big_int_128(dataViewBE, 0, -34355n, false)
|
|
3291
|
+
// console.log(dataViewBE.buffer)
|
|
3292
|
+
// const bigInt128BE = get_big_int_128(dataViewBE, 0, false)
|
|
3293
|
+
// const bigUint128BE = get_big_uint_128(dataViewBE, 0, false)
|
|
3294
|
+
// console.log(bigInt128BE.toString(), bigUint128BE.toString())
|
|
3295
|
+
// 小端
|
|
3296
|
+
// const dataLE = new ArrayBuffer(16)
|
|
3297
|
+
// const dataViewLE = new DataView(dataLE)
|
|
3298
|
+
// set_big_int_128(dataViewLE, 0, -34355n, true)
|
|
3299
|
+
// console.log(dataViewLE.buffer)
|
|
3300
|
+
// const bigInt128LE = get_big_int_128(dataViewLE, 0, true)
|
|
3301
|
+
// const bigUint128LE = get_big_uint_128(dataViewLE, 0, true)
|
|
3302
|
+
// console.log(bigInt128LE.toString(), bigUint128LE.toString())
|
|
2747
3303
|
//# sourceMappingURL=index.js.map
|