dolphindb 2.0.903 → 2.0.905
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 +6 -2
- package/browser.js.map +1 -1
- package/docs.en.json +946 -59
- package/docs.zh.json +56 -57
- package/i18n/dict.json +6 -0
- package/index.d.ts +1 -1
- package/index.js +166 -3
- package/index.js.map +1 -1
- package/package.json +5 -5
package/docs.zh.json
CHANGED
|
@@ -8867,11 +8867,11 @@
|
|
|
8867
8867
|
"",
|
|
8868
8868
|
"`tableName` 字符串标量或向量,表示表名。若不指定,表示指定数据库下的所有表。",
|
|
8869
8869
|
"",
|
|
8870
|
-
"`partition`
|
|
8870
|
+
"`partition` 表示分区。是字符串,表示备份分区的相对路径。分区路径可以包含通配符(\"%\"和\"?\"),\"?\"表示单个字符,\"%\"表示0,1或多个字符。",
|
|
8871
8871
|
"",
|
|
8872
|
-
"*
|
|
8872
|
+
"* 若仅检查某个分区,输入分区的相对路径或者\"%/\"+”分区名称”。举例:要检查\"dfs://compoDB\"下的分区”20170810/50_100”,输入\"/compoDB/20170807/0_50\"或者\"%/20170807/0_50\"。",
|
|
8873
8873
|
"",
|
|
8874
|
-
"*
|
|
8874
|
+
"* 若需要检查所有分区,直接输入\"%\"。"
|
|
8875
8875
|
]
|
|
8876
8876
|
}
|
|
8877
8877
|
]
|
|
@@ -12660,7 +12660,7 @@
|
|
|
12660
12660
|
"",
|
|
12661
12661
|
".. _dummyTable_ad:",
|
|
12662
12662
|
"",
|
|
12663
|
-
"`dummyTable`
|
|
12663
|
+
"`dummyTable` 一个表对象,和订阅的流数据表的 schema 一致,可以含有数据,亦可为空表。",
|
|
12664
12664
|
"",
|
|
12665
12665
|
".. _outputTable_ad:",
|
|
12666
12666
|
"",
|
|
@@ -13072,7 +13072,7 @@
|
|
|
13072
13072
|
"",
|
|
13073
13073
|
".. _dummyTable_cs:",
|
|
13074
13074
|
"",
|
|
13075
|
-
"`dummyTable`
|
|
13075
|
+
"`dummyTable` 一个表对象,和订阅的流数据表的 schema 一致,可以含有数据,亦可为空表。",
|
|
13076
13076
|
"",
|
|
13077
13077
|
".. _outputTable_cs:",
|
|
13078
13078
|
"",
|
|
@@ -15004,7 +15004,7 @@
|
|
|
15004
15004
|
"",
|
|
15005
15005
|
".. _dummyTable_rs:",
|
|
15006
15006
|
"",
|
|
15007
|
-
"`dummyTable`
|
|
15007
|
+
"`dummyTable` 一个表对象,和订阅的流数据表的 schema 一致,可以含有数据,亦可为空表。",
|
|
15008
15008
|
"",
|
|
15009
15009
|
".. _outputTable_rs:",
|
|
15010
15010
|
"",
|
|
@@ -15582,7 +15582,7 @@
|
|
|
15582
15582
|
"",
|
|
15583
15583
|
".. _dummyTable_ts:",
|
|
15584
15584
|
"",
|
|
15585
|
-
"`dummyTable`
|
|
15585
|
+
"`dummyTable` 一个表对象,和订阅的流数据表的 schema 一致,可以含有数据,亦可为空表。",
|
|
15586
15586
|
"",
|
|
15587
15587
|
".. _outputTable_ts:",
|
|
15588
15588
|
"",
|
|
@@ -39557,7 +39557,7 @@
|
|
|
39557
39557
|
"value": [
|
|
39558
39558
|
"创建索引内存表(indexed table)。一个索引内存表有一个主键。主键可由一个或多个字段组成。",
|
|
39559
39559
|
"",
|
|
39560
|
-
"向表中添加新记录时,系统会检查新记录的 *keyColumns*
|
|
39560
|
+
"向表中添加新记录时,系统会检查新记录的 *keyColumns* 值。如果新记录的 *keyColumns* 值与已有记录的 *keyColumns* 值重复,会更新表中对应的记录。",
|
|
39561
39561
|
"",
|
|
39562
39562
|
"查询优化:",
|
|
39563
39563
|
" ",
|
|
@@ -39691,7 +39691,7 @@
|
|
|
39691
39691
|
"GOOG 2018.06.08T12:30:00 58 7800",
|
|
39692
39692
|
"==== =================== ===== ====",
|
|
39693
39693
|
"",
|
|
39694
|
-
"
|
|
39694
|
+
"插入新记录,并且新记录中的 *keyColumns* 的值与表中 *keyColumns* 的值重复:",
|
|
39695
39695
|
""
|
|
39696
39696
|
]
|
|
39697
39697
|
},
|
|
@@ -44830,7 +44830,7 @@
|
|
|
44830
44830
|
"value": [
|
|
44831
44831
|
"创建键值内存表。一个键值内存表有一个主键。主键可由一个或多个字段组成。",
|
|
44832
44832
|
"",
|
|
44833
|
-
"
|
|
44833
|
+
"向表中添加新记录时,系统会自动检查新记录的主键值,如果新记录的主键值与已有记录的主键值重复时,会更新表中对应的记录。",
|
|
44834
44834
|
"",
|
|
44835
44835
|
"查询优化:",
|
|
44836
44836
|
"",
|
|
@@ -44969,7 +44969,7 @@
|
|
|
44969
44969
|
"GOOG 2018.06.08T12:30:00 58 7800",
|
|
44970
44970
|
"==== =================== ===== ====",
|
|
44971
44971
|
"",
|
|
44972
|
-
"
|
|
44972
|
+
"插入新记录,并且新记录中的主键值与表中主键值重复:",
|
|
44973
44973
|
""
|
|
44974
44974
|
]
|
|
44975
44975
|
},
|
|
@@ -44994,7 +44994,7 @@
|
|
|
44994
44994
|
"GOOG 2018.06.08T12:30:01 78.6 4600",
|
|
44995
44995
|
"==== =================== ===== ====",
|
|
44996
44996
|
"",
|
|
44997
|
-
"
|
|
44997
|
+
"插入新记录,并且新记录中的主键值重复:",
|
|
44998
44998
|
""
|
|
44999
44999
|
]
|
|
45000
45000
|
},
|
|
@@ -51988,7 +51988,7 @@
|
|
|
51988
51988
|
"",
|
|
51989
51989
|
"请注意,从 1.30.20 版本开始,max 处理时间类型数据的行为(之前版本统一转换为长整型)修改为:",
|
|
51990
51990
|
"",
|
|
51991
|
-
"* 若 *X* 和 *Y*
|
|
51991
|
+
"* 若 *X* 和 *Y* 是时间类型标量,系统会将时间类型统一为两者中较高精度对应的类型,再比较大小。",
|
|
51992
51992
|
"* 若 *X* 或 *Y* 是向量、矩阵或表,则必须具有相同的时间类型。"
|
|
51993
51993
|
]
|
|
51994
51994
|
}
|
|
@@ -54765,7 +54765,7 @@
|
|
|
54765
54765
|
"",
|
|
54766
54766
|
"请注意,从 1.30.20 版本开始,min 处理时间类型数据的行为(之前版本统一转换为长整型)修改为:",
|
|
54767
54767
|
"",
|
|
54768
|
-
"* 若 *X* 和 *Y*
|
|
54768
|
+
"* 若 *X* 和 *Y* 是时间类型标量,系统会将时间类型统一为两者中较高精度对应的类型,再比较大小。",
|
|
54769
54769
|
"* 若 *X* 或 *Y* 是向量、矩阵或表,则必须具有相同的时间类型。"
|
|
54770
54770
|
]
|
|
54771
54771
|
}
|
|
@@ -71902,8 +71902,8 @@
|
|
|
71902
71902
|
"type": "text",
|
|
71903
71903
|
"value": [
|
|
71904
71904
|
"* 恢复通过 SQL 元代码(即 :doc:`../b/backup` 指定 *sqlObj* 参数)备份的文件时,不能指定 *snapshot*,否则会报错。",
|
|
71905
|
-
"* 指定 *outputTable* 时,恢复通过 SQL 元代码备份的文件,系统会在 *outputTable*
|
|
71906
|
-
"* 恢复时需要确保备份数据与待恢复数据库的引擎类型(engine)一致,且 partitionScheme(VALUE 除外)也保持一致。当采用 VALUE
|
|
71905
|
+
"* 指定 *outputTable* 时,恢复通过 SQL 元代码备份的文件,系统会在 *outputTable* 中直接追加(append)备份数据;而恢复通过拷贝方式(即 backup 指定 *dbPath* 参数)备份的文件时,系统只覆盖 outputTable 中数据不一致的分区。若不指定 outputTable,则数据恢复至原表,恢复方式相同。",
|
|
71906
|
+
"* 恢复时需要确保备份数据与待恢复数据库的引擎类型(engine)一致,且 partitionScheme(VALUE 除外)也保持一致。当采用 VALUE 分区时,须保证备份数据中的分区方案是待恢复数据库的分区方案的子集。例如:备份文件的分区方案是 database(\"dfs://xxx\", VALUE, 2017.08.07..2017.08.11), 则待恢复数据库的 VALUE 分区范围必须不小于 2017.08.07..2017.08.11。"
|
|
71907
71907
|
]
|
|
71908
71908
|
}
|
|
71909
71909
|
]
|
|
@@ -71942,7 +71942,7 @@
|
|
|
71942
71942
|
" $ pt = db.createPartitionedTable(t, `pt, `date`ID)",
|
|
71943
71943
|
" $ pt.append!(t);",
|
|
71944
71944
|
"",
|
|
71945
|
-
"备份表pt的所有数据:",
|
|
71945
|
+
"备份表 pt 的所有数据:",
|
|
71946
71946
|
""
|
|
71947
71947
|
]
|
|
71948
71948
|
},
|
|
@@ -71993,7 +71993,7 @@
|
|
|
71993
71993
|
" $ restore(\"/home/DolphinDB/backup\",\"dfs://compoDB\",\"pt\",\"%20170810%\",true)",
|
|
71994
71994
|
" [\"dfs://compoDB/20170810/0_50/6F\",\"dfs://compoDB/20170810/50_100/6F\"]",
|
|
71995
71995
|
"",
|
|
71996
|
-
"例3. 在数据库dfs://compoDB中创建一个与表pt结构相同的表temp,把pt的数据恢复到表temp。",
|
|
71996
|
+
"例3. 在数据库 dfs://compoDB 中创建一个与表 pt 结构相同的表 temp,把 pt 的数据恢复到表 temp。",
|
|
71997
71997
|
""
|
|
71998
71998
|
]
|
|
71999
71999
|
},
|
|
@@ -72069,17 +72069,19 @@
|
|
|
72069
72069
|
"value": [
|
|
72070
72070
|
"恢复备份的数据到数据库。返回包含数据库名称和表名称的表,每一行为完成恢复的数据库及表名称。",
|
|
72071
72071
|
"",
|
|
72072
|
-
"该函数与 :doc:`../m/migrate`
|
|
72072
|
+
"该函数与 :doc:`../m/migrate` 类似,都可恢复整个数据库下的所有表,区别见 :ref:`表 <migrage_restore>`。",
|
|
72073
72073
|
"",
|
|
72074
|
-
"
|
|
72075
|
-
"* 当恢复后的数据库名称、表名称与原数据库、原表一致时,migrate 要求原数据库、原表已经被删除,否则无法恢复,而 restoreDB 无此限制。",
|
|
72074
|
+
".. restore_notes",
|
|
72076
72075
|
"",
|
|
72077
72076
|
"注意事项:",
|
|
72078
72077
|
"",
|
|
72079
72078
|
"该函数仅支持恢复以拷贝文件方式(即 :doc:`../b/backup` 时指定 *dbPath* 参数)进行的备份。",
|
|
72080
72079
|
"",
|
|
72081
72080
|
"恢复时需要确保备份数据与待恢复数据库的引擎类型(engine)一致,且 partitionScheme(VALUE 除外)也保持一致。",
|
|
72082
|
-
"当采用 VALUE
|
|
72081
|
+
"当采用 VALUE 分区时,须保证备份数据中的分区方案是待恢复数据库的分区方案的子集。例如:备份文件的分区方案是 database(\"dfs://xxx\", VALUE, 2017.08.07..2017.08.11),",
|
|
72082
|
+
"则待恢复数据库的 VALUE 分区范围必须不小于 2017.08.07..2017.08.11。",
|
|
72083
|
+
"",
|
|
72084
|
+
".. end_restore_notes"
|
|
72083
72085
|
]
|
|
72084
72086
|
}
|
|
72085
72087
|
]
|
|
@@ -72258,16 +72260,14 @@
|
|
|
72258
72260
|
{
|
|
72259
72261
|
"type": "text",
|
|
72260
72262
|
"value": [
|
|
72261
|
-
"
|
|
72262
|
-
"其等价于调用 restore(backupDir, dbPath, tableName, force=false, parallel=true, snapshot=true)。调用该函数可以简化代码,方便用户一次性恢复数据库的一张表。",
|
|
72263
|
-
"",
|
|
72264
|
-
"该函数与 :doc:`../m/migrate` 类似,都可恢复整个数据库下的整个表,区别在于:当恢复后的数据库名称、表名称与原数据库、原表一致时,migrate 要求原数据库、原表已经被删除,",
|
|
72265
|
-
"否则无法恢复,而 restoreTable 无此限制。",
|
|
72263
|
+
"恢复备份的表到数据库。返回一个表,包含数据库名称和表名称。调用该函数可以简化代码,方便用户一次性恢复数据库的一张表。",
|
|
72266
72264
|
"",
|
|
72267
|
-
"
|
|
72265
|
+
"该函数与 :doc:`../m/migrate` 类似,都可恢复整个数据库下的整个表,区别见 :ref:`表 <migrage_restore>`。",
|
|
72268
72266
|
"",
|
|
72269
|
-
"
|
|
72270
|
-
"
|
|
72267
|
+
".. include:: restoreDB.rst",
|
|
72268
|
+
" :start-after: restore_notes",
|
|
72269
|
+
" :end-before: end_restore_notes",
|
|
72270
|
+
""
|
|
72271
72271
|
]
|
|
72272
72272
|
}
|
|
72273
72273
|
]
|
|
@@ -77488,25 +77488,23 @@
|
|
|
77488
77488
|
"value": [
|
|
77489
77489
|
"显示指定数据表或数据库的结构信息。各字段对应含义如下:",
|
|
77490
77490
|
"",
|
|
77491
|
-
"* databaseDir
|
|
77492
|
-
"* partitionTypeName / partitionType:分区的类型名和对应的 ID。VALUE(1), RANGE(2), LIST(3), COMPO(4), HASH(5)
|
|
77493
|
-
"* partitionSites:若 database 函数配置了 locations 参数,则该字段将列出 locations 指定节点的 ip:port
|
|
77494
|
-
"* partitionSchema
|
|
77495
|
-
"* chunkGranularity
|
|
77496
|
-
"* atomic
|
|
77497
|
-
"* engineType:存储引擎的类型。说明详见 database 函数的 engine 参数。",
|
|
77498
|
-
"* keepDuplicates:数据保留策略,说明详见 createPartitionedTable 函数的 keepDuplicates 参数。",
|
|
77499
|
-
"* sortKeyMappingFunction:索引列的映射函数。说明详见 createPartitionedTable 函数的 sortKeyMappingFunction 参数。",
|
|
77500
|
-
"* sortColumns:数据表的排序列。说明详见 createPartitionedTable 函数的 sortColumns 参数。",
|
|
77491
|
+
"* databaseDir:数据库的保存目录的路径。",
|
|
77492
|
+
"* partitionTypeName / partitionType:分区的类型名和对应的 ID。VALUE(1), RANGE(2), LIST(3), COMPO(4), HASH(5)。",
|
|
77493
|
+
"* partitionSites:若 database 函数配置了 locations 参数,则该字段将列出 locations 指定节点的 ip:port 信息。",
|
|
77494
|
+
"* partitionSchema:分区的结构。",
|
|
77495
|
+
"* chunkGranularity:分区粒度。",
|
|
77496
|
+
"* atomic:写入事务的原子性层级。",
|
|
77501
77497
|
"* partitionColumnIndex:分区列在表字段中对应的下标。维度表时,该值为 -1。",
|
|
77502
|
-
"* partitionColumnName
|
|
77498
|
+
"* partitionColumnName:分区列的名称。",
|
|
77503
77499
|
"* partitionColumnType:分区列类型对应的 ID,参照数据类型章节。",
|
|
77504
77500
|
"* colDefs:数据表各字段的结构信息。",
|
|
77505
77501
|
" ",
|
|
77506
77502
|
" * name:列名",
|
|
77507
77503
|
" * typeString:列的类型",
|
|
77508
77504
|
" * typeInt:列类型对应的ID",
|
|
77509
|
-
" * comment:列字段的注释信息"
|
|
77505
|
+
" * comment:列字段的注释信息",
|
|
77506
|
+
"",
|
|
77507
|
+
"相关函数::doc:`/FunctionsandCommands/FunctionReferences/d/database`, :doc:`/FunctionsandCommands/FunctionReferences/c/createTable`, :doc:`/FunctionsandCommands/FunctionReferences/c/createPartitionedTable`"
|
|
77510
77508
|
]
|
|
77511
77509
|
}
|
|
77512
77510
|
]
|
|
@@ -79709,7 +79707,7 @@
|
|
|
79709
79707
|
{
|
|
79710
79708
|
"type": "text",
|
|
79711
79709
|
"value": [
|
|
79712
|
-
"setRetentionPolicy(
|
|
79710
|
+
"setRetentionPolicy(dbHandle, retentionHours, [retentionDimension], [hoursToColdVolume])"
|
|
79713
79711
|
]
|
|
79714
79712
|
}
|
|
79715
79713
|
]
|
|
@@ -84378,7 +84376,7 @@
|
|
|
84378
84376
|
"",
|
|
84379
84377
|
"在 streamEngineParser 中,计算指标通常是一个嵌套的因子,每层嵌套逻辑都被解析后放入特定的引擎进行计算。更多说明见详情。",
|
|
84380
84378
|
"",
|
|
84381
|
-
"`dummyTable`
|
|
84379
|
+
"`dummyTable` 一个表对象,和订阅的流数据表的 schema 一致,可以含有数据,亦可为空表。",
|
|
84382
84380
|
"",
|
|
84383
84381
|
"`outputTable` 计算结果的输出表,可以是内存表或者分布式表。调用 ``streamEngineParser`` 之前,需要将输出表预先设立为一个空表,并指定各列列名以及数据类型。各引擎会将计算结果插入该表。",
|
|
84384
84382
|
"若 *metrics* 分解的流水线上的最后一个操作对应:",
|
|
@@ -84570,19 +84568,19 @@
|
|
|
84570
84568
|
{
|
|
84571
84569
|
"type": "text",
|
|
84572
84570
|
"value": [
|
|
84573
|
-
"
|
|
84571
|
+
"创建流数据过滤引擎,返回一个表对象。对注入该表的数据进行过滤和分发处理。",
|
|
84572
|
+
"",
|
|
84573
|
+
"该引擎的处理流程如下:",
|
|
84574
84574
|
"",
|
|
84575
|
-
"
|
|
84575
|
+
"\\1. 订阅异构流表(由 :doc:`../r/replay` 函数回放得到)时,解析(反序列化)注入的数据。输入数据为普通流表时无此步骤。注意:1.30.18 版本开始,streamFilter 函数支持过滤普通流表数据,并进行分发处理。",
|
|
84576
84576
|
"",
|
|
84577
|
-
"\\
|
|
84577
|
+
"\\2. 根据 *filter* 指定的规则对流表进行过滤。",
|
|
84578
84578
|
"",
|
|
84579
|
-
"\\
|
|
84579
|
+
"\\3. 过滤后的数据按照时间顺序分发到不同的 handler 处理。",
|
|
84580
84580
|
"",
|
|
84581
84581
|
"注意:",
|
|
84582
84582
|
"",
|
|
84583
|
-
"* 1.30.17 版本开始,DolphinDB 支持通过 :doc:`../r/replay` 函数将多个结构不同的流数据表,回放(序列化)到一个流表里,这个流表被称为异构流表。streamFilter 函数用于解析(反序列化)和过滤异构流表的数据并进行分发处理。"
|
|
84584
|
-
"* 1.30.18 版本开始,streamFilter 函数支持过滤普通流表数据,并进行分发处理。",
|
|
84585
|
-
""
|
|
84583
|
+
"* 1.30.17 版本开始,DolphinDB 支持通过 :doc:`../r/replay` 函数将多个结构不同的流数据表,回放(序列化)到一个流表里,这个流表被称为异构流表。streamFilter 函数用于解析(反序列化)和过滤异构流表的数据并进行分发处理。"
|
|
84586
84584
|
]
|
|
84587
84585
|
}
|
|
84588
84586
|
]
|
|
@@ -84649,8 +84647,9 @@
|
|
|
84649
84647
|
"value": [
|
|
84650
84648
|
"\\(1) 异构流表分发:",
|
|
84651
84649
|
"",
|
|
84652
|
-
"
|
|
84653
|
-
"
|
|
84650
|
+
"一个典型场景:对分布式数据库中的订单表和交易表进行回放,模拟两者实时 asof join 的场景。如使用 replay 进行 N 对 N 回放,则无法保证数据严格按照时间戳",
|
|
84651
|
+
"顺序注入 asof join 引擎的左表和右表(原因详见 replay 说明)。但通过 replay 将两表回放到一个异构流表则可以保证表内所有数据按照时间戳顺序排序,",
|
|
84652
|
+
"之后通过 streamFilter 将表中数据分发至 asof join 引擎的左、右表时,可保证数据按时间戳顺序注入引擎左、右两表。",
|
|
84654
84653
|
""
|
|
84655
84654
|
]
|
|
84656
84655
|
},
|
|
@@ -85718,7 +85717,7 @@
|
|
|
85718
85717
|
"",
|
|
85719
85718
|
"`jobDesc` 是字符串,用于描述作业。",
|
|
85720
85719
|
"",
|
|
85721
|
-
"`jobDef`
|
|
85720
|
+
"`jobDef` 是用于定义作业的本地函数。请注意,该参数是一个函数对象,而不是表示函数名的字符串,因此不可使用引号。",
|
|
85722
85721
|
"",
|
|
85723
85722
|
"`args...` 是函数的参数。如果函数没有参数,可以不指定。"
|
|
85724
85723
|
]
|
|
@@ -85933,7 +85932,7 @@
|
|
|
85933
85932
|
{
|
|
85934
85933
|
"type": "text",
|
|
85935
85934
|
"value": [
|
|
85936
|
-
"`
|
|
85935
|
+
"`jobId` 是作业的ID,是字符串类型。",
|
|
85937
85936
|
"",
|
|
85938
85937
|
"`jobDesc` 是字符串,用于描述作业。",
|
|
85939
85938
|
"",
|
|
@@ -85941,7 +85940,7 @@
|
|
|
85941
85940
|
"",
|
|
85942
85941
|
"`parallelism` 是正整数,表示分配给该作业的线程数上限。",
|
|
85943
85942
|
"",
|
|
85944
|
-
"`
|
|
85943
|
+
"`jobDef` 是用于定义作业的本地函数。请注意,该参数是一个函数对象,而不是表示函数名的字符串,因此不可使用引号。",
|
|
85945
85944
|
"",
|
|
85946
85945
|
"`args...` 是函数的参数。如果函数没有参数,它可以不指定。"
|
|
85947
85946
|
]
|
|
@@ -86048,7 +86047,7 @@
|
|
|
86048
86047
|
"",
|
|
86049
86048
|
"`tableName` 是被订阅的数据表名。该表必须为共享的流数据表。",
|
|
86050
86049
|
"",
|
|
86051
|
-
"`actionName`
|
|
86050
|
+
"`actionName` 是一个字符串,表示订阅任务的名称。它可以包含字母,数字和下划线。如果一个节点有多个订阅任务均订阅了同一张表,则每个订阅必须指定唯一的 *actionName*。",
|
|
86052
86051
|
"",
|
|
86053
86052
|
"`offset` 是订阅任务开始后的第一条消息所在的位置。消息是流数据表中的行。如果未指定,或设为-1,订阅将会从流数据表的当前行开始。如果 *offset* \\= -2,系统会获取持久化到磁盘上的 *offset*,并从该位置开始订阅。*offset* 与流数据表创建时的第一行对应。如果某些行因为内存限制被删除,在决定订阅开始的位置时,这些行仍然考虑在内。",
|
|
86054
86053
|
"",
|
package/i18n/dict.json
CHANGED
|
@@ -61,5 +61,11 @@
|
|
|
61
61
|
},
|
|
62
62
|
" 暂时不支持序列化": {
|
|
63
63
|
"en": " serialization is currently not supported"
|
|
64
|
+
},
|
|
65
|
+
"print 消息的 buffer 应该以 \\0 结束": {
|
|
66
|
+
"en": "The buffer of the print message should end with \\0"
|
|
67
|
+
},
|
|
68
|
+
"print 消息的 buffer 中间不应该有 \\0": {
|
|
69
|
+
"en": "There should not be \\0 in the buffer of the print message"
|
|
64
70
|
}
|
|
65
71
|
}
|
package/index.d.ts
CHANGED
|
@@ -376,7 +376,7 @@ export declare function timestamp2str(timestamp: bigint | null, format?: string)
|
|
|
376
376
|
export declare function datehour2ms(datehour: number | null): number | null;
|
|
377
377
|
export declare function datehour2str(datehour: number | null, format?: string): string;
|
|
378
378
|
/** parse timestamp string to bigint value
|
|
379
|
-
- str:
|
|
379
|
+
- str: timestamp string, 如果为空字符串或 'null' 会返回对应的空值 (nulls.int64)
|
|
380
380
|
timestamp string, If it is an empty string or 'null', it will return the corresponding empty value (nulls.int64)
|
|
381
381
|
- format?:
|
|
382
382
|
对应传入字符串的格式串,默认是 `YYYY.MM.DD HH:mm:ss.SSS`
|
package/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// import { table, getBorderCharacters, type TableUserConfig } from 'table'
|
|
1
2
|
import { WebSocket } from 'ws';
|
|
2
3
|
import dayjs from 'dayjs';
|
|
3
4
|
import DayjsCustomParseFormat from 'dayjs/plugin/customParseFormat.js';
|
|
@@ -1959,7 +1960,7 @@ export function datehour2str(datehour, format = 'YYYY.MM.DDTHH') {
|
|
|
1959
1960
|
dayjs(1000 * 60 * new Date(ms).getTimezoneOffset() + ms).format(format);
|
|
1960
1961
|
}
|
|
1961
1962
|
/** parse timestamp string to bigint value
|
|
1962
|
-
- str:
|
|
1963
|
+
- str: timestamp string, 如果为空字符串或 'null' 会返回对应的空值 (nulls.int64)
|
|
1963
1964
|
timestamp string, If it is an empty string or 'null', it will return the corresponding empty value (nulls.int64)
|
|
1964
1965
|
- format?:
|
|
1965
1966
|
对应传入字符串的格式串,默认是 `YYYY.MM.DD HH:mm:ss.SSS`
|
|
@@ -2091,6 +2092,11 @@ export class DDB {
|
|
|
2091
2092
|
/** utf-8 text decoder */
|
|
2092
2093
|
dec = new TextDecoder('utf-8');
|
|
2093
2094
|
enc = new TextEncoder();
|
|
2095
|
+
// port = 8848
|
|
2096
|
+
// /** ddb 连接状态 */
|
|
2097
|
+
// state = '未连接'
|
|
2098
|
+
// socket = null as Socket
|
|
2099
|
+
// clients = new Set<Duplex>()
|
|
2094
2100
|
/** DolphinDB WebSocket URL
|
|
2095
2101
|
e.g. `ws://127.0.0.1:8848/`, `wss://dolphindb.com`
|
|
2096
2102
|
*/
|
|
@@ -2476,11 +2482,15 @@ export class DDB {
|
|
|
2476
2482
|
// MSG\n
|
|
2477
2483
|
// <message>\0
|
|
2478
2484
|
// 'M'.codePointAt(0).to_hex_str()
|
|
2479
|
-
if (buf[0] === 0x4d && buf[1] === 0x53 && buf[2] === 0x47 && buf[3] === 0x0a)
|
|
2485
|
+
if (buf[0] === 0x4d && buf[1] === 0x53 && buf[2] === 0x47 && buf[3] === 0x0a) {
|
|
2486
|
+
assert(buf.at(-1) === 0, t('print 消息的 buffer 应该以 \\0 结束'));
|
|
2487
|
+
if (buf.indexOf(0) !== buf.length - 1)
|
|
2488
|
+
console.warn(t('print 消息的 buffer 中间不应该有 \\0'));
|
|
2480
2489
|
return {
|
|
2481
2490
|
type: 'print',
|
|
2482
|
-
data: this.dec.decode(buf.subarray(4))
|
|
2491
|
+
data: this.dec.decode(buf.subarray(4, -1))
|
|
2483
2492
|
};
|
|
2493
|
+
}
|
|
2484
2494
|
// '1166953221 1 1\n'
|
|
2485
2495
|
// 'OK\n'
|
|
2486
2496
|
// '\x04\x00\x02\x00\x00\x00'
|
|
@@ -2579,4 +2589,157 @@ export class DDB {
|
|
|
2579
2589
|
return this.streaming;
|
|
2580
2590
|
}
|
|
2581
2591
|
}
|
|
2592
|
+
// const ddb_gateway = {
|
|
2593
|
+
// server: null as SocketServer,
|
|
2594
|
+
// clients: new Set<Socket>(),
|
|
2595
|
+
// port: 8849,
|
|
2596
|
+
// controllers: {
|
|
2597
|
+
// /** alias */
|
|
2598
|
+
// c0: {
|
|
2599
|
+
// hostname: '127.0.0.1',
|
|
2600
|
+
// port: 8850,
|
|
2601
|
+
// },
|
|
2602
|
+
// c1: {
|
|
2603
|
+
// hostname: '127.0.0.1',
|
|
2604
|
+
// port: 8851,
|
|
2605
|
+
// },
|
|
2606
|
+
// c2: {
|
|
2607
|
+
// hostname: '127.0.0.1',
|
|
2608
|
+
// port: 8852,
|
|
2609
|
+
// }
|
|
2610
|
+
// },
|
|
2611
|
+
// master: '',
|
|
2612
|
+
// sids: new Map<string, string>(),
|
|
2613
|
+
// state: 'init',
|
|
2614
|
+
// async start () {
|
|
2615
|
+
// for (const alias in this.controllers) {
|
|
2616
|
+
// this.master = alias
|
|
2617
|
+
// break
|
|
2618
|
+
// }
|
|
2619
|
+
// this.server = create_socket_server(
|
|
2620
|
+
// {
|
|
2621
|
+
// allowHalfOpen: false,
|
|
2622
|
+
// pauseOnConnect: false,
|
|
2623
|
+
// },
|
|
2624
|
+
// this.accept.bind(this)
|
|
2625
|
+
// )
|
|
2626
|
+
// this.server.on('error', error => {
|
|
2627
|
+
// console.log(new Date(), 'gateway 出错:', error)
|
|
2628
|
+
// })
|
|
2629
|
+
// await new Promise<void>(resolve => {
|
|
2630
|
+
// this.server.listen(this.port, resolve)
|
|
2631
|
+
// })
|
|
2632
|
+
// this.auto_switch_master()
|
|
2633
|
+
// console.log(new Date(), 'gateway 成功启动')
|
|
2634
|
+
// },
|
|
2635
|
+
// async stop () {
|
|
2636
|
+
// this.state = 'stopping'
|
|
2637
|
+
// console.log(new Date(), '正在停止 auto_switch_master')
|
|
2638
|
+
// for (const client of this.clients)
|
|
2639
|
+
// client.end()
|
|
2640
|
+
// await new Promise<void>((resolve, reject) => {
|
|
2641
|
+
// this.server.close(error => {
|
|
2642
|
+
// if (error) {
|
|
2643
|
+
// reject(error)
|
|
2644
|
+
// return
|
|
2645
|
+
// }
|
|
2646
|
+
// resolve()
|
|
2647
|
+
// })
|
|
2648
|
+
// })
|
|
2649
|
+
// },
|
|
2650
|
+
// /** 接收到 client tcp 连接 */
|
|
2651
|
+
// async accept (client: Socket) {
|
|
2652
|
+
// this.clients.add(client)
|
|
2653
|
+
// const port = client.remotePort
|
|
2654
|
+
// // ---
|
|
2655
|
+
// console.log(port, new Date(), 'gateway accept client 连接,开始建立管道')
|
|
2656
|
+
// let controller = new Socket({
|
|
2657
|
+
// allowHalfOpen: false,
|
|
2658
|
+
// readable: true,
|
|
2659
|
+
// writable: true,
|
|
2660
|
+
// })
|
|
2661
|
+
// controller.on('lookup', (error, address, family, host) => {
|
|
2662
|
+
// console.log(port, new Date(), 'controller 域名解析 (lookup) 完成', error, address, family, host)
|
|
2663
|
+
// })
|
|
2664
|
+
// controller.on('close', has_error => {
|
|
2665
|
+
// console.log(port, new Date(), 'controller 关闭连接,是否出错:', has_error)
|
|
2666
|
+
// })
|
|
2667
|
+
// controller.on('timeout', () => {
|
|
2668
|
+
// console.log(port, new Date(), 'controller 超时')
|
|
2669
|
+
// })
|
|
2670
|
+
// controller.on('error', error => {
|
|
2671
|
+
// console.log(port, new Date(), 'controller 出错了:', error)
|
|
2672
|
+
// client.end()
|
|
2673
|
+
// })
|
|
2674
|
+
// // --- client 错误处理
|
|
2675
|
+
// client.on('error', error => {
|
|
2676
|
+
// console.log(port, new Date(), 'client 出错,关闭与 controller 的连接', error)
|
|
2677
|
+
// controller.end()
|
|
2678
|
+
// })
|
|
2679
|
+
// client.on('close', has_error => {
|
|
2680
|
+
// this.clients.delete(client)
|
|
2681
|
+
// console.log(port, new Date(), 'client 关闭连接,是否出错:', has_error)
|
|
2682
|
+
// })
|
|
2683
|
+
// // ---
|
|
2684
|
+
// console.log(port, new Date(), 'gateway 开始连接到 controller')
|
|
2685
|
+
// const { hostname, port: master_port } = this.controllers[this.master]
|
|
2686
|
+
// await new Promise<void>(resolve => {
|
|
2687
|
+
// // callback 会被 socket.once('connect', callback)
|
|
2688
|
+
// controller.connect({
|
|
2689
|
+
// port: master_port,
|
|
2690
|
+
// host: hostname,
|
|
2691
|
+
// // host: '127.0.0.1',
|
|
2692
|
+
// family: 0,
|
|
2693
|
+
// }, resolve)
|
|
2694
|
+
// })
|
|
2695
|
+
// console.log(port, new Date(), 'gateway 已连接到 controller')
|
|
2696
|
+
// // ---
|
|
2697
|
+
// console.log(port, new Date(), 'gateway 建立 client <-> controller')
|
|
2698
|
+
// client.pipe(controller)
|
|
2699
|
+
// controller.pipe(client)
|
|
2700
|
+
// },
|
|
2701
|
+
// /** https://www.dolphindb.cn/cn/help/FunctionsandCommands/FunctionReferences/g/getActiveMaster.html?highlight=getactivemaster */
|
|
2702
|
+
// async get_active_master () {
|
|
2703
|
+
// for (const alias in this.controllers) {
|
|
2704
|
+
// const { hostname, port } = this.controllers[alias] as { hostname: string, port: number }
|
|
2705
|
+
// const sid = this.sids.get(alias)
|
|
2706
|
+
// try {
|
|
2707
|
+
// const master = (
|
|
2708
|
+
// await ddb.rpc_json('getActiveMaster()', { hostname, port, sid })
|
|
2709
|
+
// ).value as string
|
|
2710
|
+
// console.log(new Date(), `${alias}.getActiveMaster() -> ${this.master}`)
|
|
2711
|
+
// this.sids.set(alias, sid)
|
|
2712
|
+
// if (!master)
|
|
2713
|
+
// throw new Error(`${new Date().toString()} getActiveMaster 得到的 master 为空`)
|
|
2714
|
+
// return master
|
|
2715
|
+
// } catch (error) {
|
|
2716
|
+
// console.log(new Date(), error)
|
|
2717
|
+
// }
|
|
2718
|
+
// }
|
|
2719
|
+
// return this.master
|
|
2720
|
+
// },
|
|
2721
|
+
// async auto_switch_master () {
|
|
2722
|
+
// if (this.state === 'stopping') {
|
|
2723
|
+
// this.state = 'running'
|
|
2724
|
+
// console.log('gateway 恢复 auto_switch_master')
|
|
2725
|
+
// return
|
|
2726
|
+
// }
|
|
2727
|
+
// this.state = 'running'
|
|
2728
|
+
// for (; this.state === 'running'; ) {
|
|
2729
|
+
// const master = this.master
|
|
2730
|
+
// const master_ = await this.get_active_master()
|
|
2731
|
+
// if (master === master_) {
|
|
2732
|
+
// await delay(10 * 1000)
|
|
2733
|
+
// continue
|
|
2734
|
+
// }
|
|
2735
|
+
// this.master = master_
|
|
2736
|
+
// console.log(new Date(), `master 从 ${master} 切换为 ${master_}, 断开所有 clients`)
|
|
2737
|
+
// for (const client of this.clients)
|
|
2738
|
+
// client.end()
|
|
2739
|
+
// await delay(3 * 1000)
|
|
2740
|
+
// }
|
|
2741
|
+
// console.log(new Date(), `gateway.state === ${this.state}, 停止 auto_switch_master`)
|
|
2742
|
+
// this.state = 'stopped'
|
|
2743
|
+
// }
|
|
2744
|
+
// }
|
|
2582
2745
|
//# sourceMappingURL=index.js.map
|