dolphindb 0.0.13 → 2.0.500

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 CHANGED
@@ -220,6 +220,15 @@ const obj = new DdbObj({
220
220
  })
221
221
  ```
222
222
 
223
+ ##### NULL object in the form of scalar, the value corresponding to DdbObj is null in JavaScript
224
+ ```ts
225
+ ;(await ddb.eval('double()')).value === null
226
+
227
+ // create NULL object
228
+ new DdbInt(null)
229
+ new DdbDouble(null)
230
+ ```
231
+
223
232
 
224
233
  #### `call` Method Declaration
225
234
  ```ts
@@ -321,18 +330,28 @@ async upload (
321
330
  ```
322
331
 
323
332
 
324
- ### Notes
333
+ ### Others
325
334
  ```ts
326
- import { nulls, DdbInt, timestamp2str } from 'dolphindb'
335
+ import { nulls, DdbInt, timestamp2str, DdbVectorSymbol } from 'dolphindb'
327
336
 
328
- // create DolphinDB null integer value (the smallest 32-bit integer)
329
- new DdbInt(nulls.int32)
330
-
331
- // convert DolphinDB timestamp value to string
337
+ // Format timestamp in DolphinDB as string
332
338
  timestamp2str(
333
339
  (
334
340
  await ddb.call<DdbObj<bigint>>('now', [false])
335
341
  ).value
336
342
  ) === '2022.02.23 17:23:13.494'
343
+
344
+ // create symbol vector
345
+ new DdbVectorSymbol(['aaa', 'aaa', 'aaa', 'aaa', 'aaa', 'bbb'])
346
+
347
+ // Create a double vector with NULL values using JavaScript native arrays
348
+ new DdbVectorDouble([0.1, null, 0.3])
349
+
350
+ // More efficient and memory efficient double vector creation using JavaScript TypedArray
351
+ let av = new Float64Array(3)
352
+ av[0] = 0.1
353
+ av[1] = nulls.double
354
+ av[2] = 0.3
355
+ new DdbVectorDouble(av)
337
356
  ```
338
357
 
package/README.zh.md CHANGED
@@ -221,6 +221,15 @@ const obj = new DdbObj({
221
221
  })
222
222
  ```
223
223
 
224
+ ##### scalar 形式的 NULL 对象, 对应 DdbObj 的 value 为 JavaScript 中的 null
225
+ ```ts
226
+ ;(await ddb.eval('double()')).value === null
227
+
228
+ // 创建 NULL 对象
229
+ new DdbInt(null)
230
+ new DdbDouble(null)
231
+ ```
232
+
224
233
 
225
234
  #### `call` 方法声明
226
235
  ```ts
@@ -322,12 +331,9 @@ async upload (
322
331
  ```
323
332
 
324
333
 
325
- ### Notes
334
+ ### 其它
326
335
  ```ts
327
- import { nulls, DdbInt, timestamp2str } from 'dolphindb'
328
-
329
- // 创建 DolphinDB 空值 (最小的 32-bit 整数)
330
- new DdbInt(nulls.int32)
336
+ import { nulls, DdbInt, timestamp2str, DdbVectorSymbol } from 'dolphindb'
331
337
 
332
338
  // 将 DolphinDB 中的 timestamp 格式化为 string
333
339
  timestamp2str(
@@ -335,4 +341,17 @@ timestamp2str(
335
341
  await ddb.call<DdbObj<bigint>>('now', [false])
336
342
  ).value
337
343
  ) === '2022.02.23 17:23:13.494'
344
+
345
+ // 创建 symbol vector
346
+ new DdbVectorSymbol(['aaa', 'aaa', 'aaa', 'aaa', 'aaa', 'bbb'])
347
+
348
+ // 使用 JavaScript 原生数组创建含有 NULL 值的 double vector
349
+ new DdbVectorDouble([0.1, null, 0.3])
350
+
351
+ // 使用 JavaScript TypedArray 更加高效且节约内存的创建 double vector
352
+ let av = new Float64Array(3)
353
+ av[0] = 0.1
354
+ av[1] = nulls.double
355
+ av[2] = 0.3
356
+ new DdbVectorDouble(av)
338
357
  ```
package/browser.d.ts CHANGED
@@ -78,10 +78,15 @@ export interface DdbArrayVectorBlock {
78
78
  export declare type DdbValue = null | boolean | number | [number, number] | bigint | string | string[] | Uint8Array | Int16Array | Int32Array | Float32Array | Float64Array | BigInt64Array | Uint8Array[] | DdbObj[] | DdbFunctionDefValue | DdbSymbolExtendedValue | DdbArrayVectorBlock[];
79
79
  export declare type DdbVectorValue = string | string[] | Uint8Array | Int16Array | Int32Array | Float32Array | Float64Array | BigInt64Array | Uint8Array[] | DdbObj[] | DdbSymbolExtendedValue | DdbArrayVectorBlock[];
80
80
  export declare const nulls: {
81
+ readonly bool: 128;
81
82
  readonly char: "€";
82
83
  readonly int16: -32768;
83
84
  readonly int32: -2147483648;
84
85
  readonly int64: -9223372036854775808n;
86
+ readonly float32: -3.4028234663852886e+38;
87
+ /** -Number.MAX_VALUE */
88
+ readonly double: number;
89
+ readonly bytes16: Uint8Array;
85
90
  };
86
91
  export declare const timezone_offset: number;
87
92
  /** 可以表示所有 DolphinDB 数据库中的数据类型 */
@@ -149,57 +154,82 @@ export declare class DdbVoid extends DdbObj<undefined> {
149
154
  constructor();
150
155
  }
151
156
  export declare class DdbBool extends DdbObj<boolean> {
152
- constructor(value: boolean);
157
+ constructor(value: boolean | null);
153
158
  }
154
159
  export declare class DdbChar extends DdbObj<string> {
155
- constructor(value: string);
160
+ constructor(value: string | null);
156
161
  }
157
162
  export declare class DdbInt extends DdbObj<number> {
158
- constructor(value: number);
163
+ constructor(value: number | null);
159
164
  }
160
165
  export declare class DdbString extends DdbObj<string> {
161
166
  constructor(value: string);
162
167
  }
163
168
  export declare class DdbLong extends DdbObj<bigint> {
164
- constructor(value: bigint);
169
+ constructor(value: bigint | null);
165
170
  }
166
171
  export declare class DdbDouble extends DdbObj<number> {
167
- constructor(value: number);
172
+ constructor(value: number | null);
168
173
  }
169
174
  export declare class DdbDateTime extends DdbObj<number> {
170
- constructor(value: number);
175
+ constructor(value: number | null);
171
176
  }
172
177
  export declare class DdbTimeStamp extends DdbObj<bigint> {
173
- constructor(value: bigint);
178
+ constructor(value: bigint | null);
174
179
  }
175
180
  export declare class DdbNanoTimeStamp extends DdbObj<bigint> {
176
- constructor(value: bigint);
181
+ constructor(value: bigint | null);
177
182
  }
178
183
  export declare class DdbVectorInt extends DdbObj<Int32Array> {
179
- constructor(value: number[], name?: string);
184
+ constructor(value: (number | null)[] | Int32Array, name?: string);
180
185
  }
181
186
  export declare class DdbVectorString extends DdbObj<string[]> {
182
187
  constructor(value: string[], name?: string);
183
188
  }
184
189
  export declare class DdbVectorDouble extends DdbObj<Float64Array> {
185
- constructor(value: number[], name?: string);
190
+ constructor(value: (number | null)[] | Float64Array, name?: string);
186
191
  }
187
192
  export declare class DdbVectorAny extends DdbObj {
188
193
  constructor(value: DdbObj<DdbValue>[], name?: string);
189
194
  }
195
+ export declare class DdbVectorSymbol extends DdbObj<DdbSymbolExtendedValue> {
196
+ constructor(value: string[], name?: string);
197
+ }
190
198
  export declare class DdbPair extends DdbObj<Int32Array> {
191
- constructor(l: number, r?: number);
199
+ constructor(l: number | null, r?: number | null);
192
200
  }
193
201
  export declare class DdbFunction extends DdbObj<DdbFunctionDefValue> {
194
202
  constructor(name: string, type: DdbFunctionType);
195
203
  }
196
204
  export declare function date2str(date: number, format?: string): string;
197
205
  export declare function datetime2str(datetime: number, format?: string): string;
198
- export declare function timestamp2str(timestamp: bigint): string;
206
+ /** format timestamp (bigint) to string
207
+ - timestamp: bigint value
208
+ - format?:
209
+ format string, default to `YYYY.MM.DD HH:mm:ss.SSS`
210
+ https://day.js.org/docs/en/parse/string-format#list-of-all-available-parsing-tokens
211
+ */
212
+ export declare function timestamp2str(timestamp: bigint, format?: string): string;
213
+ /** parse timestamp string to bigint value
214
+ - str: timestamp string, If it is an empty string, it will return the corresponding empty value (nulls.int64)
215
+ - format?:
216
+ The format string corresponding to the incoming string, the default is `YYYY.MM.DD HH:mm:ss.SSS`
217
+ https://day.js.org/docs/en/parse/string-format#list-of-all-available-parsing-tokens
218
+ */
219
+ export declare function str2timestamp(str: string, format?: string): bigint;
220
+ /** format nanotimestamp value (bigint) to string
221
+ - nanotimestamp: bigint value
222
+ - format?:
223
+ format string, default is `YYYY.MM.DD HH:mm:ss.SSSSSSSSS`
224
+ Seconds are in the format ss (must be included); nanoseconds are in the format SSSSSSSSS (must be included)
225
+ https://day.js.org/docs/en/parse/string-format#list-of-all-available-parsing-tokens
226
+ */
199
227
  export declare function nanotimestamp2str(nanotimestamp: bigint, format?: string): string;
200
228
  /** parse nano timestamp string to bigint value
201
- - str: nano timestamp string, 如果为空字符串会返回对应的空值 (nulls.int64)
202
- - format?: Format string up to and including seconds of the passed string, default is `YYYY.MM.DD HH:mm:ss`
229
+ - str: nano timestamp string, If it is an empty string, it will return the corresponding empty value (nulls.int64)
230
+ - format?:
231
+ The format string corresponding to the incoming string, the default is `YYYY.MM.DD HH:mm:ss.SSSSSSSSS`
232
+ Seconds are in the format ss (must be included); nanoseconds are in the format SSSSSSSSS (must be included)
203
233
  https://day.js.org/docs/en/parse/string-format#list-of-all-available-parsing-tokens
204
234
  */
205
235
  export declare function str2nanotimestamp(str: string, format?: string): bigint;
@@ -227,6 +257,7 @@ export declare class DDB {
227
257
  presolver(buf: Uint8Array): void;
228
258
  prejector(error: Error): void;
229
259
  presult: Promise<Uint8Array>;
260
+ get connected(): boolean;
230
261
  /**
231
262
  Initialize an instance of DolphinDB Client using the WebSocket URL
232
263
  (without establishing an actual network connection)
@@ -327,7 +358,7 @@ export declare class DDB {
327
358
  };
328
359
  /** 自动转换 js string, boolean 为 DdbObj */
329
360
  to_ddbobj(value: DdbObj | string | boolean): DdbObj;
330
- /** 转换 js 数组为 DdbObj[] (in place, 会修改原数组) */
361
+ /** 转换 js 数组为 DdbObj[] */
331
362
  to_ddbobjs(values: any[]): DdbObj<DdbValue>[];
332
363
  }
333
364
  export declare let ddb: DDB;
package/browser.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ddb = exports.DDB = exports.str2nanotimestamp = exports.nanotimestamp2str = exports.timestamp2str = exports.datetime2str = exports.date2str = exports.DdbFunction = exports.DdbPair = exports.DdbVectorAny = exports.DdbVectorDouble = exports.DdbVectorString = exports.DdbVectorInt = exports.DdbNanoTimeStamp = exports.DdbTimeStamp = exports.DdbDateTime = exports.DdbDouble = exports.DdbLong = exports.DdbString = exports.DdbInt = exports.DdbChar = exports.DdbBool = exports.DdbVoid = exports.DdbObj = exports.timezone_offset = exports.nulls = exports.DdbFunctionType = exports.DdbType = exports.DdbForm = void 0;
3
+ exports.ddb = exports.DDB = exports.str2nanotimestamp = exports.nanotimestamp2str = exports.str2timestamp = exports.timestamp2str = exports.datetime2str = exports.date2str = exports.DdbFunction = exports.DdbPair = exports.DdbVectorSymbol = exports.DdbVectorAny = exports.DdbVectorDouble = exports.DdbVectorString = exports.DdbVectorInt = exports.DdbNanoTimeStamp = exports.DdbTimeStamp = exports.DdbDateTime = exports.DdbDouble = exports.DdbLong = exports.DdbString = exports.DdbInt = exports.DdbChar = exports.DdbBool = exports.DdbVoid = exports.DdbObj = exports.timezone_offset = exports.nulls = exports.DdbFunctionType = exports.DdbType = exports.DdbForm = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const dayjs_1 = tslib_1.__importDefault(require("dayjs"));
6
6
  const customParseFormat_js_1 = tslib_1.__importDefault(require("dayjs/plugin/customParseFormat.js"));
@@ -72,10 +72,15 @@ var DdbFunctionType;
72
72
  DdbFunctionType[DdbFunctionType["JitPartialFunc"] = 8] = "JitPartialFunc";
73
73
  })(DdbFunctionType = exports.DdbFunctionType || (exports.DdbFunctionType = {}));
74
74
  exports.nulls = {
75
+ bool: 0x80,
75
76
  char: '\x80',
76
77
  int16: -32768,
77
78
  int32: -2147483648,
78
- int64: -0x8000000000000000n, // -922_3372_0368_5477_5808
79
+ int64: -0x8000000000000000n,
80
+ float32: -3.4028234663852886e+38,
81
+ /** -Number.MAX_VALUE */
82
+ double: -Number.MAX_VALUE,
83
+ bytes16: Uint8Array.from(new Array(16).fill(0))
79
84
  };
80
85
  exports.timezone_offset = 1000 * 60 * new Date().getTimezoneOffset();
81
86
  /** 可以表示所有 DolphinDB 数据库中的数据类型 */
@@ -92,7 +97,7 @@ class DdbObj {
92
97
  form: DdbForm.scalar,
93
98
  type: DdbType.void,
94
99
  length: 0,
95
- value: undefined
100
+ value: null
96
101
  });
97
102
  const type = buf[0];
98
103
  const form = buf[1];
@@ -241,13 +246,18 @@ class DdbObj {
241
246
  switch (type) {
242
247
  case DdbType.void:
243
248
  return [1, null];
244
- case DdbType.bool:
245
- return [1, Boolean(buf[0])];
246
- case DdbType.char:
247
- return [1, String.fromCharCode(buf[0])];
249
+ case DdbType.bool: {
250
+ const value = buf[0];
251
+ return [1, value === exports.nulls.bool ? null : Boolean(value)];
252
+ }
253
+ case DdbType.char: {
254
+ const value = String.fromCharCode(buf[0]);
255
+ return [1, value === exports.nulls.char ? null : value];
256
+ }
248
257
  case DdbType.short: {
249
258
  const dv = new DataView(buf.buffer, buf.byteOffset);
250
- return [2, dv.getInt16(0, le)];
259
+ const value = dv.getInt16(0, le);
260
+ return [2, value === exports.nulls.int16 ? null : value];
251
261
  }
252
262
  case DdbType.int:
253
263
  // datetime
@@ -259,15 +269,18 @@ class DdbObj {
259
269
  case DdbType.datetime:
260
270
  case DdbType.datehour: {
261
271
  const dv = new DataView(buf.buffer, buf.byteOffset);
262
- return [4, dv.getInt32(0, le)];
272
+ const value = dv.getInt32(0, le);
273
+ return [4, value === exports.nulls.int32 ? null : value];
263
274
  }
264
275
  case DdbType.float: {
265
276
  const dv = new DataView(buf.buffer, buf.byteOffset);
266
- return [4, dv.getFloat32(0, le)];
277
+ const value = dv.getFloat32(0, le);
278
+ return [4, value === exports.nulls.float32 ? null : value];
267
279
  }
268
280
  case DdbType.double: {
269
281
  const dv = new DataView(buf.buffer, buf.byteOffset);
270
- return [8, dv.getFloat64(0, le)];
282
+ const value = dv.getFloat64(0, le);
283
+ return [8, value === exports.nulls.double ? null : value];
271
284
  }
272
285
  case DdbType.long:
273
286
  // timestamp
@@ -275,7 +288,8 @@ class DdbObj {
275
288
  case DdbType.nanotime:
276
289
  case DdbType.nanotimestamp: {
277
290
  const dv = new DataView(buf.buffer, buf.byteOffset);
278
- return [8, dv.getBigInt64(0, le)];
291
+ const value = dv.getBigInt64(0, le);
292
+ return [8, value === exports.nulls.int64 ? null : value];
279
293
  }
280
294
  case DdbType.string:
281
295
  case DdbType.symbol:
@@ -576,11 +590,26 @@ class DdbObj {
576
590
  case DdbType.void:
577
591
  return [Uint8Array.of(1)];
578
592
  case DdbType.bool:
579
- return [Uint8Array.of(Number(value))];
593
+ return [
594
+ Uint8Array.of(value === null ?
595
+ exports.nulls.bool
596
+ :
597
+ Number(value))
598
+ ];
580
599
  case DdbType.char:
581
- return [Uint8Array.of(value.charCodeAt(0))];
600
+ return [
601
+ Uint8Array.of((value === null ?
602
+ exports.nulls.char
603
+ :
604
+ value).charCodeAt(0))
605
+ ];
582
606
  case DdbType.short:
583
- return [Int16Array.of(value)];
607
+ return [
608
+ Int16Array.of(value === null ?
609
+ exports.nulls.int16
610
+ :
611
+ value)
612
+ ];
584
613
  case DdbType.int:
585
614
  // datetime
586
615
  case DdbType.date:
@@ -590,17 +619,37 @@ class DdbObj {
590
619
  case DdbType.second:
591
620
  case DdbType.datetime:
592
621
  case DdbType.datehour:
593
- return [Int32Array.of(value)];
622
+ return [
623
+ Int32Array.of(value === null ?
624
+ exports.nulls.int32
625
+ :
626
+ value)
627
+ ];
594
628
  case DdbType.float:
595
- return [Float32Array.of(value)];
629
+ return [
630
+ Float32Array.of(value === null ?
631
+ exports.nulls.float32
632
+ :
633
+ value)
634
+ ];
596
635
  case DdbType.double:
597
- return [Float64Array.of(value)];
636
+ return [
637
+ Float64Array.of(value === null ?
638
+ exports.nulls.double
639
+ :
640
+ value)
641
+ ];
598
642
  case DdbType.long:
599
643
  // timestamp
600
644
  case DdbType.timestamp:
601
645
  case DdbType.nanotime:
602
646
  case DdbType.nanotimestamp:
603
- return [BigInt64Array.of(this.value)];
647
+ return [
648
+ BigInt64Array.of(value === null ?
649
+ exports.nulls.int64
650
+ :
651
+ value)
652
+ ];
604
653
  case DdbType.string:
605
654
  case DdbType.symbol:
606
655
  case DdbType.code:
@@ -764,7 +813,7 @@ class DdbObj {
764
813
  case DdbType.symbol_extended: {
765
814
  const { base_id, base, data } = value;
766
815
  return [
767
- Uint32Array.of(base_id, base.length),
816
+ Uint32Array.of(base_id || 0, base.length),
768
817
  ...this.pack_vector_body(base, DdbType.string, base.length),
769
818
  data
770
819
  ];
@@ -843,6 +892,11 @@ class DdbObj {
843
892
  case DdbType.ipaddr:
844
893
  row[name] = value.subarray(16 * i, 16 * (i + 1));
845
894
  break;
895
+ case DdbType.symbol_extended: {
896
+ const { base, data } = value;
897
+ row[name] = base[data[i]];
898
+ break;
899
+ }
846
900
  default:
847
901
  row[name] = value[i];
848
902
  }
@@ -874,6 +928,7 @@ class DdbVoid extends DdbObj {
874
928
  form: DdbForm.scalar,
875
929
  type: DdbType.void,
876
930
  length: 0,
931
+ value: null,
877
932
  });
878
933
  }
879
934
  }
@@ -906,7 +961,7 @@ class DdbInt extends DdbObj {
906
961
  form: DdbForm.scalar,
907
962
  type: DdbType.int,
908
963
  length: 4,
909
- value
964
+ value,
910
965
  });
911
966
  }
912
967
  }
@@ -985,7 +1040,13 @@ class DdbVectorInt extends DdbObj {
985
1040
  length: 0,
986
1041
  rows: value.length,
987
1042
  cols: 1,
988
- value: Int32Array.from(value),
1043
+ value: value instanceof Int32Array ?
1044
+ value
1045
+ :
1046
+ Int32Array.from(value, v => v === null ?
1047
+ exports.nulls.int32
1048
+ :
1049
+ v),
989
1050
  name,
990
1051
  });
991
1052
  }
@@ -1013,7 +1074,13 @@ class DdbVectorDouble extends DdbObj {
1013
1074
  length: 0,
1014
1075
  rows: value.length,
1015
1076
  cols: 1,
1016
- value: Float64Array.from(value),
1077
+ value: value instanceof Float64Array ?
1078
+ value
1079
+ :
1080
+ Float64Array.from(value, v => v === null ?
1081
+ exports.nulls.double
1082
+ :
1083
+ v),
1017
1084
  name,
1018
1085
  });
1019
1086
  }
@@ -1033,15 +1100,46 @@ class DdbVectorAny extends DdbObj {
1033
1100
  }
1034
1101
  }
1035
1102
  exports.DdbVectorAny = DdbVectorAny;
1103
+ class DdbVectorSymbol extends DdbObj {
1104
+ constructor(value, name) {
1105
+ let map = new Map([
1106
+ ['', 0]
1107
+ ]);
1108
+ let data = new Uint32Array(value.length);
1109
+ for (let i = 0; i < value.length; i++) {
1110
+ const x = value[i];
1111
+ let index = map.get(x);
1112
+ if (index === undefined) {
1113
+ index = map.size;
1114
+ map.set(x, index);
1115
+ }
1116
+ data[i] = index;
1117
+ }
1118
+ super({
1119
+ form: DdbForm.vector,
1120
+ type: DdbType.symbol_extended,
1121
+ length: 0,
1122
+ rows: value.length,
1123
+ cols: 1,
1124
+ value: {
1125
+ base: [...map.keys()],
1126
+ base_id: null,
1127
+ data,
1128
+ },
1129
+ name
1130
+ });
1131
+ }
1132
+ }
1133
+ exports.DdbVectorSymbol = DdbVectorSymbol;
1036
1134
  class DdbPair extends DdbObj {
1037
- constructor(l, r = -2147483648) {
1135
+ constructor(l, r = null) {
1038
1136
  super({
1039
1137
  form: DdbForm.pair,
1040
1138
  type: DdbType.int,
1041
1139
  length: 0,
1042
1140
  rows: 2,
1043
1141
  cols: 1,
1044
- value: Int32Array.of(l, r)
1142
+ value: Int32Array.of(l === null ? exports.nulls.int32 : l, r === null ? exports.nulls.int32 : r)
1045
1143
  });
1046
1144
  }
1047
1145
  }
@@ -1071,34 +1169,79 @@ function datetime2str(datetime, format = 'YYYY.MM.DD HH:mm:ss') {
1071
1169
  (0, dayjs_1.default)(exports.timezone_offset + 1000 * datetime).format(format);
1072
1170
  }
1073
1171
  exports.datetime2str = datetime2str;
1074
- function timestamp2str(timestamp) {
1172
+ /** format timestamp (bigint) to string
1173
+ - timestamp: bigint value
1174
+ - format?:
1175
+ format string, default to `YYYY.MM.DD HH:mm:ss.SSS`
1176
+ https://day.js.org/docs/en/parse/string-format#list-of-all-available-parsing-tokens
1177
+ */
1178
+ function timestamp2str(timestamp, format = 'YYYY.MM.DD HH:mm:ss.SSS') {
1075
1179
  return timestamp === exports.nulls.int64 ?
1076
1180
  ''
1077
1181
  :
1078
- (0, dayjs_1.default)(exports.timezone_offset + Number(timestamp)).format('YYYY.MM.DD HH:mm:ss.SSS');
1182
+ (0, dayjs_1.default)(exports.timezone_offset + Number(timestamp)).format(format);
1079
1183
  }
1080
1184
  exports.timestamp2str = timestamp2str;
1081
- function nanotimestamp2str(nanotimestamp, format = 'YYYY.MM.DD HH:mm:ss') {
1082
- return nanotimestamp === exports.nulls.int64 ?
1083
- ''
1084
- :
1085
- (0, dayjs_1.default)(exports.timezone_offset + (Number(nanotimestamp) / 1000000)).format(format) + `.${nanotimestamp % 1000000000n}`;
1185
+ /** parse timestamp string to bigint value
1186
+ - str: timestamp string, If it is an empty string, it will return the corresponding empty value (nulls.int64)
1187
+ - format?:
1188
+ The format string corresponding to the incoming string, the default is `YYYY.MM.DD HH:mm:ss.SSS`
1189
+ https://day.js.org/docs/en/parse/string-format#list-of-all-available-parsing-tokens
1190
+ */
1191
+ function str2timestamp(str, format = 'YYYY.MM.DD HH:mm:ss.SSS') {
1192
+ if (!str)
1193
+ return exports.nulls.int64;
1194
+ if (str.length !== format.length)
1195
+ throw new Error('The length of the timestamp string is not equal to the length of the format string');
1196
+ return BigInt(-exports.timezone_offset +
1197
+ (0, dayjs_1.default)(str, format).valueOf());
1198
+ }
1199
+ exports.str2timestamp = str2timestamp;
1200
+ /** format nanotimestamp value (bigint) to string
1201
+ - nanotimestamp: bigint value
1202
+ - format?:
1203
+ format string, default is `YYYY.MM.DD HH:mm:ss.SSSSSSSSS`
1204
+ Seconds are in the format ss (must be included); nanoseconds are in the format SSSSSSSSS (must be included)
1205
+ https://day.js.org/docs/en/parse/string-format#list-of-all-available-parsing-tokens
1206
+ */
1207
+ function nanotimestamp2str(nanotimestamp, format = 'YYYY.MM.DD HH:mm:ss.SSSSSSSSS') {
1208
+ if (nanotimestamp === exports.nulls.int64)
1209
+ return '';
1210
+ const i_second_start = format.indexOf('ss');
1211
+ if (i_second_start === -1)
1212
+ throw new Error('The format string must contain the format for seconds (ss)');
1213
+ const i_second_end = i_second_start + 2;
1214
+ const i_nanosecond_start = format.indexOf('SSSSSSSSS', i_second_end);
1215
+ if (i_nanosecond_start === -1)
1216
+ throw new Error('The format string must contain the format for nanoseconds (SSSSSSSSS)');
1217
+ return ((0, dayjs_1.default)(exports.timezone_offset + (Number(nanotimestamp) / 1000000)).format(format.slice(0, i_second_end)) +
1218
+ format.slice(i_second_end, i_nanosecond_start) +
1219
+ String(nanotimestamp % 1000000000n));
1086
1220
  }
1087
1221
  exports.nanotimestamp2str = nanotimestamp2str;
1088
1222
  /** parse nano timestamp string to bigint value
1089
- - str: nano timestamp string, 如果为空字符串会返回对应的空值 (nulls.int64)
1090
- - format?: Format string up to and including seconds of the passed string, default is `YYYY.MM.DD HH:mm:ss`
1223
+ - str: nano timestamp string, If it is an empty string, it will return the corresponding empty value (nulls.int64)
1224
+ - format?:
1225
+ The format string corresponding to the incoming string, the default is `YYYY.MM.DD HH:mm:ss.SSSSSSSSS`
1226
+ Seconds are in the format ss (must be included); nanoseconds are in the format SSSSSSSSS (must be included)
1091
1227
  https://day.js.org/docs/en/parse/string-format#list-of-all-available-parsing-tokens
1092
1228
  */
1093
- function str2nanotimestamp(str, format = 'YYYY.MM.DD HH:mm:ss') {
1229
+ function str2nanotimestamp(str, format = 'YYYY.MM.DD HH:mm:ss.SSSSSSSSS') {
1094
1230
  if (!str)
1095
1231
  return exports.nulls.int64;
1096
- if (str.length - format.length !== 9)
1097
- throw new Error('nanotimestamp 字符串长度减格式串长度应该等于 9');
1232
+ if (str.length !== format.length)
1233
+ throw new Error('nanotimestamp string length is not equal to format string length');
1234
+ const i_second_start = format.indexOf('ss');
1235
+ if (i_second_start === -1)
1236
+ throw new Error('The format string must contain the format for seconds (ss)');
1237
+ const i_second_end = i_second_start + 2;
1238
+ const i_nanosecond_start = format.indexOf('SSSSSSSSS', i_second_end);
1239
+ if (i_nanosecond_start === -1)
1240
+ throw new Error('Format string must contain nanosecond format (SSSSSSSSS)');
1098
1241
  return (BigInt(-exports.timezone_offset +
1099
- (0, dayjs_1.default)(str.slice(0, format.length), format).valueOf()) * 1000000n
1242
+ (0, dayjs_1.default)(str.slice(0, i_second_end), format.slice(0, i_second_end)).valueOf()) * 1000000n
1100
1243
  +
1101
- BigInt(str.slice(format.length)));
1244
+ BigInt(str.slice(i_nanosecond_start, i_nanosecond_start + 9)));
1102
1245
  }
1103
1246
  exports.str2nanotimestamp = str2nanotimestamp;
1104
1247
  class DDB {
@@ -1137,12 +1280,14 @@ class DDB {
1137
1280
  /** resolver, rejector, promise of last rpc */
1138
1281
  presolver(buf) { }
1139
1282
  prejector(error) { }
1283
+ get connected() {
1284
+ return this.websocket?.readyState === WebSocket.OPEN;
1285
+ }
1140
1286
  /** Establish the actual WebSocket connection to the DolphinDB corresponding to the URL */
1141
1287
  async connect({ url = this.url, login = true, username = 'admin', password = '123456', python = false, } = {}) {
1142
1288
  this.url = url;
1143
1289
  this.python = python;
1144
- if (this.websocket?.readyState === WebSocket.OPEN)
1145
- this.disconnect();
1290
+ this.disconnect();
1146
1291
  let websocket = new WebSocket(url, python ? ['python'] : []);
1147
1292
  // https://stackoverflow.com/questions/11821096/what-is-the-difference-between-an-arraybuffer-and-a-blob/39951543
1148
1293
  websocket.binaryType = 'arraybuffer';
@@ -1196,7 +1341,10 @@ class DDB {
1196
1341
  ' )\n' +
1197
1342
  '}\n', { urgent: true });
1198
1343
  if (login)
1199
- await this.call('login', [username, password], { urgent: true });
1344
+ if (this.python)
1345
+ await this.eval(`login(${username.quote('double')}, ${password.quote('double')})`, { urgent: true });
1346
+ else
1347
+ await this.call('login', [username, password], { urgent: true });
1200
1348
  }
1201
1349
  get_rpc_options({ urgent = false, secondary = false, async: _async = false, pickle = false, clear = false, api = false, compress = false, cancellable = true, priority = urgent ? 8 : 4, parallelism = 8, root_id = '', limit, } = {}) {
1202
1350
  let flag = 0;
@@ -1230,7 +1378,11 @@ class DDB {
1230
1378
  return `/ ${options.join('_')}`;
1231
1379
  }
1232
1380
  disconnect() {
1233
- this.websocket?.close(1000);
1381
+ if (this.connected)
1382
+ this.websocket.close(1000);
1383
+ this.presolver = buf => { };
1384
+ this.prejector = error => { };
1385
+ this.presult = Promise.resolve(null);
1234
1386
  }
1235
1387
  /** rpc through websocket (function/script/variable command)
1236
1388
  - type: API 类型: 'script' | 'function' | 'variable'
@@ -1241,7 +1393,7 @@ class DDB {
1241
1393
  async rpc(type, { script, func, args = [], vars = [], urgent, }) {
1242
1394
  if (!this.websocket)
1243
1395
  await this.connect();
1244
- if (this.websocket.readyState !== WebSocket.OPEN)
1396
+ if (!this.connected)
1245
1397
  throw new Error(`${this.url} is already disconnected`);
1246
1398
  // 临界区:保证多个 rpc 并发时形成 promise 链
1247
1399
  // ddb 世界观:需要等待上一个 rpc 结果从 server 返回之后才能发起下一个调用
@@ -1264,7 +1416,7 @@ class DDB {
1264
1416
  // 临界区结束,只有一个 rpc 请求可以写 WebSocket
1265
1417
  if (urgent && type !== 'script' && type !== 'function')
1266
1418
  throw new Error('urgent 只适用于 script 和 funciton');
1267
- this.to_ddbobjs(args);
1419
+ args = this.to_ddbobjs(args);
1268
1420
  const command = this.enc.encode((() => {
1269
1421
  switch (type) {
1270
1422
  case 'function':
@@ -1406,11 +1558,9 @@ class DDB {
1406
1558
  throw new Error(`不能自动转换 ${type} 至 DdbObj`);
1407
1559
  }
1408
1560
  }
1409
- /** 转换 js 数组为 DdbObj[] (in place, 会修改原数组) */
1561
+ /** 转换 js 数组为 DdbObj[] */
1410
1562
  to_ddbobjs(values) {
1411
- for (let i = 0; i < values.length; i++)
1412
- values[i] = this.to_ddbobj(values[i]);
1413
- return values;
1563
+ return values.map(value => this.to_ddbobj(value));
1414
1564
  }
1415
1565
  }
1416
1566
  exports.DDB = DDB;