dolphindb 3.0.123 → 3.0.125

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/browser.js CHANGED
@@ -825,41 +825,20 @@ export class DdbObj {
825
825
  ];
826
826
  }
827
827
  case DdbType.iotany: {
828
- // 构造 indexes
829
- const dv = new DataView(buf.buffer, buf.byteOffset);
830
- let i_value_start = 0;
831
- const size = Number(dv.getUint32(i_value_start, le));
832
- i_value_start += 4;
833
- const indexes = new Array(size * 2);
834
- for (let i = 0; i < size; i++) {
835
- const type = dv.getUint32(i_value_start, le);
836
- i_value_start += 4;
837
- const idx = dv.getUint32(i_value_start, le);
838
- i_value_start += 4;
839
- indexes[i * 2] = type;
840
- indexes[i * 2 + 1] = idx;
841
- }
842
- // 构造 sub vector
843
- const type_size = dv.getUint32(i_value_start, le);
844
- i_value_start += 4;
845
- const sub_vec = new Map();
846
- for (let i = 0; i < type_size; i++) {
847
- const flag = dv.getUint16(i_value_start, le);
848
- i_value_start += 2;
849
- const form = flag >> 8;
850
- const sub_type = flag & 0xff;
851
- assert(form === DdbForm.vector, t('iotany sub vector 不支持非 vector 类型'));
852
- const sub_size = dv.getUint32(i_value_start, le);
853
- i_value_start += 8; // 同时跳过 sub_size 和 cols
854
- let [len, vector] = this.parse_vector_items(buf.subarray(i_value_start), le, sub_type, sub_size);
855
- vector = converts(sub_type, vector, sub_size, le);
856
- i_value_start += len;
857
- sub_vec.set(sub_type, vector);
828
+ const [len, anys] = this.parse_vector_items(buf, le, DdbType.any, length);
829
+ const metas = anys[0].data();
830
+ assert(metas.length >= 2, t('iotany 的 meta vector 长度至少为 2'));
831
+ const size = metas[0];
832
+ // let sub_vec_count = meta_vec[1]
833
+ let sub_vecs = new Map();
834
+ for (let i = 1; i < length; i++) {
835
+ const sub_vector = anys[i];
836
+ const sub_type = sub_vector.type;
837
+ sub_vecs.set(sub_type, converts(sub_type, sub_vector.data(), sub_vector.length, le));
858
838
  }
859
839
  return [
860
- i_value_start,
861
- // 根据 indexes 数组构建最终的 value 数组
862
- seq(size, i => (sub_vec.get(indexes[i * 2]))[indexes[i * 2 + 1]])
840
+ len,
841
+ seq(size, i => (sub_vecs.get(metas[i + size + 2]))[metas[i + 2]])
863
842
  ];
864
843
  }
865
844
  // 25 01 type = decimal32, form = vector
@@ -2989,46 +2968,52 @@ export class DDB {
2989
2968
  await this.connect();
2990
2969
  const { script, func, args: _args = [], vars = [], urgent, listener, on_more_messages, } = options;
2991
2970
  if (func === 'pnode_run')
2992
- await (this.ppnode_run ??= this.eval(this.python ?
2993
- '\n' +
2994
- 'def pnode_run (nodes, func_name, args, add_node_alias):\n' +
2995
- ' nargs = size(args)\n' +
2996
- ' func = funcByName(func_name)\n' +
2997
- ' \n' +
2998
- ' if not nargs:\n' +
2999
- ' return pnodeRun(func, nodes, add_node_alias)\n' +
3000
- ' \n' +
3001
- ' args_partial = [ ]\n' +
3002
- ' args_partial.append(func)\n' +
3003
- ' for a in args:\n' +
3004
- ' args_partial.append(a)\n' +
3005
- ' \n' +
3006
- ' return pnodeRun(\n' +
3007
- ' unifiedCall(partial, args_partial),\n' +
3008
- ' nodes,\n' +
3009
- ' add_node_alias\n' +
3010
- ' )\n'
3011
- :
3012
- // 这个开头的空行很重要,应该可以绕过 webLoginRequired = true 时禁止执行代码
3013
- // 搜一下 APISocketConsole::execute
3014
- // https://dolphindb1.atlassian.net/browse/D20-4991
2971
+ try {
2972
+ await (this.ppnode_run ??= this.eval(this.python ?
3015
2973
  '\n' +
3016
- 'def pnode_run (nodes, func_name, args, add_node_alias = true) {\n' +
2974
+ 'def pnode_run (nodes, func_name, args, add_node_alias):\n' +
3017
2975
  ' nargs = size(args)\n' +
3018
2976
  ' func = funcByName(func_name)\n' +
3019
2977
  ' \n' +
3020
- ' if (!nargs)\n' +
2978
+ ' if not nargs:\n' +
3021
2979
  ' return pnodeRun(func, nodes, add_node_alias)\n' +
3022
2980
  ' \n' +
3023
- ' args_partial = array(any, 1 + nargs, 1 + nargs)\n' +
3024
- ' args_partial[0] = func\n' +
3025
- ' args_partial[1:] = args\n' +
2981
+ ' args_partial = [ ]\n' +
2982
+ ' args_partial.append(func)\n' +
2983
+ ' for a in args:\n' +
2984
+ ' args_partial.append(a)\n' +
2985
+ ' \n' +
3026
2986
  ' return pnodeRun(\n' +
3027
2987
  ' unifiedCall(partial, args_partial),\n' +
3028
2988
  ' nodes,\n' +
3029
2989
  ' add_node_alias\n' +
3030
- ' )\n' +
3031
- '}\n', { urgent: true }));
2990
+ ' )\n'
2991
+ :
2992
+ // 这个开头的空行很重要,应该可以绕过 webLoginRequired = true 时禁止执行代码
2993
+ // 搜一下 APISocketConsole::execute
2994
+ // https://dolphindb1.atlassian.net/browse/D20-4991
2995
+ '\n' +
2996
+ 'def pnode_run (nodes, func_name, args, add_node_alias = true) {\n' +
2997
+ ' nargs = size(args)\n' +
2998
+ ' func = funcByName(func_name)\n' +
2999
+ ' \n' +
3000
+ ' if (!nargs)\n' +
3001
+ ' return pnodeRun(func, nodes, add_node_alias)\n' +
3002
+ ' \n' +
3003
+ ' args_partial = array(any, 1 + nargs, 1 + nargs)\n' +
3004
+ ' args_partial[0] = func\n' +
3005
+ ' args_partial[1:] = args\n' +
3006
+ ' return pnodeRun(\n' +
3007
+ ' unifiedCall(partial, args_partial),\n' +
3008
+ ' nodes,\n' +
3009
+ ' add_node_alias\n' +
3010
+ ' )\n' +
3011
+ '}\n', { urgent: true }));
3012
+ }
3013
+ catch (error) {
3014
+ this.ppnode_run = undefined;
3015
+ throw error;
3016
+ }
3032
3017
  // this 上的当前配置需要在 message 到达后使用,先保存起来
3033
3018
  const _listeners = [...this.listeners].reverse();
3034
3019
  // rpc 请求期间需要独占 websocket,所以设计了一个锁,申请之后才能使用
@@ -3255,34 +3240,6 @@ export class DDB {
3255
3240
  - add_node_alias?: 设置 nodes 参数时选传,其它情况不传
3256
3241
  - listener?: 处理本次 rpc 期间的消息 (DdbMessage) */
3257
3242
  async invoke(func, args, options) {
3258
- try {
3259
- await (this.pinvoke ??= this.eval(this.python ?
3260
- '\n' +
3261
- 'def invoke (func, args_json):\n' +
3262
- ' args = fromStdJson(args_json)\n' +
3263
- ' func_ = func\n' +
3264
- ' if type(func) == STRING:\n' +
3265
- ' func_ = funcByName(func)\n' +
3266
- ' if type(args) != ANY:\n' +
3267
- ' args = cast(args, ANY)\n' +
3268
- ' return unifiedCall(func_, args)\n'
3269
- :
3270
- '\n' +
3271
- 'def invoke (func, args_json) {\n' +
3272
- ' args = fromStdJson(args_json)\n' +
3273
- ' func_ = func\n' +
3274
- ' if (type(func) == STRING)\n' +
3275
- ' func_ = funcByName(func)\n' +
3276
- ' if (type(args) != ANY)\n' +
3277
- ' args = cast(args, ANY)\n' +
3278
- ' return unifiedCall(func_, args)\n' +
3279
- '}\n', { urgent: true }));
3280
- }
3281
- catch (error) {
3282
- // invoke 没有正确执行时,重新将 pinvoke 赋值为 undefined
3283
- this.pinvoke = undefined;
3284
- throw error;
3285
- }
3286
3243
  // 检查 args 是否全部为简单参数,是则直接调用 call,避免 invoke 间接调用
3287
3244
  // 逻辑类似 DdbObj.to_ddbobjs, 需要同步修改
3288
3245
  let simple = true;
@@ -3299,11 +3256,42 @@ export class DDB {
3299
3256
  break;
3300
3257
  }
3301
3258
  }
3302
- if (!simple && has_ddbobj)
3303
- throw new Error(t('调用 ddb.invoke 的参数中不能同时有 DdbObj 与复杂 js 原生对象'));
3304
- const result = simple
3305
- ? await this.call(func, args, options)
3306
- : await this.call('invoke', [func, JSON.stringify(args)], options);
3259
+ let result;
3260
+ if (simple)
3261
+ result = await this.call(func, args, options);
3262
+ else {
3263
+ if (has_ddbobj)
3264
+ throw new Error(t('调用 ddb.invoke 的参数中不能同时有 DdbObj 与复杂 js 原生对象'));
3265
+ try {
3266
+ await (this.pinvoke ??= this.eval(this.python ?
3267
+ '\n' +
3268
+ 'def invoke (func, args_json):\n' +
3269
+ ' args = fromStdJson(args_json)\n' +
3270
+ ' func_ = func\n' +
3271
+ ' if type(func) == STRING:\n' +
3272
+ ' func_ = funcByName(func)\n' +
3273
+ ' if type(args) != ANY:\n' +
3274
+ ' args = cast(args, ANY)\n' +
3275
+ ' return unifiedCall(func_, args)\n'
3276
+ :
3277
+ '\n' +
3278
+ 'def invoke (func, args_json) {\n' +
3279
+ ' args = fromStdJson(args_json)\n' +
3280
+ ' func_ = func\n' +
3281
+ ' if (type(func) == STRING)\n' +
3282
+ ' func_ = funcByName(func)\n' +
3283
+ ' if (type(args) != ANY)\n' +
3284
+ ' args = cast(args, ANY)\n' +
3285
+ ' return unifiedCall(func_, args)\n' +
3286
+ '}\n', { urgent: true }));
3287
+ }
3288
+ catch (error) {
3289
+ // invoke 没有正确执行时,重新将 pinvoke 赋值为 undefined
3290
+ this.pinvoke = undefined;
3291
+ throw error;
3292
+ }
3293
+ result = await this.call('invoke', [func, JSON.stringify(args)], options);
3294
+ }
3307
3295
  return result.data(options);
3308
3296
  }
3309
3297
  /** 执行 dolphindb 脚本,返回 js 原生对象或值(调用 DdbObj.data() 后的结果)